/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_SRC_VERIFIER_GC_MAP_H_
#define ART_SRC_VERIFIER_GC_MAP_H_

#include "logging.h"
#include "macros.h"
#include <stdint.h>

namespace art {
namespace verifier {

/*
 * Format enumeration for RegisterMap data area.
 */
enum RegisterMapFormat {
  kRegMapFormatUnknown = 0,
  kRegMapFormatNone = 1,      // Indicates no map data follows.
  kRegMapFormatCompact8 = 2,  // Compact layout, 8-bit addresses.
  kRegMapFormatCompact16 = 3, // Compact layout, 16-bit addresses.
};

// Lightweight wrapper for PC to reference bit maps.
class PcToReferenceMap {
 public:
  PcToReferenceMap(const uint8_t* data, size_t data_length) {
    data_ = data;
    CHECK(data_ != NULL);
    // Check the size of the table agrees with the number of entries
    size_t data_size = data_length - 4;
    DCHECK_EQ(EntryWidth() * NumEntries(), data_size);
  }

  // The number of entries in the table
  size_t NumEntries() const {
    return GetData()[2] | (GetData()[3] << 8);
  }

  // Get the PC at the given index
  uint16_t GetPC(size_t index) const {
    size_t entry_offset = index * EntryWidth();
    if (PcWidth() == 1) {
      return Table()[entry_offset];
    } else {
      return Table()[entry_offset] | (Table()[entry_offset + 1] << 8);
    }
  }

  // Return address of bitmap encoding what are live references
  const uint8_t* GetBitMap(size_t index) const {
    size_t entry_offset = index * EntryWidth();
    return &Table()[entry_offset + PcWidth()];
  }

  // Find the bitmap associated with the given dex pc
  const uint8_t* FindBitMap(uint16_t dex_pc, bool error_if_not_present = true) const;

  // The number of bytes used to encode registers
  size_t RegWidth() const {
    return GetData()[1] | ((GetData()[0] & ~kRegMapFormatMask) << kRegMapFormatShift);
  }

 private:
  // Table of num_entries * (dex pc, bitmap)
  const uint8_t* Table() const {
    return GetData() + 4;
  }

  // The format of the table of the PCs for the table
  RegisterMapFormat Format() const {
    return static_cast<RegisterMapFormat>(GetData()[0] & kRegMapFormatMask);
  }

  // Number of bytes used to encode a dex pc
  size_t PcWidth() const {
    RegisterMapFormat format = Format();
    switch (format) {
      case kRegMapFormatCompact8:
        return 1;
      case kRegMapFormatCompact16:
        return 2;
      default:
        LOG(FATAL) << "Invalid format " << static_cast<int>(format);
        return -1;
    }
  }

  // The width of an entry in the table
  size_t EntryWidth() const {
    return PcWidth() + RegWidth();
  }

  const uint8_t* GetData() const {
    return data_;
  }

  friend class MethodVerifier;

  static const int kRegMapFormatShift = 5;
  static const uint8_t kRegMapFormatMask = 0x7;

  const uint8_t* data_;  // The header and table data
};

}  // namespace verifier
}  // namespace art

#endif  // ART_SRC_VERIFIER_GC_MAP_H_
