blob: ea52785f8e0af1cd5e8969d8b8a6084f1256d69c [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"
Vladimir Marko8d6768d2017-03-14 10:13:21 +000021#include "base/bit_utils.h"
Andreas Gampe7fbc4a52018-11-28 08:26:47 -080022#include "base/locks.h"
David Sehr9e734c72018-01-04 17:56:19 -080023#include "dex/dex_file_types.h"
Andreas Gampe88dbad32018-06-26 19:54:12 -070024#include "gc_root.h" // Note: must not use -inl here to avoid circular dependency.
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070025#include "object.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080026#include "object_array.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070027
28namespace art {
29
Vladimir Markoca8de0a2018-07-04 11:56:08 +010030namespace linker {
31class ImageWriter;
32} // namespace linker
33
Vladimir Marko8d6768d2017-03-14 10:13:21 +000034class ArtField;
Alex Lightdba61482016-12-21 08:20:29 -080035class ArtMethod;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080036struct DexCacheOffsets;
37class DexFile;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080038union JValue;
Andreas Gampecc1b5352016-12-01 16:58:38 -080039class LinearAlloc;
Alex Lightc18eba32019-09-24 14:36:27 -070040class ReflectiveValueVisitor;
Andreas Gampecc1b5352016-12-01 16:58:38 -080041class Thread;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080042
43namespace mirror {
44
Orion Hodsonc069a302017-01-18 09:23:12 +000045class CallSite;
Vladimir Marko8d6768d2017-03-14 10:13:21 +000046class Class;
Andreas Gampe8a1a0f72020-03-03 16:07:45 -080047class ClassLoader;
Narayan Kamath25352fc2016-08-03 12:46:58 +010048class MethodType;
Mingyao Yang98d1cc82014-05-15 17:02:16 -070049class String;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070050
Narayan Kamathc38a6f82016-09-29 17:07:20 +010051template <typename T> struct PACKED(8) DexCachePair {
52 GcRoot<T> object;
53 uint32_t index;
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070054 // The array is initially [ {0,0}, {0,0}, {0,0} ... ]
55 // We maintain the invariant that once a dex cache entry is populated,
56 // the pointer is always non-0
57 // Any given entry would thus be:
58 // {non-0, non-0} OR {0,0}
59 //
60 // It's generally sufficiently enough then to check if the
Narayan Kamathc38a6f82016-09-29 17:07:20 +010061 // lookup index matches the stored index (for a >0 lookup index)
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070062 // because if it's true the pointer is also non-null.
63 //
64 // For the 0th entry which is a special case, the value is either
65 // {0,0} (initial state) or {non-0, 0} which indicates
Narayan Kamathc38a6f82016-09-29 17:07:20 +010066 // that a valid object is stored at that index for a dex section id of 0.
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070067 //
Narayan Kamathc38a6f82016-09-29 17:07:20 +010068 // As an optimization, we want to avoid branching on the object pointer since
69 // it's always non-null if the id branch succeeds (except for the 0th id).
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070070 // Set the initial state for the 0th entry to be {0,1} which is guaranteed to fail
Narayan Kamathc38a6f82016-09-29 17:07:20 +010071 // the lookup id == stored id branch.
Andreas Gampe88dbad32018-06-26 19:54:12 -070072 DexCachePair(ObjPtr<T> object, uint32_t index);
Andreas Gamped9911ee2017-03-27 13:27:24 -070073 DexCachePair() : index(0) {}
Narayan Kamathc38a6f82016-09-29 17:07:20 +010074 DexCachePair(const DexCachePair<T>&) = default;
75 DexCachePair& operator=(const DexCachePair<T>&) = default;
Mathieu Chartierbb816d62016-09-07 10:17:46 -070076
Andreas Gampe88dbad32018-06-26 19:54:12 -070077 static void Initialize(std::atomic<DexCachePair<T>>* dex_cache);
Mathieu Chartierbb816d62016-09-07 10:17:46 -070078
Narayan Kamathc38a6f82016-09-29 17:07:20 +010079 static uint32_t InvalidIndexForSlot(uint32_t slot) {
Mathieu Chartierbb816d62016-09-07 10:17:46 -070080 // Since the cache size is a power of two, 0 will always map to slot 0.
81 // Use 1 for slot 0 and 0 for all other slots.
82 return (slot == 0) ? 1u : 0u;
83 }
Vladimir Marko8d6768d2017-03-14 10:13:21 +000084
Andreas Gampe88dbad32018-06-26 19:54:12 -070085 T* GetObjectForIndex(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_);
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -070086};
Narayan Kamathc38a6f82016-09-29 17:07:20 +010087
Vladimir Markof44d36c2017-03-14 14:18:46 +000088template <typename T> struct PACKED(2 * __SIZEOF_POINTER__) NativeDexCachePair {
89 T* object;
90 size_t index;
91 // This is similar to DexCachePair except that we're storing a native pointer
92 // instead of a GC root. See DexCachePair for the details.
93 NativeDexCachePair(T* object, uint32_t index)
94 : object(object),
95 index(index) {}
96 NativeDexCachePair() : object(nullptr), index(0u) { }
97 NativeDexCachePair(const NativeDexCachePair<T>&) = default;
98 NativeDexCachePair& operator=(const NativeDexCachePair<T>&) = default;
99
David Srbecky5de5efe2021-02-15 21:23:00 +0000100 static void Initialize(std::atomic<NativeDexCachePair<T>>* dex_cache);
Vladimir Markof44d36c2017-03-14 14:18:46 +0000101
102 static uint32_t InvalidIndexForSlot(uint32_t slot) {
103 // Since the cache size is a power of two, 0 will always map to slot 0.
104 // Use 1 for slot 0 and 0 for all other slots.
105 return (slot == 0) ? 1u : 0u;
106 }
107
108 T* GetObjectForIndex(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_) {
109 if (idx != index) {
110 return nullptr;
111 }
112 DCHECK(object != nullptr);
113 return object;
114 }
115};
116
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000117using TypeDexCachePair = DexCachePair<Class>;
118using TypeDexCacheType = std::atomic<TypeDexCachePair>;
119
120using StringDexCachePair = DexCachePair<String>;
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700121using StringDexCacheType = std::atomic<StringDexCachePair>;
122
Vladimir Markof44d36c2017-03-14 14:18:46 +0000123using FieldDexCachePair = NativeDexCachePair<ArtField>;
124using FieldDexCacheType = std::atomic<FieldDexCachePair>;
125
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100126using MethodDexCachePair = NativeDexCachePair<ArtMethod>;
127using MethodDexCacheType = std::atomic<MethodDexCachePair>;
128
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000129using MethodTypeDexCachePair = DexCachePair<MethodType>;
Narayan Kamath25352fc2016-08-03 12:46:58 +0100130using MethodTypeDexCacheType = std::atomic<MethodTypeDexCachePair>;
131
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700132// C++ mirror of java.lang.DexCache.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100133class MANAGED DexCache final : public Object {
Brian Carlstrom83db7722011-08-26 17:32:56 -0700134 public:
Alex Light8f187c32021-04-20 14:29:00 -0700135 MIRROR_CLASS("Ljava/lang/DexCache;");
136
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700137 // Size of java.lang.DexCache.class.
Andreas Gampe542451c2016-07-26 09:02:02 -0700138 static uint32_t ClassSize(PointerSize pointer_size);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700139
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000140 // Size of type dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
141 static constexpr size_t kDexCacheTypeCacheSize = 1024;
142 static_assert(IsPowerOfTwo(kDexCacheTypeCacheSize),
143 "Type dex cache size is not a power of 2.");
144
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700145 // Size of string dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
146 static constexpr size_t kDexCacheStringCacheSize = 1024;
147 static_assert(IsPowerOfTwo(kDexCacheStringCacheSize),
148 "String dex cache size is not a power of 2.");
149
Vladimir Markof44d36c2017-03-14 14:18:46 +0000150 // Size of field dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
Vladimir Marko990fc442018-08-29 13:58:23 +0000151 static constexpr size_t kDexCacheFieldCacheSize = 1024;
Vladimir Markof44d36c2017-03-14 14:18:46 +0000152 static_assert(IsPowerOfTwo(kDexCacheFieldCacheSize),
153 "Field dex cache size is not a power of 2.");
154
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100155 // Size of method dex cache. Needs to be a power of 2 for entrypoint assumptions to hold.
Vladimir Marko990fc442018-08-29 13:58:23 +0000156 static constexpr size_t kDexCacheMethodCacheSize = 1024;
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100157 static_assert(IsPowerOfTwo(kDexCacheMethodCacheSize),
158 "Method dex cache size is not a power of 2.");
159
Narayan Kamath25352fc2016-08-03 12:46:58 +0100160 // Size of method type dex cache. Needs to be a power of 2 for entrypoint assumptions
161 // to hold.
162 static constexpr size_t kDexCacheMethodTypeCacheSize = 1024;
163 static_assert(IsPowerOfTwo(kDexCacheMethodTypeCacheSize),
164 "MethodType dex cache size is not a power of 2.");
165
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000166 static constexpr size_t StaticTypeSize() {
167 return kDexCacheTypeCacheSize;
168 }
169
Christina Wadsworthbf44e0e2016-08-18 10:37:42 -0700170 static constexpr size_t StaticStringSize() {
171 return kDexCacheStringCacheSize;
172 }
173
Vladimir Markof44d36c2017-03-14 14:18:46 +0000174 static constexpr size_t StaticArtFieldSize() {
175 return kDexCacheFieldCacheSize;
176 }
177
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100178 static constexpr size_t StaticMethodSize() {
179 return kDexCacheMethodCacheSize;
180 }
181
Narayan Kamath25352fc2016-08-03 12:46:58 +0100182 static constexpr size_t StaticMethodTypeSize() {
183 return kDexCacheMethodTypeCacheSize;
184 }
185
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700186 // Size of an instance of java.lang.DexCache not including referenced values.
187 static constexpr uint32_t InstanceSize() {
188 return sizeof(DexCache);
189 }
190
Orion Hodsonb9b7d912021-02-24 09:24:47 +0000191 // Initialize native fields and allocate memory.
192 void InitializeNativeFields(const DexFile* dex_file, LinearAlloc* linear_alloc)
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
Orion Hodsonb9b7d912021-02-24 09:24:47 +0000196 // Clear all native fields.
197 void ResetNativeFields() REQUIRES_SHARED(Locks::mutator_lock_);
198
199 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
200 void FixupStrings(StringDexCacheType* dest, const Visitor& visitor)
201 REQUIRES_SHARED(Locks::mutator_lock_);
202
203 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
204 void FixupResolvedTypes(TypeDexCacheType* dest, const Visitor& visitor)
205 REQUIRES_SHARED(Locks::mutator_lock_);
206
207 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
208 void FixupResolvedMethodTypes(MethodTypeDexCacheType* dest, const Visitor& visitor)
209 REQUIRES_SHARED(Locks::mutator_lock_);
210
211 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
212 void FixupResolvedCallSites(GcRoot<mirror::CallSite>* dest, const Visitor& visitor)
213 REQUIRES_SHARED(Locks::mutator_lock_);
Orion Hodsonc069a302017-01-18 09:23:12 +0000214
Vladimir Marko58412b12019-04-01 13:26:34 +0100215 ObjPtr<String> GetLocation() REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700216
David Srbecky56de89a2018-10-01 15:32:20 +0100217 static constexpr MemberOffset StringsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700218 return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_);
buzbeec5ef0462011-08-25 18:44:49 -0700219 }
220
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700221 static constexpr MemberOffset PreResolvedStringsOffset() {
222 return OFFSET_OF_OBJECT_MEMBER(DexCache, preresolved_strings_);
223 }
224
David Srbecky56de89a2018-10-01 15:32:20 +0100225 static constexpr MemberOffset ResolvedTypesOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100226 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_);
227 }
228
David Srbecky56de89a2018-10-01 15:32:20 +0100229 static constexpr MemberOffset ResolvedFieldsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700230 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_);
buzbeec5ef0462011-08-25 18:44:49 -0700231 }
232
David Srbecky56de89a2018-10-01 15:32:20 +0100233 static constexpr MemberOffset ResolvedMethodsOffset() {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700234 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
buzbeec5ef0462011-08-25 18:44:49 -0700235 }
236
David Srbecky56de89a2018-10-01 15:32:20 +0100237 static constexpr MemberOffset ResolvedMethodTypesOffset() {
Narayan Kamath25352fc2016-08-03 12:46:58 +0100238 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_method_types_);
239 }
240
David Srbecky56de89a2018-10-01 15:32:20 +0100241 static constexpr MemberOffset ResolvedCallSitesOffset() {
Orion Hodsonc069a302017-01-18 09:23:12 +0000242 return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_call_sites_);
243 }
244
David Srbecky56de89a2018-10-01 15:32:20 +0100245 static constexpr MemberOffset NumStringsOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100246 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_strings_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700247 }
248
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700249 static constexpr MemberOffset NumPreResolvedStringsOffset() {
250 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_preresolved_strings_);
251 }
252
David Srbecky56de89a2018-10-01 15:32:20 +0100253 static constexpr MemberOffset NumResolvedTypesOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100254 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_types_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700255 }
256
David Srbecky56de89a2018-10-01 15:32:20 +0100257 static constexpr MemberOffset NumResolvedFieldsOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100258 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_fields_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700259 }
260
David Srbecky56de89a2018-10-01 15:32:20 +0100261 static constexpr MemberOffset NumResolvedMethodsOffset() {
Vladimir Marko05792b92015-08-03 11:56:49 +0100262 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_methods_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700263 }
264
David Srbecky56de89a2018-10-01 15:32:20 +0100265 static constexpr MemberOffset NumResolvedMethodTypesOffset() {
Narayan Kamath25352fc2016-08-03 12:46:58 +0100266 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_method_types_);
267 }
268
David Srbecky56de89a2018-10-01 15:32:20 +0100269 static constexpr MemberOffset NumResolvedCallSitesOffset() {
Orion Hodsonc069a302017-01-18 09:23:12 +0000270 return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_call_sites_);
271 }
272
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700273 static constexpr size_t PreResolvedStringsAlignment() {
274 return alignof(GcRoot<mirror::String>);
275 }
276
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000277 String* GetResolvedString(dex::StringIndex string_idx) ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700278 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700279
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800280 void SetResolvedString(dex::StringIndex string_idx, ObjPtr<mirror::String> resolved) ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700281 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700282
Orion Hodsonb9b7d912021-02-24 09:24:47 +0000283 void SetPreResolvedString(dex::StringIndex string_idx,
284 ObjPtr<mirror::String> resolved)
285 ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_);
286
287 // Clear the preresolved string cache to prevent further usage.
288 void ClearPreResolvedStrings()
289 ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_);
290
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700291 // Clear a string for a string_idx, used to undo string intern transactions to make sure
292 // the string isn't kept live.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800293 void ClearString(dex::StringIndex string_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700294
Andreas Gampea5b09a62016-11-17 15:21:22 -0800295 Class* GetResolvedType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100296
Andreas Gampea5b09a62016-11-17 15:21:22 -0800297 void SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved)
Mathieu Chartier31e88222016-10-14 18:43:19 -0700298 REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100299
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000300 void ClearResolvedType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
301
David Srbecky5de5efe2021-02-15 21:23:00 +0000302 ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700303 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700304
David Srbecky5de5efe2021-02-15 21:23:00 +0000305 ALWAYS_INLINE void SetResolvedMethod(uint32_t method_idx, ArtMethod* resolved)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700306 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700307
David Srbecky5de5efe2021-02-15 21:23:00 +0000308 ALWAYS_INLINE ArtField* GetResolvedField(uint32_t idx)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700309 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700310
David Srbecky5de5efe2021-02-15 21:23:00 +0000311 ALWAYS_INLINE void SetResolvedField(uint32_t idx, ArtField* field)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700312 REQUIRES_SHARED(Locks::mutator_lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700313
Orion Hodson06d10a72018-05-14 08:53:38 +0100314 MethodType* GetResolvedMethodType(dex::ProtoIndex proto_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Narayan Kamath25352fc2016-08-03 12:46:58 +0100315
Orion Hodson06d10a72018-05-14 08:53:38 +0100316 void SetResolvedMethodType(dex::ProtoIndex proto_idx, MethodType* resolved)
Orion Hodsonc069a302017-01-18 09:23:12 +0000317 REQUIRES_SHARED(Locks::mutator_lock_);
318
319 CallSite* GetResolvedCallSite(uint32_t call_site_idx) REQUIRES_SHARED(Locks::mutator_lock_);
320
321 // Attempts to bind |call_site_idx| to the call site |resolved|. The
322 // caller must use the return value in place of |resolved|. This is
323 // because multiple threads can invoke the bootstrap method each
324 // producing a call site, but the method handle invocation on the
325 // call site must be on a common agreed value.
Orion Hodson4c8e12e2018-05-18 08:33:20 +0100326 ObjPtr<CallSite> SetResolvedCallSite(uint32_t call_site_idx, ObjPtr<CallSite> resolved)
327 REQUIRES_SHARED(Locks::mutator_lock_) WARN_UNUSED;
Narayan Kamath25352fc2016-08-03 12:46:58 +0100328
Vladimir Marko98db89c2018-09-07 11:45:46 +0100329 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700330 StringDexCacheType* GetStrings() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100331 return GetFieldPtr64<StringDexCacheType*, kVerifyFlags>(StringsOffset());
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700332 }
Brian Carlstrom83db7722011-08-26 17:32:56 -0700333
Orion Hodsonb9b7d912021-02-24 09:24:47 +0000334 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
335 GcRoot<mirror::String>* GetPreResolvedStrings() ALWAYS_INLINE
336 REQUIRES_SHARED(Locks::mutator_lock_) {
337 return GetFieldPtr64<GcRoot<mirror::String>*, kVerifyFlags>(PreResolvedStringsOffset());
338 }
339
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700340 void SetStrings(StringDexCacheType* strings) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800341 SetFieldPtr<false>(StringsOffset(), strings);
342 }
343
Orion Hodsonb9b7d912021-02-24 09:24:47 +0000344 void SetPreResolvedStrings(GcRoot<mirror::String>* strings)
345 ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
346 SetFieldPtr<false>(PreResolvedStringsOffset(), strings);
347 }
348
Vladimir Marko98db89c2018-09-07 11:45:46 +0100349 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000350 TypeDexCacheType* GetResolvedTypes() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100351 return GetFieldPtr<TypeDexCacheType*, kVerifyFlags>(ResolvedTypesOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700352 }
353
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000354 void SetResolvedTypes(TypeDexCacheType* resolved_types)
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800355 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700356 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800357 SetFieldPtr<false>(ResolvedTypesOffset(), resolved_types);
358 }
359
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100360 MethodDexCacheType* GetResolvedMethods() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
361 return GetFieldPtr<MethodDexCacheType*>(ResolvedMethodsOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700362 }
363
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100364 void SetResolvedMethods(MethodDexCacheType* resolved_methods)
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800365 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700366 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800367 SetFieldPtr<false>(ResolvedMethodsOffset(), resolved_methods);
368 }
369
Vladimir Markof44d36c2017-03-14 14:18:46 +0000370 FieldDexCacheType* GetResolvedFields() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
371 return GetFieldPtr<FieldDexCacheType*>(ResolvedFieldsOffset());
Vladimir Marko05792b92015-08-03 11:56:49 +0100372 }
373
Vladimir Markof44d36c2017-03-14 14:18:46 +0000374 void SetResolvedFields(FieldDexCacheType* resolved_fields)
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800375 ALWAYS_INLINE
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700376 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800377 SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields);
378 }
379
Vladimir Marko98db89c2018-09-07 11:45:46 +0100380 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Narayan Kamath25352fc2016-08-03 12:46:58 +0100381 MethodTypeDexCacheType* GetResolvedMethodTypes()
382 ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100383 return GetFieldPtr64<MethodTypeDexCacheType*, kVerifyFlags>(ResolvedMethodTypesOffset());
Narayan Kamath25352fc2016-08-03 12:46:58 +0100384 }
385
386 void SetResolvedMethodTypes(MethodTypeDexCacheType* resolved_method_types)
387 ALWAYS_INLINE
388 REQUIRES_SHARED(Locks::mutator_lock_) {
389 SetFieldPtr<false>(ResolvedMethodTypesOffset(), resolved_method_types);
390 }
391
Vladimir Marko98db89c2018-09-07 11:45:46 +0100392 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Orion Hodsonc069a302017-01-18 09:23:12 +0000393 GcRoot<CallSite>* GetResolvedCallSites()
394 ALWAYS_INLINE
395 REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100396 return GetFieldPtr<GcRoot<CallSite>*, kVerifyFlags>(ResolvedCallSitesOffset());
Orion Hodsonc069a302017-01-18 09:23:12 +0000397 }
398
399 void SetResolvedCallSites(GcRoot<CallSite>* resolved_call_sites)
400 ALWAYS_INLINE
401 REQUIRES_SHARED(Locks::mutator_lock_) {
402 SetFieldPtr<false>(ResolvedCallSitesOffset(), resolved_call_sites);
403 }
404
Vladimir Marko98db89c2018-09-07 11:45:46 +0100405 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700406 size_t NumStrings() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100407 return GetField32<kVerifyFlags>(NumStringsOffset());
Vladimir Marko05792b92015-08-03 11:56:49 +0100408 }
409
Vladimir Marko98db89c2018-09-07 11:45:46 +0100410 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700411 size_t NumPreResolvedStrings() REQUIRES_SHARED(Locks::mutator_lock_) {
412 return GetField32<kVerifyFlags>(NumPreResolvedStringsOffset());
413 }
414
415 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700416 size_t NumResolvedTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100417 return GetField32<kVerifyFlags>(NumResolvedTypesOffset());
Vladimir Marko05792b92015-08-03 11:56:49 +0100418 }
419
Vladimir Marko924ad502018-09-19 09:48:04 +0100420 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700421 size_t NumResolvedMethods() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko924ad502018-09-19 09:48:04 +0100422 return GetField32<kVerifyFlags>(NumResolvedMethodsOffset());
Vladimir Marko05792b92015-08-03 11:56:49 +0100423 }
424
Vladimir Marko924ad502018-09-19 09:48:04 +0100425 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700426 size_t NumResolvedFields() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko924ad502018-09-19 09:48:04 +0100427 return GetField32<kVerifyFlags>(NumResolvedFieldsOffset());
Mathieu Chartier66f19252012-09-18 08:57:04 -0700428 }
429
Vladimir Marko98db89c2018-09-07 11:45:46 +0100430 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Narayan Kamath25352fc2016-08-03 12:46:58 +0100431 size_t NumResolvedMethodTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100432 return GetField32<kVerifyFlags>(NumResolvedMethodTypesOffset());
Narayan Kamath25352fc2016-08-03 12:46:58 +0100433 }
434
Vladimir Marko98db89c2018-09-07 11:45:46 +0100435 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Orion Hodsonc069a302017-01-18 09:23:12 +0000436 size_t NumResolvedCallSites() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko98db89c2018-09-07 11:45:46 +0100437 return GetField32<kVerifyFlags>(NumResolvedCallSitesOffset());
Orion Hodsonc069a302017-01-18 09:23:12 +0000438 }
439
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700440 const DexFile* GetDexFile() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700441 return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
Mathieu Chartier66f19252012-09-18 08:57:04 -0700442 }
443
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700444 void SetDexFile(const DexFile* dex_file) REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier76172162016-01-26 14:54:06 -0800445 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700446 }
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700447
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000448 void SetLocation(ObjPtr<String> location) REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier76172162016-01-26 14:54:06 -0800449
Vladimir Markof44d36c2017-03-14 14:18:46 +0000450 template <typename T>
David Srbecky5de5efe2021-02-15 21:23:00 +0000451 static NativeDexCachePair<T> GetNativePair(std::atomic<NativeDexCachePair<T>>* pair_array,
452 size_t idx);
Vladimir Markof44d36c2017-03-14 14:18:46 +0000453
454 template <typename T>
David Srbecky5de5efe2021-02-15 21:23:00 +0000455 static void SetNativePair(std::atomic<NativeDexCachePair<T>>* pair_array,
456 size_t idx,
457 NativeDexCachePair<T> pair);
Vladimir Markof44d36c2017-03-14 14:18:46 +0000458
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700459 static size_t PreResolvedStringsSize(size_t num_strings) {
460 return sizeof(GcRoot<mirror::String>) * num_strings;
461 }
462
Vladimir Markof25cc732017-03-16 16:18:15 +0000463 uint32_t StringSlotIndex(dex::StringIndex string_idx) REQUIRES_SHARED(Locks::mutator_lock_);
464 uint32_t TypeSlotIndex(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
465 uint32_t FieldSlotIndex(uint32_t field_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100466 uint32_t MethodSlotIndex(uint32_t method_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Orion Hodson06d10a72018-05-14 08:53:38 +0100467 uint32_t MethodTypeSlotIndex(dex::ProtoIndex proto_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Vladimir Markof25cc732017-03-16 16:18:15 +0000468
Orion Hodsonb9b7d912021-02-24 09:24:47 +0000469 // Returns true if we succeeded in adding the pre-resolved string array.
470 bool AddPreResolvedStringsArray() REQUIRES_SHARED(Locks::mutator_lock_);
471
Alex Lightc18eba32019-09-24 14:36:27 -0700472 void VisitReflectiveTargets(ReflectiveValueVisitor* visitor) REQUIRES(Locks::mutator_lock_);
473
Andreas Gampe8a1a0f72020-03-03 16:07:45 -0800474 void SetClassLoader(ObjPtr<ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_);
475
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700476 private:
Orion Hodsonb9b7d912021-02-24 09:24:47 +0000477 void SetNativeArrays(StringDexCacheType* strings,
478 uint32_t num_strings,
479 TypeDexCacheType* resolved_types,
480 uint32_t num_resolved_types,
481 MethodDexCacheType* resolved_methods,
482 uint32_t num_resolved_methods,
483 FieldDexCacheType* resolved_fields,
484 uint32_t num_resolved_fields,
485 MethodTypeDexCacheType* resolved_method_types,
486 uint32_t num_resolved_method_types,
487 GcRoot<CallSite>* resolved_call_sites,
488 uint32_t num_resolved_call_sites)
489 REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampecc1b5352016-12-01 16:58:38 -0800490
Vladimir Markof44d36c2017-03-14 14:18:46 +0000491 // std::pair<> is not trivially copyable and as such it is unsuitable for atomic operations,
492 // so we use a custom pair class for loading and storing the NativeDexCachePair<>.
493 template <typename IntType>
494 struct PACKED(2 * sizeof(IntType)) ConversionPair {
495 ConversionPair(IntType f, IntType s) : first(f), second(s) { }
496 ConversionPair(const ConversionPair&) = default;
497 ConversionPair& operator=(const ConversionPair&) = default;
498 IntType first;
499 IntType second;
500 };
501 using ConversionPair32 = ConversionPair<uint32_t>;
502 using ConversionPair64 = ConversionPair<uint64_t>;
503
Vladimir Marko05792b92015-08-03 11:56:49 +0100504 // Visit instance fields of the dex cache as well as its associated arrays.
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800505 template <bool kVisitNativeRoots,
506 VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
507 ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
508 typename Visitor>
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000509 void VisitReferences(ObjPtr<Class> klass, const Visitor& visitor)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700510 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_);
Vladimir Marko05792b92015-08-03 11:56:49 +0100511
Vladimir Markof44d36c2017-03-14 14:18:46 +0000512 // Due to lack of 16-byte atomics support, we use hand-crafted routines.
Vladimir Marko41b605c2020-02-12 10:52:22 +0000513#if defined(__aarch64__)
514 // 16-byte atomics are supported on aarch64.
Vladimir Markof44d36c2017-03-14 14:18:46 +0000515 ALWAYS_INLINE static ConversionPair64 AtomicLoadRelaxed16B(
516 std::atomic<ConversionPair64>* target) {
517 return target->load(std::memory_order_relaxed);
518 }
519
520 ALWAYS_INLINE static void AtomicStoreRelease16B(
521 std::atomic<ConversionPair64>* target, ConversionPair64 value) {
522 target->store(value, std::memory_order_release);
523 }
524#elif defined(__x86_64__)
525 ALWAYS_INLINE static ConversionPair64 AtomicLoadRelaxed16B(
526 std::atomic<ConversionPair64>* target) {
527 uint64_t first, second;
528 __asm__ __volatile__(
529 "lock cmpxchg16b (%2)"
530 : "=&a"(first), "=&d"(second)
531 : "r"(target), "a"(0), "d"(0), "b"(0), "c"(0)
532 : "cc");
533 return ConversionPair64(first, second);
534 }
535
536 ALWAYS_INLINE static void AtomicStoreRelease16B(
537 std::atomic<ConversionPair64>* target, ConversionPair64 value) {
538 uint64_t first, second;
539 __asm__ __volatile__ (
540 "movq (%2), %%rax\n\t"
541 "movq 8(%2), %%rdx\n\t"
542 "1:\n\t"
543 "lock cmpxchg16b (%2)\n\t"
544 "jnz 1b"
545 : "=&a"(first), "=&d"(second)
546 : "r"(target), "b"(value.first), "c"(value.second)
547 : "cc");
548 }
549#else
550 static ConversionPair64 AtomicLoadRelaxed16B(std::atomic<ConversionPair64>* target);
551 static void AtomicStoreRelease16B(std::atomic<ConversionPair64>* target, ConversionPair64 value);
552#endif
553
Andreas Gampe8a1a0f72020-03-03 16:07:45 -0800554 HeapReference<ClassLoader> class_loader_;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800555 HeapReference<String> location_;
Narayan Kamath6b2dc312017-03-14 13:26:12 +0000556
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700557 uint64_t dex_file_; // const DexFile*
558 uint64_t preresolved_strings_; // GcRoot<mirror::String*> array with num_preresolved_strings
559 // elements.
560 uint64_t resolved_call_sites_; // GcRoot<CallSite>* array with num_resolved_call_sites_
561 // elements.
562 uint64_t resolved_fields_; // std::atomic<FieldDexCachePair>*, array with
563 // num_resolved_fields_ elements.
564 uint64_t resolved_method_types_; // std::atomic<MethodTypeDexCachePair>* array with
565 // num_resolved_method_types_ elements.
566 uint64_t resolved_methods_; // ArtMethod*, array with num_resolved_methods_ elements.
567 uint64_t resolved_types_; // TypeDexCacheType*, array with num_resolved_types_ elements.
568 uint64_t strings_; // std::atomic<StringDexCachePair>*, array with num_strings_
569 // elements.
Narayan Kamath25352fc2016-08-03 12:46:58 +0100570
Andreas Gampe8a1a0f72020-03-03 16:07:45 -0800571 uint32_t num_preresolved_strings_; // Number of elements in the preresolved_strings_ array.
Mathieu Chartier1ca718e2018-10-23 12:55:34 -0700572 uint32_t num_resolved_call_sites_; // Number of elements in the call_sites_ array.
Narayan Kamath25352fc2016-08-03 12:46:58 +0100573 uint32_t num_resolved_fields_; // Number of elements in the resolved_fields_ array.
574 uint32_t num_resolved_method_types_; // Number of elements in the resolved_method_types_ array.
575 uint32_t num_resolved_methods_; // Number of elements in the resolved_methods_ array.
576 uint32_t num_resolved_types_; // Number of elements in the resolved_types_ array.
577 uint32_t num_strings_; // Number of elements in the strings_ array.
Brian Carlstrom83db7722011-08-26 17:32:56 -0700578
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700579 friend struct art::DexCacheOffsets; // for verifying offset information
Vladimir Markoca8de0a2018-07-04 11:56:08 +0100580 friend class linker::ImageWriter;
Vladimir Marko05792b92015-08-03 11:56:49 +0100581 friend class Object; // For VisitReferences
Brian Carlstromc4fa2c02011-08-21 03:00:12 -0700582 DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700583};
584
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800585} // namespace mirror
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700586} // namespace art
587
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700588#endif // ART_RUNTIME_MIRROR_DEX_CACHE_H_