/*
 * Copyright (C) 2017 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_METHOD_INFO_H_
#define ART_RUNTIME_METHOD_INFO_H_

#include <android-base/logging.h>

#include "base/leb128.h"
#include "base/macros.h"
#include "base/bit_memory_region.h"

namespace art {

// Method info is for not dedupe friendly data of a method. Currently it only holds methods indices.
// Putting this data in MethodInfo instead of code infos saves ~5% oat size.
class MethodInfo {
  using MethodIndexType = uint16_t;

 public:
  // Reading mode
  explicit MethodInfo(const uint8_t* ptr) {
    if (ptr != nullptr) {
      num_method_indices_ = DecodeUnsignedLeb128(&ptr);
      region_ = BitMemoryRegion(
          MemoryRegion(const_cast<uint8_t*>(ptr), num_method_indices_ * sizeof(MethodIndexType)));
    }
  }

  // Writing mode
  MethodInfo(uint8_t* ptr, size_t num_method_indices) : num_method_indices_(num_method_indices) {
    DCHECK(ptr != nullptr);
    ptr = EncodeUnsignedLeb128(ptr, num_method_indices_);
    region_ = BitMemoryRegion(MemoryRegion(ptr, num_method_indices_ * sizeof(MethodIndexType)));
  }

  static size_t ComputeSize(size_t num_method_indices) {
    uint8_t temp[8];
    uint8_t* ptr = temp;
    ptr = EncodeUnsignedLeb128(ptr, num_method_indices);
    return (ptr - temp) + num_method_indices * sizeof(MethodIndexType);
  }

  ALWAYS_INLINE MethodIndexType GetMethodIndex(size_t index) const {
    // Use bit functions to avoid pesky alignment requirements.
    return region_.LoadBits(index * BitSizeOf<MethodIndexType>(), BitSizeOf<MethodIndexType>());
  }

  void SetMethodIndex(size_t index, MethodIndexType method_index) {
    region_.StoreBits(index * BitSizeOf<MethodIndexType>(),
                      method_index,
                      BitSizeOf<MethodIndexType>());
  }

  size_t NumMethodIndices() const {
    return num_method_indices_;
  }

 private:
  size_t num_method_indices_ = 0u;
  BitMemoryRegion region_;
};

}  // namespace art

#endif  // ART_RUNTIME_METHOD_INFO_H_
