blob: 1ae694d789f745ce60a01a1544b01f8a27bfc3e1 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070016
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_MIRROR_DEX_CACHE_H_
18#define ART_RUNTIME_MIRROR_DEX_CACHE_H_
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070019
Mathieu Chartiere401d142015-04-22 13:56:20 -070020#include "array.h"
Andreas Gampe58a5af82014-07-31 16:23:49 -070021#include "art_field.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070022#include "art_method.h"
Andreas Gampe58a5af82014-07-31 16:23:49 -070023#include "class.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070024#include "object.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080025#include "object_array.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070026
27namespace art {
28
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080029struct DexCacheOffsets;
30class DexFile;
31class ImageWriter;
32union JValue;
33
34namespace mirror {
35
Narayan Kamath25352fc2016-08-03 12:46:58 +010036class MethodType;
Mingyao Yang98d1cc82014-05-15 17:02:16 -070037class String;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070038
Narayan Kamathc38a6f82016-09-29 17:07:20 +010039template <typename T> struct PACKED(8) DexCachePair {
40 GcRoot<T> object;
41 uint32_t index;
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070042 // The array is initially [ {0,0}, {0,0}, {0,0} ... ]
43 // We maintain the invariant that once a dex cache entry is populated,
44 // the pointer is always non-0
45 // Any given entry would thus be:
46 // {non-0, non-0} OR {0,0}
47 //
48 // It's generally sufficiently enough then to check if the
Narayan Kamathc38a6f82016-09-29 17:07:20 +010049 // lookup index matches the stored index (for a >0 lookup index)
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070050 // because if it's true the pointer is also non-null.
51 //
52 // For the 0th entry which is a special case, the value is either
53 // {0,0} (initial state) or {non-0, 0} which indicates
Narayan Kamathc38a6f82016-09-29 17:07:20 +010054 // that a valid object is stored at that index for a dex section id of 0.
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070055 //
Narayan Kamathc38a6f82016-09-29 17:07:20 +010056 // As an optimization, we want to avoid branching on the object pointer since
57 // it's always non-null if the id branch succeeds (except for the 0th id).
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070058 // Set the initial state for the 0th entry to be {0,1} which is guaranteed to fail
Narayan Kamathc38a6f82016-09-29 17:07:20 +010059 // the lookup id == stored id branch.
60 DexCachePair(T* object, uint32_t index)
61 : object(object),
62 index(index) {}
63 DexCachePair() = default;
64 DexCachePair(const DexCachePair<T>&) = default;
65 DexCachePair& operator=(const DexCachePair<T>&) = default;
Mathieu Chartierbb816d62016-09-07 10:17:46 -070066
Narayan Kamathc38a6f82016-09-29 17:07:20 +010067 static void Initialize(std::atomic<DexCachePair<T>>* dex_cache) {
68 DexCachePair<T> first_elem;
69 first_elem.object = GcRoot<T>(nullptr);
70 first_elem.index = InvalidIndexForSlot(0);
71 dex_cache[0].store(first_elem, std::memory_order_relaxed);
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070072 }
Mathieu Chartierbb816d62016-09-07 10:17:46 -070073
Narayan Kamathc38a6f82016-09-29 17:07:20 +010074 static GcRoot<T> Lookup(std::atomic<DexCachePair<T>>* dex_cache,
75 uint32_t idx,
76 uint32_t cache_size) {
Narayan Kamath000e1882016-10-24 17:14:25 +010077 DCHECK_NE(cache_size, 0u);
Narayan Kamathc38a6f82016-09-29 17:07:20 +010078 DexCachePair<T> element = dex_cache[idx % cache_size].load(std::memory_order_relaxed);
79 if (idx != element.index) {
80 return GcRoot<T>(nullptr);
81 }
82
83 DCHECK(!element.object.IsNull());
84 return element.object;
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070085 }
Mathieu Chartierbb816d62016-09-07 10:17:46 -070086
Narayan Kamath23136d12016-09-30 16:29:19 +010087 static void Assign(std::atomic<DexCachePair<T>>* dex_cache,
88 uint32_t idx,
89 T* object,
90 uint32_t cache_size) {
91 DCHECK_LT(idx % cache_size, cache_size);
92 dex_cache[idx % cache_size].store(
93 DexCachePair<T>(object, idx), std::memory_order_relaxed);
94 }
95
Narayan Kamathc38a6f82016-09-29 17:07:20 +010096 static uint32_t InvalidIndexForSlot(uint32_t slot) {
Mathieu Chartierbb816d62016-09-07 10:17:46 -070097 // Since the cache size is a power of two, 0 will always map to slot 0.
98 // Use 1 for slot 0 and 0 for all other slots.
99 return (slot == 0) ? 1u : 0u;
100 }
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700101};
Narayan Kamathc38a6f82016-09-29 17:07:20 +0100102
103using StringDexCachePair = DexCachePair<mirror::String>;
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700104using StringDexCacheType = std::atomic<StringDexCachePair>;
105
Narayan Kamath25352fc2016-08-03 12:46:58 +0100106using MethodTypeDexCachePair = DexCachePair<mirror::MethodType>;
107using MethodTypeDexCacheType = std::atomic<MethodTypeDexCachePair>;
108
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700109// C++ mirror of java.lang.DexCache.
110class MANAGED DexCache FINAL : public Object {
Brian Carlstrom83db7722011-08-26 17:32:56 -0700111 public:
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700112 // Size of java.lang.DexCache.class.
Andreas Gampe542451c2016-07-26 09:02:02 -0700113 static uint32_t ClassSize(PointerSize pointer_size);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700114
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700115 // Size of string dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
116 static constexpr size_t kDexCacheStringCacheSize = 1024;
117 static_assert(IsPowerOfTwo(kDexCacheStringCacheSize),
118 "String dex cache size is not a power of 2.");
119
Narayan Kamath25352fc2016-08-03 12:46:58 +0100120 // Size of method type dex cache. Needs to be a power of 2 for entrypoint assumptions
121 // to hold.
122 static constexpr size_t kDexCacheMethodTypeCacheSize = 1024;
123 static_assert(IsPowerOfTwo(kDexCacheMethodTypeCacheSize),
124 "MethodType dex cache size is not a power of 2.");
125
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700126 static constexpr size_t StaticStringSize() {
127 return kDexCacheStringCacheSize;
128 }
129
Narayan Kamath25352fc2016-08-03 12:46:58 +0100130 static constexpr size_t StaticMethodTypeSize() {
131 return kDexCacheMethodTypeCacheSize;
132 }
133
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700134 // Size of an instance of java.lang.DexCache not including referenced values.
135 static constexpr uint32_t InstanceSize() {
136 return sizeof(DexCache);
137 }
138
Vladimir Marko05792b92015-08-03 11:56:49 +0100139 void Init(const DexFile* dex_file,
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700140 ObjPtr<String> location,
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700141 StringDexCacheType* strings,
Vladimir Marko05792b92015-08-03 11:56:49 +0100142 uint32_t num_strings,
143 GcRoot<Class>* resolved_types,
144 uint32_t num_resolved_types,
145 ArtMethod** resolved_methods,
146 uint32_t num_resolved_methods,
147 ArtField** resolved_fields,
148 uint32_t num_resolved_fields,
Narayan Kamath25352fc2016-08-03 12:46:58 +0100149 MethodTypeDexCacheType* resolved_methodtypes,
150 uint32_t num_resolved_methodtypes,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700151 PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700152
Andreas Gampe542451c2016-07-26 09:02:02 -0700153 void Fixup(ArtMethod* trampoline, PointerSize pointer_size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700154 REQUIRES_SHARED(Locks::mutator_lock_);
Ian Rogers19846512012-02-24 11:42:47 -0800155
Mathieu Chartier60bc39c2016-01-27 18:37:48 -0800156 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700157 void FixupStrings(StringDexCacheType* dest, const Visitor& visitor)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700158 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier4b00d342015-11-13 10:42:08 -0800159
Mathieu Chartier60bc39c2016-01-27 18:37:48 -0800160 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
Mathieu Chartier4b00d342015-11-13 10:42:08 -0800161 void FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700162 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier4b00d342015-11-13 10:42:08 -0800163
Narayan Kamath7fe56582016-10-14 18:49:12 +0100164 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
165 void FixupResolvedMethodTypes(MethodTypeDexCacheType* dest, const Visitor& visitor)
166 REQUIRES_SHARED(Locks::mutator_lock_);
167
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700168 String* GetLocation() REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700169 return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_));
Brian Carlstroma663ea52011-08-19 23:33:41 -0700170 }
171
Andreas Gampedd9d0552015-03-09 12:57:41 -0700172 static MemberOffset DexOffset() {
173 return OFFSET_OF_OBJECT_MEMBER(DexCache, dex_);
174 }
175
buzbee5cd21802011-08-26 10:40:14 -0700176 static MemberOffset StringsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700177 return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_);
buzbeec5ef0462011-08-25 18:44:49 -0700178 }
179
Vladimir Marko05792b92015-08-03 11:56:49 +0100180 static MemberOffset ResolvedTypesOffset() {
181 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_);
182 }
183
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700184 static MemberOffset ResolvedFieldsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700185 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_);
buzbeec5ef0462011-08-25 18:44:49 -0700186 }
187
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700188 static MemberOffset ResolvedMethodsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700189 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
buzbeec5ef0462011-08-25 18:44:49 -0700190 }
191
Narayan Kamath25352fc2016-08-03 12:46:58 +0100192 static MemberOffset ResolvedMethodTypesOffset() {
193 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_method_types_);
194 }
195
Vladimir Marko05792b92015-08-03 11:56:49 +0100196 static MemberOffset NumStringsOffset() {
197 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_strings_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700198 }
199
Vladimir Marko05792b92015-08-03 11:56:49 +0100200 static MemberOffset NumResolvedTypesOffset() {
201 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_types_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700202 }
203
Vladimir Marko05792b92015-08-03 11:56:49 +0100204 static MemberOffset NumResolvedFieldsOffset() {
205 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_fields_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700206 }
207
Vladimir Marko05792b92015-08-03 11:56:49 +0100208 static MemberOffset NumResolvedMethodsOffset() {
209 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_methods_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700210 }
211
Narayan Kamath25352fc2016-08-03 12:46:58 +0100212 static MemberOffset NumResolvedMethodTypesOffset() {
213 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_method_types_);
214 }
215
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700216 mirror::String* GetResolvedString(uint32_t string_idx) ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700217 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700218
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700219 void SetResolvedString(uint32_t string_idx, ObjPtr<mirror::String> resolved) ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700220 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700221
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700222 // Clear a string for a string_idx, used to undo string intern transactions to make sure
223 // the string isn't kept live.
224 void ClearString(uint32_t string_idx) REQUIRES_SHARED(Locks::mutator_lock_);
225
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700226 Class* GetResolvedType(uint32_t type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100227
Mathieu Chartier31e88222016-10-14 18:43:19 -0700228 void SetResolvedType(uint32_t type_idx, ObjPtr<Class> resolved)
229 REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100230
Andreas Gampe542451c2016-07-26 09:02:02 -0700231 ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, PointerSize ptr_size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700232 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700233
Andreas Gampe542451c2016-07-26 09:02:02 -0700234 ALWAYS_INLINE void SetResolvedMethod(uint32_t method_idx,
235 ArtMethod* resolved,
236 PointerSize ptr_size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700237 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700238
Mathieu Chartierc7853442015-03-27 14:35:38 -0700239 // Pointer sized variant, used for patching.
Andreas Gampe542451c2016-07-26 09:02:02 -0700240 ALWAYS_INLINE ArtField* GetResolvedField(uint32_t idx, PointerSize ptr_size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700241 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700242
243 // Pointer sized variant, used for patching.
Andreas Gampe542451c2016-07-26 09:02:02 -0700244 ALWAYS_INLINE void SetResolvedField(uint32_t idx, ArtField* field, PointerSize ptr_size)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700245 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700246
Narayan Kamath25352fc2016-08-03 12:46:58 +0100247 MethodType* GetResolvedMethodType(uint32_t proto_idx) REQUIRES_SHARED(Locks::mutator_lock_);
248
249 void SetResolvedMethodType(uint32_t proto_idx, MethodType* resolved) REQUIRES_SHARED(Locks::mutator_lock_);
250
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700251 StringDexCacheType* GetStrings() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700252 return GetFieldPtr64<StringDexCacheType*>(StringsOffset());
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700253 }
Brian Carlstrom83db7722011-08-26 17:32:56 -0700254
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700255 void SetStrings(StringDexCacheType* strings) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800256 SetFieldPtr<false>(StringsOffset(), strings);
257 }
258
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700259 GcRoot<Class>* GetResolvedTypes() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100260 return GetFieldPtr<GcRoot<Class>*>(ResolvedTypesOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700261 }
262
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800263 void SetResolvedTypes(GcRoot<Class>* resolved_types)
264 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700265 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800266 SetFieldPtr<false>(ResolvedTypesOffset(), resolved_types);
267 }
268
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700269 ArtMethod** GetResolvedMethods() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100270 return GetFieldPtr<ArtMethod**>(ResolvedMethodsOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700271 }
272
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800273 void SetResolvedMethods(ArtMethod** resolved_methods)
274 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700275 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800276 SetFieldPtr<false>(ResolvedMethodsOffset(), resolved_methods);
277 }
278
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700279 ArtField** GetResolvedFields() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100280 return GetFieldPtr<ArtField**>(ResolvedFieldsOffset());
281 }
282
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800283 void SetResolvedFields(ArtField** resolved_fields)
284 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700285 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800286 SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields);
287 }
288
Narayan Kamath25352fc2016-08-03 12:46:58 +0100289 MethodTypeDexCacheType* GetResolvedMethodTypes()
290 ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Narayan Kamath7fe56582016-10-14 18:49:12 +0100291 return GetFieldPtr64<MethodTypeDexCacheType*>(ResolvedMethodTypesOffset());
Narayan Kamath25352fc2016-08-03 12:46:58 +0100292 }
293
294 void SetResolvedMethodTypes(MethodTypeDexCacheType* resolved_method_types)
295 ALWAYS_INLINE
296 REQUIRES_SHARED(Locks::mutator_lock_) {
297 SetFieldPtr<false>(ResolvedMethodTypesOffset(), resolved_method_types);
298 }
299
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700300 size_t NumStrings() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100301 return GetField32(NumStringsOffset());
302 }
303
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700304 size_t NumResolvedTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100305 return GetField32(NumResolvedTypesOffset());
306 }
307
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700308 size_t NumResolvedMethods() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100309 return GetField32(NumResolvedMethodsOffset());
310 }
311
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700312 size_t NumResolvedFields() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100313 return GetField32(NumResolvedFieldsOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700314 }
315
Narayan Kamath25352fc2016-08-03 12:46:58 +0100316 size_t NumResolvedMethodTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
317 return GetField32(NumResolvedMethodTypesOffset());
318 }
319
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700320 const DexFile* GetDexFile() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700321 return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
Mathieu Chartier66f19252012-09-18 08:57:04 -0700322 }
323
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700324 void SetDexFile(const DexFile* dex_file) REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier76172162016-01-26 14:54:06 -0800325 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700326 }
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700327
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700328 void SetLocation(ObjPtr<mirror::String> location) REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier76172162016-01-26 14:54:06 -0800329
Vladimir Marko05792b92015-08-03 11:56:49 +0100330 // NOTE: Get/SetElementPtrSize() are intended for working with ArtMethod** and ArtField**
331 // provided by GetResolvedMethods/Fields() and ArtMethod::GetDexCacheResolvedMethods(),
332 // so they need to be public.
333
334 template <typename PtrType>
Andreas Gampe542451c2016-07-26 09:02:02 -0700335 static PtrType GetElementPtrSize(PtrType* ptr_array, size_t idx, PointerSize ptr_size);
Vladimir Marko05792b92015-08-03 11:56:49 +0100336
337 template <typename PtrType>
Andreas Gampe542451c2016-07-26 09:02:02 -0700338 static void SetElementPtrSize(PtrType* ptr_array, size_t idx, PtrType ptr, PointerSize ptr_size);
Vladimir Marko05792b92015-08-03 11:56:49 +0100339
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700340 private:
Vladimir Marko05792b92015-08-03 11:56:49 +0100341 // Visit instance fields of the dex cache as well as its associated arrays.
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800342 template <bool kVisitNativeRoots,
343 VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
344 ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
345 typename Visitor>
Mathieu Chartier31e88222016-10-14 18:43:19 -0700346 void VisitReferences(ObjPtr<mirror::Class> klass, const Visitor& visitor)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700347 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100348
Ian Rogersef7d42f2014-01-06 12:55:46 -0800349 HeapReference<Object> dex_;
350 HeapReference<String> location_;
Narayan Kamath25352fc2016-08-03 12:46:58 +0100351 uint64_t dex_file_; // const DexFile*
352 uint64_t resolved_fields_; // ArtField*, array with num_resolved_fields_ elements.
353 uint64_t resolved_method_types_; // std::atomic<MethodTypeDexCachePair>* array with
354 // num_resolved_method_types_ elements.
355 uint64_t resolved_methods_; // ArtMethod*, array with num_resolved_methods_ elements.
356 uint64_t resolved_types_; // GcRoot<Class>*, array with num_resolved_types_ elements.
357 uint64_t strings_; // std::atomic<StringDexCachePair>*, array with num_strings_
358 // elements.
359
360 uint32_t num_resolved_fields_; // Number of elements in the resolved_fields_ array.
361 uint32_t num_resolved_method_types_; // Number of elements in the resolved_method_types_ array.
362 uint32_t num_resolved_methods_; // Number of elements in the resolved_methods_ array.
363 uint32_t num_resolved_types_; // Number of elements in the resolved_types_ array.
364 uint32_t num_strings_; // Number of elements in the strings_ array.
Brian Carlstrom83db7722011-08-26 17:32:56 -0700365
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700366 friend struct art::DexCacheOffsets; // for verifying offset information
Vladimir Marko05792b92015-08-03 11:56:49 +0100367 friend class Object; // For VisitReferences
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700368 DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700369};
370
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800371} // namespace mirror
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700372} // namespace art
373
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700374#endif // ART_RUNTIME_MIRROR_DEX_CACHE_H_