/*
 * Copyright (C) 2018 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_COMPILER_OPTIMIZING_INTRINSIC_OBJECTS_H_
#define ART_COMPILER_OPTIMIZING_INTRINSIC_OBJECTS_H_

#include "base/bit_field.h"
#include "base/bit_utils.h"
#include "base/macros.h"
#include "base/mutex.h"

namespace art HIDDEN {

class ClassLinker;
template <class MirrorType> class ObjPtr;
class MemberOffset;
class Thread;

namespace mirror {
class Object;
template <class T> class ObjectArray;
}  // namespace mirror

class IntrinsicObjects {
 public:
  enum class PatchType {
    kIntegerValueOfObject,
    kIntegerValueOfArray,

    kLast = kIntegerValueOfArray
  };

  static uint32_t EncodePatch(PatchType patch_type, uint32_t index = 0u) {
    DCHECK(patch_type == PatchType::kIntegerValueOfObject || index == 0u);
    return PatchTypeField::Encode(static_cast<uint32_t>(patch_type)) | IndexField::Encode(index);
  }

  static PatchType DecodePatchType(uint32_t intrinsic_data) {
    return static_cast<PatchType>(PatchTypeField::Decode(intrinsic_data));
  }

  static uint32_t DecodePatchIndex(uint32_t intrinsic_data) {
    return IndexField::Decode(intrinsic_data);
  }

  // Functions for retrieving data for Integer.valueOf().
  EXPORT static ObjPtr<mirror::ObjectArray<mirror::Object>> LookupIntegerCache(
      Thread* self, ClassLinker* class_linker) REQUIRES_SHARED(Locks::mutator_lock_);
  EXPORT static ObjPtr<mirror::ObjectArray<mirror::Object>> GetIntegerValueOfCache(
      ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects)
      REQUIRES_SHARED(Locks::mutator_lock_);
  EXPORT static ObjPtr<mirror::Object> GetIntegerValueOfObject(
      ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects,
      uint32_t index) REQUIRES_SHARED(Locks::mutator_lock_);
  EXPORT static MemberOffset GetIntegerValueOfArrayDataOffset(
      ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects)
      REQUIRES_SHARED(Locks::mutator_lock_);

 private:
  static constexpr size_t kPatchTypeBits =
      MinimumBitsToStore(static_cast<uint32_t>(PatchType::kLast));
  static constexpr size_t kIndexBits = BitSizeOf<uint32_t>() - kPatchTypeBits;
  using PatchTypeField = BitField<uint32_t, 0u, kPatchTypeBits>;
  using IndexField = BitField<uint32_t, kPatchTypeBits, kIndexBits>;
};

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_INTRINSIC_OBJECTS_H_
