1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_COMPILER_OPTIMIZING_INTRINSIC_OBJECTS_H_ 18 #define ART_COMPILER_OPTIMIZING_INTRINSIC_OBJECTS_H_ 19 20 #include "base/bit_field.h" 21 #include "base/bit_utils.h" 22 #include "base/macros.h" 23 #include "base/mutex.h" 24 #include "obj_ptr.h" 25 #include "offsets.h" 26 27 namespace art HIDDEN { 28 29 class ClassLinker; 30 class MemberOffset; 31 class Thread; 32 33 namespace mirror { 34 class Object; 35 template <class T> class ObjectArray; 36 } // namespace mirror 37 38 #define BOXED_TYPES(V) \ 39 V(Byte, -128, 127, DataType::Type::kInt8, 0) \ 40 V(Short, -128, 127, DataType::Type::kInt16, kByteCacheLastIndex) \ 41 V(Character, 0, 127, DataType::Type::kUint16, kShortCacheLastIndex) \ 42 V(Integer, -128, 127, DataType::Type::kInt32, kCharacterCacheLastIndex) 43 44 #define DEFINE_BOXED_CONSTANTS(name, low, high, unused, start_index) \ 45 static constexpr size_t k ##name ##CacheLastIndex = start_index + (high - low + 1); \ 46 static constexpr size_t k ##name ##CacheFirstIndex = start_index; 47 BOXED_TYPES(DEFINE_BOXED_CONSTANTS) 48 49 static constexpr size_t kNumberOfBoxedCaches = kIntegerCacheLastIndex; 50 #undef DEFINE_BOXED_CONSTANTS 51 52 class IntrinsicObjects { 53 public: 54 enum class PatchType { 55 kValueOfObject, 56 kValueOfArray, 57 58 kLast = kValueOfArray 59 }; 60 61 static uint32_t EncodePatch(PatchType patch_type, uint32_t index = 0u) { 62 return PatchTypeField::Encode(static_cast<uint32_t>(patch_type)) | IndexField::Encode(index); 63 } 64 DecodePatchType(uint32_t intrinsic_data)65 static PatchType DecodePatchType(uint32_t intrinsic_data) { 66 return static_cast<PatchType>(PatchTypeField::Decode(intrinsic_data)); 67 } 68 DecodePatchIndex(uint32_t intrinsic_data)69 static uint32_t DecodePatchIndex(uint32_t intrinsic_data) { 70 return IndexField::Decode(intrinsic_data); 71 } 72 73 // Helpers returning addresses of objects, suitable for embedding in generated code. 74 #define DEFINE_BOXED_ACCESSES(name, unused1, unused2, unused3, start_index) \ 75 static ObjPtr<mirror::Object> Get ##name ##ValueOfObject( \ 76 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects, \ 77 uint32_t index) REQUIRES_SHARED(Locks::mutator_lock_) { \ 78 return GetValueOfObject(boot_image_live_objects, k ##name ##CacheFirstIndex, index); \ 79 } \ 80 static MemberOffset Get ##name ##ValueOfArrayDataOffset( \ 81 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects) \ 82 REQUIRES_SHARED(Locks::mutator_lock_) { \ 83 return GetValueOfArrayDataOffset(boot_image_live_objects, k ##name ##CacheFirstIndex); \ 84 } 85 BOXED_TYPES(DEFINE_BOXED_ACCESSES) 86 #undef DEFINED_BOXED_ACCESSES 87 88 EXPORT static void FillIntrinsicObjects( 89 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects, size_t start_index) 90 REQUIRES_SHARED(Locks::mutator_lock_); 91 GetNumberOfIntrinsicObjects()92 static constexpr size_t GetNumberOfIntrinsicObjects() { 93 return kNumberOfBoxedCaches; 94 } 95 96 EXPORT static ObjPtr<mirror::Object> GetValueOfObject( 97 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects, 98 size_t start_index, 99 uint32_t index) REQUIRES_SHARED(Locks::mutator_lock_); 100 101 EXPORT static MemberOffset GetValueOfArrayDataOffset( 102 ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects, 103 size_t start_index) REQUIRES_SHARED(Locks::mutator_lock_); 104 105 private: 106 static constexpr size_t kPatchTypeBits = 107 MinimumBitsToStore(static_cast<uint32_t>(PatchType::kLast)); 108 static constexpr size_t kIndexBits = BitSizeOf<uint32_t>() - kPatchTypeBits; 109 using PatchTypeField = BitField<uint32_t, 0u, kPatchTypeBits>; 110 using IndexField = BitField<uint32_t, kPatchTypeBits, kIndexBits>; 111 }; 112 113 } // namespace art 114 115 #endif // ART_COMPILER_OPTIMIZING_INTRINSIC_OBJECTS_H_ 116