/*
 * 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_RUNTIME_VERIFIER_DEX_GC_MAP_H_
#define ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_

#include <stdint.h>

#include "base/logging.h"
#include "base/macros.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 Dex PC to reference bit maps.
class DexPcToReferenceMap {
 public:
  DexPcToReferenceMap(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 Dex PC at the given index
  uint16_t GetDexPc(size_t index) const {
    size_t entry_offset = index * EntryWidth();
    if (DexPcWidth() == 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 + DexPcWidth()];
  }

  // 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 DexPcWidth() 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 DexPcWidth() + 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* const data_;  // The header and table data
};

}  // namespace verifier
}  // namespace art

#endif  // ART_RUNTIME_VERIFIER_DEX_GC_MAP_H_
