blob: 26fc520cd7018788f8d0e254b2a953678dd8bf6d [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"
David Srbeckye153a622021-03-02 15:07:26 +000021#include "base/array_ref.h"
Vladimir Marko8d6768d2017-03-14 10:13:21 +000022#include "base/bit_utils.h"
Andreas Gampe7fbc4a52018-11-28 08:26:47 -080023#include "base/locks.h"
David Sehr9e734c72018-01-04 17:56:19 -080024#include "dex/dex_file_types.h"
Andreas Gampe88dbad32018-06-26 19:54:12 -070025#include "gc_root.h" // Note: must not use -inl here to avoid circular dependency.
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070026#include "object.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027#include "object_array.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070028
29namespace art {
30
Vladimir Markoca8de0a2018-07-04 11:56:08 +010031namespace linker {
32class ImageWriter;
33} // namespace linker
34
Vladimir Marko8d6768d2017-03-14 10:13:21 +000035class ArtField;
Alex Lightdba61482016-12-21 08:20:29 -080036class ArtMethod;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080037struct DexCacheOffsets;
38class DexFile;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080039union JValue;
Andreas Gampecc1b5352016-12-01 16:58:38 -080040class LinearAlloc;
Alex Lightc18eba32019-09-24 14:36:27 -070041class ReflectiveValueVisitor;
Andreas Gampecc1b5352016-12-01 16:58:38 -080042class Thread;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043
44namespace mirror {
45
Orion Hodsonc069a302017-01-18 09:23:12 +000046class CallSite;
Vladimir Marko8d6768d2017-03-14 10:13:21 +000047class Class;
Andreas Gampe8a1a0f72020-03-03 16:07:45 -080048class ClassLoader;
Narayan Kamath25352fc2016-08-03 12:46:58 +010049class MethodType;
Mingyao Yang98d1cc82014-05-15 17:02:16 -070050class String;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070051
Narayan Kamathc38a6f82016-09-29 17:07:20 +010052template <typename T> struct PACKED(8) DexCachePair {
53 GcRoot<T> object;
54 uint32_t index;
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070055 // The array is initially [ {0,0}, {0,0}, {0,0} ... ]
56 // We maintain the invariant that once a dex cache entry is populated,
57 // the pointer is always non-0
58 // Any given entry would thus be:
59 // {non-0, non-0} OR {0,0}
60 //
61 // It's generally sufficiently enough then to check if the
Narayan Kamathc38a6f82016-09-29 17:07:20 +010062 // lookup index matches the stored index (for a >0 lookup index)
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070063 // because if it's true the pointer is also non-null.
64 //
65 // For the 0th entry which is a special case, the value is either
66 // {0,0} (initial state) or {non-0, 0} which indicates
Narayan Kamathc38a6f82016-09-29 17:07:20 +010067 // that a valid object is stored at that index for a dex section id of 0.
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070068 //
Narayan Kamathc38a6f82016-09-29 17:07:20 +010069 // As an optimization, we want to avoid branching on the object pointer since
70 // it's always non-null if the id branch succeeds (except for the 0th id).
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070071 // Set the initial state for the 0th entry to be {0,1} which is guaranteed to fail
Narayan Kamathc38a6f82016-09-29 17:07:20 +010072 // the lookup id == stored id branch.
Andreas Gampe88dbad32018-06-26 19:54:12 -070073 DexCachePair(ObjPtr<T> object, uint32_t index);
Andreas Gamped9911ee2017-03-27 13:27:24 -070074 DexCachePair() : index(0) {}
Narayan Kamathc38a6f82016-09-29 17:07:20 +010075 DexCachePair(const DexCachePair<T>&) = default;
76 DexCachePair& operator=(const DexCachePair<T>&) = default;
Mathieu Chartierbb816d62016-09-07 10:17:46 -070077
Andreas Gampe88dbad32018-06-26 19:54:12 -070078 static void Initialize(std::atomic<DexCachePair<T>>* dex_cache);
Mathieu Chartierbb816d62016-09-07 10:17:46 -070079
Narayan Kamathc38a6f82016-09-29 17:07:20 +010080 static uint32_t InvalidIndexForSlot(uint32_t slot) {
Mathieu Chartierbb816d62016-09-07 10:17:46 -070081 // Since the cache size is a power of two, 0 will always map to slot 0.
82 // Use 1 for slot 0 and 0 for all other slots.
83 return (slot == 0) ? 1u : 0u;
84 }
Vladimir Marko8d6768d2017-03-14 10:13:21 +000085
Andreas Gampe88dbad32018-06-26 19:54:12 -070086 T* GetObjectForIndex(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_);
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070087};
Narayan Kamathc38a6f82016-09-29 17:07:20 +010088
Vladimir Markof44d36c2017-03-14 14:18:46 +000089template <typename T> struct PACKED(2 * __SIZEOF_POINTER__) NativeDexCachePair {
90 T* object;
91 size_t index;
92 // This is similar to DexCachePair except that we're storing a native pointer
93 // instead of a GC root. See DexCachePair for the details.
94 NativeDexCachePair(T* object, uint32_t index)
95 : object(object),
96 index(index) {}
97 NativeDexCachePair() : object(nullptr), index(0u) { }
98 NativeDexCachePair(const NativeDexCachePair<T>&) = default;
99 NativeDexCachePair& operator=(const NativeDexCachePair<T>&) = default;
100
David Srbecky5de5efe2021-02-15 21:23:00 +0000101 static void Initialize(std::atomic<NativeDexCachePair<T>>* dex_cache);
Vladimir Markof44d36c2017-03-14 14:18:46 +0000102
103 static uint32_t InvalidIndexForSlot(uint32_t slot) {
104 // Since the cache size is a power of two, 0 will always map to slot 0.
105 // Use 1 for slot 0 and 0 for all other slots.
106 return (slot == 0) ? 1u : 0u;
107 }
108
109 T* GetObjectForIndex(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_) {
110 if (idx != index) {
111 return nullptr;
112 }
113 DCHECK(object != nullptr);
114 return object;
115 }
116};
117
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000118using TypeDexCachePair = DexCachePair<Class>;
119using TypeDexCacheType = std::atomic<TypeDexCachePair>;
120
121using StringDexCachePair = DexCachePair<String>;
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700122using StringDexCacheType = std::atomic<StringDexCachePair>;
123
Vladimir Markof44d36c2017-03-14 14:18:46 +0000124using FieldDexCachePair = NativeDexCachePair<ArtField>;
125using FieldDexCacheType = std::atomic<FieldDexCachePair>;
126
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100127using MethodDexCachePair = NativeDexCachePair<ArtMethod>;
128using MethodDexCacheType = std::atomic<MethodDexCachePair>;
129
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000130using MethodTypeDexCachePair = DexCachePair<MethodType>;
Narayan Kamath25352fc2016-08-03 12:46:58 +0100131using MethodTypeDexCacheType = std::atomic<MethodTypeDexCachePair>;
132
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700133// C++ mirror of java.lang.DexCache.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100134class MANAGED DexCache final : public Object {
Brian Carlstrom83db7722011-08-26 17:32:56 -0700135 public:
Alex Light8f187c32021-04-20 14:29:00 -0700136 MIRROR_CLASS("Ljava/lang/DexCache;");
137
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700138 // Size of java.lang.DexCache.class.
Andreas Gampe542451c2016-07-26 09:02:02 -0700139 static uint32_t ClassSize(PointerSize pointer_size);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700140
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000141 // Size of type dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
142 static constexpr size_t kDexCacheTypeCacheSize = 1024;
143 static_assert(IsPowerOfTwo(kDexCacheTypeCacheSize),
144 "Type dex cache size is not a power of 2.");
145
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700146 // Size of string dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
147 static constexpr size_t kDexCacheStringCacheSize = 1024;
148 static_assert(IsPowerOfTwo(kDexCacheStringCacheSize),
149 "String dex cache size is not a power of 2.");
150
Vladimir Markof44d36c2017-03-14 14:18:46 +0000151 // Size of field dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
Vladimir Marko990fc442018-08-29 13:58:23 +0000152 static constexpr size_t kDexCacheFieldCacheSize = 1024;
Vladimir Markof44d36c2017-03-14 14:18:46 +0000153 static_assert(IsPowerOfTwo(kDexCacheFieldCacheSize),
154 "Field dex cache size is not a power of 2.");
155
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100156 // Size of method dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
Vladimir Marko990fc442018-08-29 13:58:23 +0000157 static constexpr size_t kDexCacheMethodCacheSize = 1024;
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100158 static_assert(IsPowerOfTwo(kDexCacheMethodCacheSize),
159 "Method dex cache size is not a power of 2.");
160
Narayan Kamath25352fc2016-08-03 12:46:58 +0100161 // Size of method type dex cache. Needs to be a power of 2 for entrypoint assumptions
162 // to hold.
163 static constexpr size_t kDexCacheMethodTypeCacheSize = 1024;
164 static_assert(IsPowerOfTwo(kDexCacheMethodTypeCacheSize),
165 "MethodType dex cache size is not a power of 2.");
166
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000167 static constexpr size_t StaticTypeSize() {
168 return kDexCacheTypeCacheSize;
169 }
170
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700171 static constexpr size_t StaticStringSize() {
172 return kDexCacheStringCacheSize;
173 }
174
Vladimir Markof44d36c2017-03-14 14:18:46 +0000175 static constexpr size_t StaticArtFieldSize() {
176 return kDexCacheFieldCacheSize;
177 }
178
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100179 static constexpr size_t StaticMethodSize() {
180 return kDexCacheMethodCacheSize;
181 }
182
Narayan Kamath25352fc2016-08-03 12:46:58 +0100183 static constexpr size_t StaticMethodTypeSize() {
184 return kDexCacheMethodTypeCacheSize;
185 }
186
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700187 // Size of an instance of java.lang.DexCache not including referenced values.
188 static constexpr uint32_t InstanceSize() {
189 return sizeof(DexCache);
190 }
191
David Srbeckye153a622021-03-02 15:07:26 +0000192 void Initialize(const DexFile* dex_file, ObjPtr<ClassLoader> class_loader)
Andreas Gampecc1b5352016-12-01 16:58:38 -0800193 REQUIRES_SHARED(Locks::mutator_lock_)
194 REQUIRES(Locks::dex_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700195
David Srbeckye153a622021-03-02 15:07:26 +0000196 // Zero all array references.
197 // WARNING: This does not free the memory since it is in LinearAlloc.
198 void ResetNativeArrays() REQUIRES_SHARED(Locks::mutator_lock_);
Orion Hodsonc069a302017-01-18 09:23:12 +0000199
Vladimir Marko58412b12019-04-01 13:26:34 +0100200 ObjPtr<String> GetLocation() REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700201
David Srbecky56de89a2018-10-01 15:32:20 +0100202 static constexpr MemberOffset StringsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700203 return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_);
buzbeec5ef0462011-08-25 18:44:49 -0700204 }
205
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700206 static constexpr MemberOffset PreResolvedStringsOffset() {
207 return OFFSET_OF_OBJECT_MEMBER(DexCache, preresolved_strings_);
208 }
209
David Srbecky56de89a2018-10-01 15:32:20 +0100210 static constexpr MemberOffset ResolvedTypesOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100211 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_);
212 }
213
David Srbecky56de89a2018-10-01 15:32:20 +0100214 static constexpr MemberOffset ResolvedFieldsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700215 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_);
buzbeec5ef0462011-08-25 18:44:49 -0700216 }
217
David Srbecky56de89a2018-10-01 15:32:20 +0100218 static constexpr MemberOffset ResolvedMethodsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700219 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
buzbeec5ef0462011-08-25 18:44:49 -0700220 }
221
David Srbecky56de89a2018-10-01 15:32:20 +0100222 static constexpr MemberOffset ResolvedMethodTypesOffset() {
Narayan Kamath25352fc2016-08-03 12:46:58 +0100223 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_method_types_);
224 }
225
David Srbecky56de89a2018-10-01 15:32:20 +0100226 static constexpr MemberOffset ResolvedCallSitesOffset() {
Orion Hodsonc069a302017-01-18 09:23:12 +0000227 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_call_sites_);
228 }
229
David Srbecky56de89a2018-10-01 15:32:20 +0100230 static constexpr MemberOffset NumStringsOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100231 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_strings_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700232 }
233
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700234 static constexpr MemberOffset NumPreResolvedStringsOffset() {
235 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_preresolved_strings_);
236 }
237
David Srbecky56de89a2018-10-01 15:32:20 +0100238 static constexpr MemberOffset NumResolvedTypesOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100239 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_types_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700240 }
241
David Srbecky56de89a2018-10-01 15:32:20 +0100242 static constexpr MemberOffset NumResolvedFieldsOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100243 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_fields_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700244 }
245
David Srbecky56de89a2018-10-01 15:32:20 +0100246 static constexpr MemberOffset NumResolvedMethodsOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100247 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_methods_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700248 }
249
David Srbecky56de89a2018-10-01 15:32:20 +0100250 static constexpr MemberOffset NumResolvedMethodTypesOffset() {
Narayan Kamath25352fc2016-08-03 12:46:58 +0100251 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_method_types_);
252 }
253
David Srbecky56de89a2018-10-01 15:32:20 +0100254 static constexpr MemberOffset NumResolvedCallSitesOffset() {
Orion Hodsonc069a302017-01-18 09:23:12 +0000255 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_call_sites_);
256 }
257
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700258 static constexpr size_t PreResolvedStringsAlignment() {
259 return alignof(GcRoot<mirror::String>);
260 }
261
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000262 String* GetResolvedString(dex::StringIndex string_idx) ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700263 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700264
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800265 void SetResolvedString(dex::StringIndex string_idx, ObjPtr<mirror::String> resolved) ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700266 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700267
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700268 // Clear a string for a string_idx, used to undo string intern transactions to make sure
269 // the string isn't kept live.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800270 void ClearString(dex::StringIndex string_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700271
Andreas Gampea5b09a62016-11-17 15:21:22 -0800272 Class* GetResolvedType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100273
Andreas Gampea5b09a62016-11-17 15:21:22 -0800274 void SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved)
Mathieu Chartier31e88222016-10-14 18:43:19 -0700275 REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100276
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000277 void ClearResolvedType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
278
David Srbecky5de5efe2021-02-15 21:23:00 +0000279 ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700280 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700281
David Srbecky5de5efe2021-02-15 21:23:00 +0000282 ALWAYS_INLINE void SetResolvedMethod(uint32_t method_idx, ArtMethod* resolved)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700283 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700284
David Srbecky5de5efe2021-02-15 21:23:00 +0000285 ALWAYS_INLINE ArtField* GetResolvedField(uint32_t idx)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700286 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700287
David Srbecky5de5efe2021-02-15 21:23:00 +0000288 ALWAYS_INLINE void SetResolvedField(uint32_t idx, ArtField* field)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700289 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700290
Orion Hodson06d10a72018-05-14 08:53:38 +0100291 MethodType* GetResolvedMethodType(dex::ProtoIndex proto_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Narayan Kamath25352fc2016-08-03 12:46:58 +0100292
Orion Hodson06d10a72018-05-14 08:53:38 +0100293 void SetResolvedMethodType(dex::ProtoIndex proto_idx, MethodType* resolved)
Orion Hodsonc069a302017-01-18 09:23:12 +0000294 REQUIRES_SHARED(Locks::mutator_lock_);
295
Vladimir Markoe9a4a602021-06-22 16:33:34 +0100296 // Clear a method type for proto_idx, used to undo method type resolution
297 // in aborted transactions to make sure the method type isn't kept live.
298 void ClearMethodType(dex::ProtoIndex proto_idx) REQUIRES_SHARED(Locks::mutator_lock_);
299
Orion Hodsonc069a302017-01-18 09:23:12 +0000300 CallSite* GetResolvedCallSite(uint32_t call_site_idx) REQUIRES_SHARED(Locks::mutator_lock_);
301
302 // Attempts to bind |call_site_idx| to the call site |resolved|. The
303 // caller must use the return value in place of |resolved|. This is
304 // because multiple threads can invoke the bootstrap method each
305 // producing a call site, but the method handle invocation on the
306 // call site must be on a common agreed value.
Orion Hodson4c8e12e2018-05-18 08:33:20 +0100307 ObjPtr<CallSite> SetResolvedCallSite(uint32_t call_site_idx, ObjPtr<CallSite> resolved)
308 REQUIRES_SHARED(Locks::mutator_lock_) WARN_UNUSED;
Narayan Kamath25352fc2016-08-03 12:46:58 +0100309
Vladimir Marko98db89c2018-09-07 11:45:46 +0100310 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700311 StringDexCacheType* GetStrings() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100312 return GetFieldPtr64<StringDexCacheType*, kVerifyFlags>(StringsOffset());
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700313 }
Brian Carlstrom83db7722011-08-26 17:32:56 -0700314
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700315 void SetStrings(StringDexCacheType* strings) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800316 SetFieldPtr<false>(StringsOffset(), strings);
317 }
318
Vladimir Marko98db89c2018-09-07 11:45:46 +0100319 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000320 TypeDexCacheType* GetResolvedTypes() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100321 return GetFieldPtr<TypeDexCacheType*, kVerifyFlags>(ResolvedTypesOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700322 }
323
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000324 void SetResolvedTypes(TypeDexCacheType* resolved_types)
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800325 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700326 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800327 SetFieldPtr<false>(ResolvedTypesOffset(), resolved_types);
328 }
329
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100330 MethodDexCacheType* GetResolvedMethods() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
331 return GetFieldPtr<MethodDexCacheType*>(ResolvedMethodsOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700332 }
333
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100334 void SetResolvedMethods(MethodDexCacheType* resolved_methods)
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800335 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700336 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800337 SetFieldPtr<false>(ResolvedMethodsOffset(), resolved_methods);
338 }
339
Vladimir Markof44d36c2017-03-14 14:18:46 +0000340 FieldDexCacheType* GetResolvedFields() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
341 return GetFieldPtr<FieldDexCacheType*>(ResolvedFieldsOffset());
Vladimir Marko05792b92015-08-03 11:56:49 +0100342 }
343
Vladimir Markof44d36c2017-03-14 14:18:46 +0000344 void SetResolvedFields(FieldDexCacheType* resolved_fields)
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800345 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700346 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800347 SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields);
348 }
349
Vladimir Marko98db89c2018-09-07 11:45:46 +0100350 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Narayan Kamath25352fc2016-08-03 12:46:58 +0100351 MethodTypeDexCacheType* GetResolvedMethodTypes()
352 ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100353 return GetFieldPtr64<MethodTypeDexCacheType*, kVerifyFlags>(ResolvedMethodTypesOffset());
Narayan Kamath25352fc2016-08-03 12:46:58 +0100354 }
355
356 void SetResolvedMethodTypes(MethodTypeDexCacheType* resolved_method_types)
357 ALWAYS_INLINE
358 REQUIRES_SHARED(Locks::mutator_lock_) {
359 SetFieldPtr<false>(ResolvedMethodTypesOffset(), resolved_method_types);
360 }
361
Vladimir Marko98db89c2018-09-07 11:45:46 +0100362 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Orion Hodsonc069a302017-01-18 09:23:12 +0000363 GcRoot<CallSite>* GetResolvedCallSites()
364 ALWAYS_INLINE
365 REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100366 return GetFieldPtr<GcRoot<CallSite>*, kVerifyFlags>(ResolvedCallSitesOffset());
Orion Hodsonc069a302017-01-18 09:23:12 +0000367 }
368
369 void SetResolvedCallSites(GcRoot<CallSite>* resolved_call_sites)
370 ALWAYS_INLINE
371 REQUIRES_SHARED(Locks::mutator_lock_) {
372 SetFieldPtr<false>(ResolvedCallSitesOffset(), resolved_call_sites);
373 }
374
Vladimir Marko98db89c2018-09-07 11:45:46 +0100375 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700376 size_t NumStrings() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100377 return GetField32<kVerifyFlags>(NumStringsOffset());
Vladimir Marko05792b92015-08-03 11:56:49 +0100378 }
379
Vladimir Marko98db89c2018-09-07 11:45:46 +0100380 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700381 size_t NumPreResolvedStrings() REQUIRES_SHARED(Locks::mutator_lock_) {
382 return GetField32<kVerifyFlags>(NumPreResolvedStringsOffset());
383 }
384
385 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700386 size_t NumResolvedTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100387 return GetField32<kVerifyFlags>(NumResolvedTypesOffset());
Vladimir Marko05792b92015-08-03 11:56:49 +0100388 }
389
Vladimir Marko924ad502018-09-19 09:48:04 +0100390 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700391 size_t NumResolvedMethods() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko924ad502018-09-19 09:48:04 +0100392 return GetField32<kVerifyFlags>(NumResolvedMethodsOffset());
Vladimir Marko05792b92015-08-03 11:56:49 +0100393 }
394
Vladimir Marko924ad502018-09-19 09:48:04 +0100395 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700396 size_t NumResolvedFields() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko924ad502018-09-19 09:48:04 +0100397 return GetField32<kVerifyFlags>(NumResolvedFieldsOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700398 }
399
Vladimir Marko98db89c2018-09-07 11:45:46 +0100400 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Narayan Kamath25352fc2016-08-03 12:46:58 +0100401 size_t NumResolvedMethodTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100402 return GetField32<kVerifyFlags>(NumResolvedMethodTypesOffset());
Narayan Kamath25352fc2016-08-03 12:46:58 +0100403 }
404
Vladimir Marko98db89c2018-09-07 11:45:46 +0100405 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Orion Hodsonc069a302017-01-18 09:23:12 +0000406 size_t NumResolvedCallSites() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100407 return GetField32<kVerifyFlags>(NumResolvedCallSitesOffset());
Orion Hodsonc069a302017-01-18 09:23:12 +0000408 }
409
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700410 const DexFile* GetDexFile() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700411 return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
Mathieu Chartier66f19252012-09-18 08:57:04 -0700412 }
413
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700414 void SetDexFile(const DexFile* dex_file) REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier76172162016-01-26 14:54:06 -0800415 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700416 }
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700417
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000418 void SetLocation(ObjPtr<String> location) REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier76172162016-01-26 14:54:06 -0800419
Vladimir Markof44d36c2017-03-14 14:18:46 +0000420 template <typename T>
David Srbecky5de5efe2021-02-15 21:23:00 +0000421 static NativeDexCachePair<T> GetNativePair(std::atomic<NativeDexCachePair<T>>* pair_array,
422 size_t idx);
Vladimir Markof44d36c2017-03-14 14:18:46 +0000423
424 template <typename T>
David Srbecky5de5efe2021-02-15 21:23:00 +0000425 static void SetNativePair(std::atomic<NativeDexCachePair<T>>* pair_array,
426 size_t idx,
427 NativeDexCachePair<T> pair);
Vladimir Markof44d36c2017-03-14 14:18:46 +0000428
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700429 static size_t PreResolvedStringsSize(size_t num_strings) {
430 return sizeof(GcRoot<mirror::String>) * num_strings;
431 }
432
Vladimir Markof25cc732017-03-16 16:18:15 +0000433 uint32_t StringSlotIndex(dex::StringIndex string_idx) REQUIRES_SHARED(Locks::mutator_lock_);
434 uint32_t TypeSlotIndex(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
435 uint32_t FieldSlotIndex(uint32_t field_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100436 uint32_t MethodSlotIndex(uint32_t method_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Orion Hodson06d10a72018-05-14 08:53:38 +0100437 uint32_t MethodTypeSlotIndex(dex::ProtoIndex proto_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Markof25cc732017-03-16 16:18:15 +0000438
Alex Lightc18eba32019-09-24 14:36:27 -0700439 void VisitReflectiveTargets(ReflectiveValueVisitor* visitor) REQUIRES(Locks::mutator_lock_);
440
Andreas Gampe8a1a0f72020-03-03 16:07:45 -0800441 void SetClassLoader(ObjPtr<ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_);
David Srbeckye153a622021-03-02 15:07:26 +0000442
Nicolas Geoffrayc07f4882021-09-13 09:20:33 +0100443 ObjPtr<ClassLoader> GetClassLoader() REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampe8a1a0f72020-03-03 16:07:45 -0800444
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700445 private:
David Srbeckye153a622021-03-02 15:07:26 +0000446 // Allocate new array in linear alloc and save it in the given fields.
447 template<typename T, size_t kMaxCacheSize>
448 T* AllocArray(MemberOffset obj_offset, MemberOffset num_offset, size_t num)
449 REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampecc1b5352016-12-01 16:58:38 -0800450
Vladimir Markof44d36c2017-03-14 14:18:46 +0000451 // std::pair<> is not trivially copyable and as such it is unsuitable for atomic operations,
452 // so we use a custom pair class for loading and storing the NativeDexCachePair<>.
453 template <typename IntType>
454 struct PACKED(2 * sizeof(IntType)) ConversionPair {
455 ConversionPair(IntType f, IntType s) : first(f), second(s) { }
456 ConversionPair(const ConversionPair&) = default;
457 ConversionPair& operator=(const ConversionPair&) = default;
458 IntType first;
459 IntType second;
460 };
461 using ConversionPair32 = ConversionPair<uint32_t>;
462 using ConversionPair64 = ConversionPair<uint64_t>;
463
Vladimir Marko05792b92015-08-03 11:56:49 +0100464 // Visit instance fields of the dex cache as well as its associated arrays.
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800465 template <bool kVisitNativeRoots,
466 VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
467 ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
468 typename Visitor>
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000469 void VisitReferences(ObjPtr<Class> klass, const Visitor& visitor)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700470 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100471
Vladimir Markof44d36c2017-03-14 14:18:46 +0000472 // Due to lack of 16-byte atomics support, we use hand-crafted routines.
Vladimir Marko41b605c2020-02-12 10:52:22 +0000473#if defined(__aarch64__)
474 // 16-byte atomics are supported on aarch64.
Vladimir Markof44d36c2017-03-14 14:18:46 +0000475 ALWAYS_INLINE static ConversionPair64 AtomicLoadRelaxed16B(
476 std::atomic<ConversionPair64>* target) {
477 return target->load(std::memory_order_relaxed);
478 }
479
480 ALWAYS_INLINE static void AtomicStoreRelease16B(
481 std::atomic<ConversionPair64>* target, ConversionPair64 value) {
482 target->store(value, std::memory_order_release);
483 }
484#elif defined(__x86_64__)
485 ALWAYS_INLINE static ConversionPair64 AtomicLoadRelaxed16B(
486 std::atomic<ConversionPair64>* target) {
487 uint64_t first, second;
488 __asm__ __volatile__(
489 "lock cmpxchg16b (%2)"
490 : "=&a"(first), "=&d"(second)
491 : "r"(target), "a"(0), "d"(0), "b"(0), "c"(0)
492 : "cc");
493 return ConversionPair64(first, second);
494 }
495
496 ALWAYS_INLINE static void AtomicStoreRelease16B(
497 std::atomic<ConversionPair64>* target, ConversionPair64 value) {
498 uint64_t first, second;
499 __asm__ __volatile__ (
500 "movq (%2), %%rax\n\t"
501 "movq 8(%2), %%rdx\n\t"
502 "1:\n\t"
503 "lock cmpxchg16b (%2)\n\t"
504 "jnz 1b"
505 : "=&a"(first), "=&d"(second)
506 : "r"(target), "b"(value.first), "c"(value.second)
507 : "cc");
508 }
509#else
510 static ConversionPair64 AtomicLoadRelaxed16B(std::atomic<ConversionPair64>* target);
511 static void AtomicStoreRelease16B(std::atomic<ConversionPair64>* target, ConversionPair64 value);
512#endif
513
Andreas Gampe8a1a0f72020-03-03 16:07:45 -0800514 HeapReference<ClassLoader> class_loader_;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800515 HeapReference<String> location_;
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000516
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700517 uint64_t dex_file_; // const DexFile*
518 uint64_t preresolved_strings_; // GcRoot<mirror::String*> array with num_preresolved_strings
519 // elements.
520 uint64_t resolved_call_sites_; // GcRoot<CallSite>* array with num_resolved_call_sites_
521 // elements.
522 uint64_t resolved_fields_; // std::atomic<FieldDexCachePair>*, array with
523 // num_resolved_fields_ elements.
524 uint64_t resolved_method_types_; // std::atomic<MethodTypeDexCachePair>* array with
525 // num_resolved_method_types_ elements.
526 uint64_t resolved_methods_; // ArtMethod*, array with num_resolved_methods_ elements.
527 uint64_t resolved_types_; // TypeDexCacheType*, array with num_resolved_types_ elements.
528 uint64_t strings_; // std::atomic<StringDexCachePair>*, array with num_strings_
529 // elements.
Narayan Kamath25352fc2016-08-03 12:46:58 +0100530
Andreas Gampe8a1a0f72020-03-03 16:07:45 -0800531 uint32_t num_preresolved_strings_; // Number of elements in the preresolved_strings_ array.
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700532 uint32_t num_resolved_call_sites_; // Number of elements in the call_sites_ array.
Narayan Kamath25352fc2016-08-03 12:46:58 +0100533 uint32_t num_resolved_fields_; // Number of elements in the resolved_fields_ array.
534 uint32_t num_resolved_method_types_; // Number of elements in the resolved_method_types_ array.
535 uint32_t num_resolved_methods_; // Number of elements in the resolved_methods_ array.
536 uint32_t num_resolved_types_; // Number of elements in the resolved_types_ array.
537 uint32_t num_strings_; // Number of elements in the strings_ array.
Brian Carlstrom83db7722011-08-26 17:32:56 -0700538
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700539 friend struct art::DexCacheOffsets; // for verifying offset information
Vladimir Markoca8de0a2018-07-04 11:56:08 +0100540 friend class linker::ImageWriter;
Vladimir Marko05792b92015-08-03 11:56:49 +0100541 friend class Object; // For VisitReferences
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700542 DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700543};
544
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800545} // namespace mirror
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700546} // namespace art
547
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700548#endif // ART_RUNTIME_MIRROR_DEX_CACHE_H_