1 /* 2 * Copyright (C) 2011 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_RUNTIME_MIRROR_DEX_CACHE_H_ 18 #define ART_RUNTIME_MIRROR_DEX_CACHE_H_ 19 20 #include "array.h" 21 #include "art_field.h" 22 #include "art_method.h" 23 #include "class.h" 24 #include "object.h" 25 #include "object_array.h" 26 27 namespace art { 28 29 struct DexCacheOffsets; 30 class DexFile; 31 class ImageWriter; 32 union JValue; 33 34 namespace mirror { 35 36 class String; 37 38 // C++ mirror of java.lang.DexCache. 39 class MANAGED DexCache FINAL : public Object { 40 public: 41 // Size of java.lang.DexCache.class. 42 static uint32_t ClassSize(size_t pointer_size); 43 44 // Size of an instance of java.lang.DexCache not including referenced values. InstanceSize()45 static constexpr uint32_t InstanceSize() { 46 return sizeof(DexCache); 47 } 48 49 void Init(const DexFile* dex_file, 50 String* location, 51 GcRoot<String>* strings, 52 uint32_t num_strings, 53 GcRoot<Class>* resolved_types, 54 uint32_t num_resolved_types, 55 ArtMethod** resolved_methods, 56 uint32_t num_resolved_methods, 57 ArtField** resolved_fields, 58 uint32_t num_resolved_fields, 59 size_t pointer_size) SHARED_REQUIRES(Locks::mutator_lock_); 60 61 void Fixup(ArtMethod* trampoline, size_t pointer_size) 62 SHARED_REQUIRES(Locks::mutator_lock_); 63 64 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor> 65 void FixupStrings(GcRoot<mirror::String>* dest, const Visitor& visitor) 66 SHARED_REQUIRES(Locks::mutator_lock_); 67 68 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor> 69 void FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor) 70 SHARED_REQUIRES(Locks::mutator_lock_); 71 GetLocation()72 String* GetLocation() SHARED_REQUIRES(Locks::mutator_lock_) { 73 return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_)); 74 } 75 DexOffset()76 static MemberOffset DexOffset() { 77 return OFFSET_OF_OBJECT_MEMBER(DexCache, dex_); 78 } 79 StringsOffset()80 static MemberOffset StringsOffset() { 81 return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_); 82 } 83 ResolvedTypesOffset()84 static MemberOffset ResolvedTypesOffset() { 85 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_); 86 } 87 ResolvedFieldsOffset()88 static MemberOffset ResolvedFieldsOffset() { 89 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_); 90 } 91 ResolvedMethodsOffset()92 static MemberOffset ResolvedMethodsOffset() { 93 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_); 94 } 95 NumStringsOffset()96 static MemberOffset NumStringsOffset() { 97 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_strings_); 98 } 99 NumResolvedTypesOffset()100 static MemberOffset NumResolvedTypesOffset() { 101 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_types_); 102 } 103 NumResolvedFieldsOffset()104 static MemberOffset NumResolvedFieldsOffset() { 105 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_fields_); 106 } 107 NumResolvedMethodsOffset()108 static MemberOffset NumResolvedMethodsOffset() { 109 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_methods_); 110 } 111 112 String* GetResolvedString(uint32_t string_idx) ALWAYS_INLINE 113 SHARED_REQUIRES(Locks::mutator_lock_); 114 115 void SetResolvedString(uint32_t string_idx, String* resolved) ALWAYS_INLINE 116 SHARED_REQUIRES(Locks::mutator_lock_); 117 118 Class* GetResolvedType(uint32_t type_idx) SHARED_REQUIRES(Locks::mutator_lock_); 119 120 void SetResolvedType(uint32_t type_idx, Class* resolved) SHARED_REQUIRES(Locks::mutator_lock_); 121 122 ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, size_t ptr_size) 123 SHARED_REQUIRES(Locks::mutator_lock_); 124 125 ALWAYS_INLINE void SetResolvedMethod(uint32_t method_idx, ArtMethod* resolved, size_t ptr_size) 126 SHARED_REQUIRES(Locks::mutator_lock_); 127 128 // Pointer sized variant, used for patching. 129 ALWAYS_INLINE ArtField* GetResolvedField(uint32_t idx, size_t ptr_size) 130 SHARED_REQUIRES(Locks::mutator_lock_); 131 132 // Pointer sized variant, used for patching. 133 ALWAYS_INLINE void SetResolvedField(uint32_t idx, ArtField* field, size_t ptr_size) 134 SHARED_REQUIRES(Locks::mutator_lock_); 135 GetStrings()136 GcRoot<String>* GetStrings() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) { 137 return GetFieldPtr<GcRoot<String>*>(StringsOffset()); 138 } 139 SetStrings(GcRoot<String> * strings)140 void SetStrings(GcRoot<String>* strings) ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) { 141 SetFieldPtr<false>(StringsOffset(), strings); 142 } 143 GetResolvedTypes()144 GcRoot<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) { 145 return GetFieldPtr<GcRoot<Class>*>(ResolvedTypesOffset()); 146 } 147 SetResolvedTypes(GcRoot<Class> * resolved_types)148 void SetResolvedTypes(GcRoot<Class>* resolved_types) 149 ALWAYS_INLINE 150 SHARED_REQUIRES(Locks::mutator_lock_) { 151 SetFieldPtr<false>(ResolvedTypesOffset(), resolved_types); 152 } 153 GetResolvedMethods()154 ArtMethod** GetResolvedMethods() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) { 155 return GetFieldPtr<ArtMethod**>(ResolvedMethodsOffset()); 156 } 157 SetResolvedMethods(ArtMethod ** resolved_methods)158 void SetResolvedMethods(ArtMethod** resolved_methods) 159 ALWAYS_INLINE 160 SHARED_REQUIRES(Locks::mutator_lock_) { 161 SetFieldPtr<false>(ResolvedMethodsOffset(), resolved_methods); 162 } 163 GetResolvedFields()164 ArtField** GetResolvedFields() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) { 165 return GetFieldPtr<ArtField**>(ResolvedFieldsOffset()); 166 } 167 SetResolvedFields(ArtField ** resolved_fields)168 void SetResolvedFields(ArtField** resolved_fields) 169 ALWAYS_INLINE 170 SHARED_REQUIRES(Locks::mutator_lock_) { 171 SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields); 172 } 173 NumStrings()174 size_t NumStrings() SHARED_REQUIRES(Locks::mutator_lock_) { 175 return GetField32(NumStringsOffset()); 176 } 177 NumResolvedTypes()178 size_t NumResolvedTypes() SHARED_REQUIRES(Locks::mutator_lock_) { 179 return GetField32(NumResolvedTypesOffset()); 180 } 181 NumResolvedMethods()182 size_t NumResolvedMethods() SHARED_REQUIRES(Locks::mutator_lock_) { 183 return GetField32(NumResolvedMethodsOffset()); 184 } 185 NumResolvedFields()186 size_t NumResolvedFields() SHARED_REQUIRES(Locks::mutator_lock_) { 187 return GetField32(NumResolvedFieldsOffset()); 188 } 189 GetDexFile()190 const DexFile* GetDexFile() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) { 191 return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_)); 192 } 193 SetDexFile(const DexFile * dex_file)194 void SetDexFile(const DexFile* dex_file) SHARED_REQUIRES(Locks::mutator_lock_) { 195 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file); 196 } 197 198 void SetLocation(mirror::String* location) SHARED_REQUIRES(Locks::mutator_lock_); 199 200 // NOTE: Get/SetElementPtrSize() are intended for working with ArtMethod** and ArtField** 201 // provided by GetResolvedMethods/Fields() and ArtMethod::GetDexCacheResolvedMethods(), 202 // so they need to be public. 203 204 template <typename PtrType> 205 static PtrType GetElementPtrSize(PtrType* ptr_array, size_t idx, size_t ptr_size); 206 207 template <typename PtrType> 208 static void SetElementPtrSize(PtrType* ptr_array, size_t idx, PtrType ptr, size_t ptr_size); 209 210 private: 211 // Visit instance fields of the dex cache as well as its associated arrays. 212 template <bool kVisitNativeRoots, 213 VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, 214 ReadBarrierOption kReadBarrierOption = kWithReadBarrier, 215 typename Visitor> 216 void VisitReferences(mirror::Class* klass, const Visitor& visitor) 217 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_); 218 219 HeapReference<Object> dex_; 220 HeapReference<String> location_; 221 uint64_t dex_file_; // const DexFile* 222 uint64_t resolved_fields_; // ArtField*, array with num_resolved_fields_ elements. 223 uint64_t resolved_methods_; // ArtMethod*, array with num_resolved_methods_ elements. 224 uint64_t resolved_types_; // GcRoot<Class>*, array with num_resolved_types_ elements. 225 uint64_t strings_; // GcRoot<String>*, array with num_strings_ elements. 226 uint32_t num_resolved_fields_; // Number of elements in the resolved_fields_ array. 227 uint32_t num_resolved_methods_; // Number of elements in the resolved_methods_ array. 228 uint32_t num_resolved_types_; // Number of elements in the resolved_types_ array. 229 uint32_t num_strings_; // Number of elements in the strings_ array. 230 231 friend struct art::DexCacheOffsets; // for verifying offset information 232 friend class Object; // For VisitReferences 233 DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache); 234 }; 235 236 } // namespace mirror 237 } // namespace art 238 239 #endif // ART_RUNTIME_MIRROR_DEX_CACHE_H_ 240