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 "art_field.h" 21 #include "art_method.h" 22 #include "class.h" 23 #include "object.h" 24 #include "object_array.h" 25 26 namespace art { 27 28 struct DexCacheOffsets; 29 class DexFile; 30 class ImageWriter; 31 union JValue; 32 33 namespace mirror { 34 35 class String; 36 37 // C++ mirror of java.lang.DexCache. 38 class MANAGED DexCache FINAL : public Object { 39 public: 40 // Size of java.lang.DexCache.class. 41 static uint32_t ClassSize(); 42 43 // Size of an instance of java.lang.DexCache not including referenced values. 44 static constexpr uint32_t InstanceSize() { 45 return sizeof(DexCache); 46 } 47 48 void Init(const DexFile* dex_file, 49 String* location, 50 ObjectArray<String>* strings, 51 ObjectArray<Class>* types, 52 ObjectArray<ArtMethod>* methods, 53 ObjectArray<ArtField>* fields) 54 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 55 56 void Fixup(ArtMethod* trampoline) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 57 58 String* GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 59 return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_)); 60 } 61 62 static MemberOffset StringsOffset() { 63 return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_); 64 } 65 66 static MemberOffset ResolvedFieldsOffset() { 67 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_); 68 } 69 70 static MemberOffset ResolvedMethodsOffset() { 71 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_); 72 } 73 74 size_t NumStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 75 return GetStrings()->GetLength(); 76 } 77 78 size_t NumResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 79 return GetResolvedTypes()->GetLength(); 80 } 81 82 size_t NumResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 83 return GetResolvedMethods()->GetLength(); 84 } 85 86 size_t NumResolvedFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 87 return GetResolvedFields()->GetLength(); 88 } 89 90 String* GetResolvedString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 91 return GetStrings()->Get(string_idx); 92 } 93 94 void SetResolvedString(uint32_t string_idx, String* resolved) ALWAYS_INLINE 95 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 96 // TODO default transaction support. 97 GetStrings()->Set(string_idx, resolved); 98 } 99 100 Class* GetResolvedType(uint32_t type_idx) ALWAYS_INLINE 101 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 102 return GetResolvedTypes()->Get(type_idx); 103 } 104 105 void SetResolvedType(uint32_t type_idx, Class* resolved) 106 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 107 108 ArtMethod* GetResolvedMethod(uint32_t method_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 109 110 void SetResolvedMethod(uint32_t method_idx, ArtMethod* resolved) ALWAYS_INLINE 111 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 112 GetResolvedMethods()->Set(method_idx, resolved); 113 } 114 115 ArtField* GetResolvedField(uint32_t field_idx) ALWAYS_INLINE 116 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 117 ArtField* field = GetResolvedFields()->Get(field_idx); 118 if (UNLIKELY(field == nullptr || field->GetDeclaringClass()->IsErroneous())) { 119 return nullptr; 120 } else { 121 return field; 122 } 123 } 124 125 void SetResolvedField(uint32_t field_idx, ArtField* resolved) ALWAYS_INLINE 126 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 127 GetResolvedFields()->Set(field_idx, resolved); 128 } 129 130 ObjectArray<String>* GetStrings() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 131 return GetFieldObject< ObjectArray<String>>(StringsOffset()); 132 } 133 134 ObjectArray<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 135 return GetFieldObject<ObjectArray<Class>>( 136 OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_)); 137 } 138 139 ObjectArray<ArtMethod>* GetResolvedMethods() ALWAYS_INLINE 140 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 141 return GetFieldObject< ObjectArray<ArtMethod>>(ResolvedMethodsOffset()); 142 } 143 144 ObjectArray<ArtField>* GetResolvedFields() ALWAYS_INLINE 145 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 146 return GetFieldObject<ObjectArray<ArtField>>(ResolvedFieldsOffset()); 147 } 148 149 const DexFile* GetDexFile() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 150 return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_)); 151 } 152 153 void SetDexFile(const DexFile* dex_file) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 154 ALWAYS_INLINE { 155 return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file); 156 } 157 158 private: 159 HeapReference<Object> dex_; 160 HeapReference<String> location_; 161 HeapReference<ObjectArray<ArtField>> resolved_fields_; 162 HeapReference<ObjectArray<ArtMethod>> resolved_methods_; 163 HeapReference<ObjectArray<Class>> resolved_types_; 164 HeapReference<ObjectArray<String>> strings_; 165 uint64_t dex_file_; 166 167 friend struct art::DexCacheOffsets; // for verifying offset information 168 DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache); 169 }; 170 171 } // namespace mirror 172 } // namespace art 173 174 #endif // ART_RUNTIME_MIRROR_DEX_CACHE_H_ 175