blob: 978b1abbaf505945440367d8e7b6414f5841c0f5 [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -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 */
16
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_CLASS_LINKER_INL_H_
18#define ART_RUNTIME_CLASS_LINKER_INL_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
Vladimir Marko09c5ca42018-05-31 15:15:31 +010020#include <atomic>
21
22#include "art_field-inl.h"
23#include "art_method-inl.h"
Andreas Gampe7fbc4a52018-11-28 08:26:47 -080024#include "base/mutex.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080025#include "class_linker.h"
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080026#include "dex/dex_file.h"
27#include "dex/dex_file_structs.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070028#include "gc_root-inl.h"
29#include "handle_scope-inl.h"
Mathieu Chartier590fee92013-09-13 13:46:47 -070030#include "mirror/class_loader.h"
Mathieu Chartierbc56fc32014-06-03 15:37:03 -070031#include "mirror/dex_cache-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080032#include "mirror/iftable.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070033#include "mirror/object_array-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070034#include "obj_ptr-inl.h"
Mathieu Chartierc4f39252016-10-05 18:32:08 -070035#include "scoped_thread_state_change-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080036
37namespace art {
38
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010039inline ObjPtr<mirror::Class> ClassLinker::FindArrayClass(Thread* self,
Vladimir Markobcf17522018-06-01 13:14:32 +010040 ObjPtr<mirror::Class> element_class) {
Ian Rogers98379392014-02-24 16:53:16 -080041 for (size_t i = 0; i < kFindArrayCacheSize; ++i) {
Ian Rogersa55cf412014-02-27 00:31:26 -080042 // Read the cached array class once to avoid races with other threads setting it.
Mathieu Chartier28357fa2016-10-18 16:27:40 -070043 ObjPtr<mirror::Class> array_class = find_array_class_cache_[i].Read();
Vladimir Markobcf17522018-06-01 13:14:32 +010044 if (array_class != nullptr && array_class->GetComponentType() == element_class) {
45 return array_class;
Ian Rogers98379392014-02-24 16:53:16 -080046 }
47 }
Ian Rogers1ff3c982014-08-12 02:30:58 -070048 std::string descriptor = "[";
49 std::string temp;
Vladimir Markobcf17522018-06-01 13:14:32 +010050 descriptor += element_class->GetDescriptor(&temp);
51 StackHandleScope<1> hs(Thread::Current());
52 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(element_class->GetClassLoader()));
Mathieu Chartier28357fa2016-10-18 16:27:40 -070053 ObjPtr<mirror::Class> array_class = FindClass(self, descriptor.c_str(), class_loader);
Nicolas Geoffray9638b642015-06-23 18:16:46 +010054 if (array_class != nullptr) {
55 // Benign races in storing array class and incrementing index.
56 size_t victim_index = find_array_class_cache_next_victim_;
57 find_array_class_cache_[victim_index] = GcRoot<mirror::Class>(array_class);
58 find_array_class_cache_next_victim_ = (victim_index + 1) % kFindArrayCacheSize;
59 } else {
60 // We should have a NoClassDefFoundError.
61 self->AssertPendingException();
62 }
Vladimir Markobcf17522018-06-01 13:14:32 +010063 return array_class;
Ian Rogers98379392014-02-24 16:53:16 -080064}
65
Vladimir Marko18090d12018-06-01 16:53:12 +010066inline ObjPtr<mirror::String> ClassLinker::ResolveString(dex::StringIndex string_idx,
67 ArtField* referrer) {
68 Thread::PoisonObjectPointersIfDebug();
69 DCHECK(!Thread::Current()->IsExceptionPending());
70 // We do not need the read barrier for getting the DexCache for the initial resolved type
71 // lookup as both from-space and to-space copies point to the same native resolved types array.
72 ObjPtr<mirror::String> resolved =
73 referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedString(string_idx);
74 if (resolved == nullptr) {
75 resolved = DoResolveString(string_idx, referrer->GetDexCache());
76 }
77 return resolved;
78}
79
80inline ObjPtr<mirror::String> ClassLinker::ResolveString(dex::StringIndex string_idx,
81 ArtMethod* referrer) {
82 Thread::PoisonObjectPointersIfDebug();
83 DCHECK(!Thread::Current()->IsExceptionPending());
84 // We do not need the read barrier for getting the DexCache for the initial resolved type
85 // lookup as both from-space and to-space copies point to the same native resolved types array.
86 ObjPtr<mirror::String> resolved =
87 referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedString(string_idx);
88 if (resolved == nullptr) {
89 resolved = DoResolveString(string_idx, referrer->GetDexCache());
90 }
91 return resolved;
92}
93
94inline ObjPtr<mirror::String> ClassLinker::ResolveString(dex::StringIndex string_idx,
95 Handle<mirror::DexCache> dex_cache) {
96 Thread::PoisonObjectPointersIfDebug();
97 DCHECK(!Thread::Current()->IsExceptionPending());
98 ObjPtr<mirror::String> resolved = dex_cache->GetResolvedString(string_idx);
99 if (resolved == nullptr) {
100 resolved = DoResolveString(string_idx, dex_cache);
101 }
102 return resolved;
103}
104
105inline ObjPtr<mirror::String> ClassLinker::LookupString(dex::StringIndex string_idx,
106 ObjPtr<mirror::DexCache> dex_cache) {
107 ObjPtr<mirror::String> resolved = dex_cache->GetResolvedString(string_idx);
108 if (resolved == nullptr) {
109 resolved = DoLookupString(string_idx, dex_cache);
110 }
111 return resolved;
112}
113
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000114inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx,
115 ObjPtr<mirror::Class> referrer) {
116 if (kObjPtrPoisoning) {
117 StackHandleScope<1> hs(Thread::Current());
118 HandleWrapperObjPtr<mirror::Class> referrer_wrapper = hs.NewHandleWrapper(&referrer);
119 Thread::Current()->PoisonObjectPointers();
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000120 }
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100121 DCHECK(!Thread::Current()->IsExceptionPending());
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000122 // We do not need the read barrier for getting the DexCache for the initial resolved type
123 // lookup as both from-space and to-space copies point to the same native resolved types array.
124 ObjPtr<mirror::Class> resolved_type =
125 referrer->GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>()->GetResolvedType(type_idx);
126 if (resolved_type == nullptr) {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100127 resolved_type = DoResolveType(type_idx, referrer);
128 }
129 return resolved_type;
130}
131
132inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx,
133 ArtField* referrer) {
134 Thread::PoisonObjectPointersIfDebug();
135 DCHECK(!Thread::Current()->IsExceptionPending());
136 // We do not need the read barrier for getting the DexCache for the initial resolved type
137 // lookup as both from-space and to-space copies point to the same native resolved types array.
138 ObjPtr<mirror::Class> resolved_type =
139 referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedType(type_idx);
140 if (UNLIKELY(resolved_type == nullptr)) {
Andreas Gampe4835d212018-11-21 14:55:10 -0800141 resolved_type = DoResolveType(type_idx, referrer);
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000142 }
143 return resolved_type;
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000144}
145
Vladimir Marko28e012a2017-12-07 11:22:59 +0000146inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx,
147 ArtMethod* referrer) {
Mathieu Chartiera59d9b22016-09-26 18:13:17 -0700148 Thread::PoisonObjectPointersIfDebug();
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100149 DCHECK(!Thread::Current()->IsExceptionPending());
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000150 // We do not need the read barrier for getting the DexCache for the initial resolved type
151 // lookup as both from-space and to-space copies point to the same native resolved types array.
152 ObjPtr<mirror::Class> resolved_type =
153 referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedType(type_idx);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700154 if (UNLIKELY(resolved_type == nullptr)) {
Andreas Gampe4835d212018-11-21 14:55:10 -0800155 resolved_type = DoResolveType(type_idx, referrer);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800156 }
Vladimir Marko28e012a2017-12-07 11:22:59 +0000157 return resolved_type;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800158}
159
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000160inline ObjPtr<mirror::Class> ClassLinker::ResolveType(dex::TypeIndex type_idx,
161 Handle<mirror::DexCache> dex_cache,
162 Handle<mirror::ClassLoader> class_loader) {
163 DCHECK(dex_cache != nullptr);
164 Thread::PoisonObjectPointersIfDebug();
165 ObjPtr<mirror::Class> resolved = dex_cache->GetResolvedType(type_idx);
166 if (resolved == nullptr) {
167 resolved = DoResolveType(type_idx, dex_cache, class_loader);
168 }
169 return resolved;
170}
171
172inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
173 ObjPtr<mirror::Class> referrer) {
174 // We do not need the read barrier for getting the DexCache for the initial resolved type
175 // lookup as both from-space and to-space copies point to the same native resolved types array.
176 ObjPtr<mirror::Class> type =
177 referrer->GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>()->GetResolvedType(type_idx);
178 if (type == nullptr) {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100179 type = DoLookupResolvedType(type_idx, referrer);
180 }
181 return type;
182}
183
184inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
185 ArtField* referrer) {
186 // We do not need the read barrier for getting the DexCache for the initial resolved type
187 // lookup as both from-space and to-space copies point to the same native resolved types array.
188 ObjPtr<mirror::Class> type =
189 referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedType(type_idx);
190 if (type == nullptr) {
191 type = DoLookupResolvedType(type_idx, referrer->GetDeclaringClass());
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000192 }
193 return type;
194}
195
196inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(dex::TypeIndex type_idx,
197 ArtMethod* referrer) {
198 // We do not need the read barrier for getting the DexCache for the initial resolved type
199 // lookup as both from-space and to-space copies point to the same native resolved types array.
200 ObjPtr<mirror::Class> type =
201 referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedType(type_idx);
202 if (type == nullptr) {
Vladimir Marko09c5ca42018-05-31 15:15:31 +0100203 type = DoLookupResolvedType(type_idx, referrer->GetDeclaringClass());
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000204 }
205 return type;
206}
207
208inline ObjPtr<mirror::Class> ClassLinker::LookupResolvedType(
209 dex::TypeIndex type_idx,
210 ObjPtr<mirror::DexCache> dex_cache,
211 ObjPtr<mirror::ClassLoader> class_loader) {
212 ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx);
213 if (type == nullptr) {
214 type = DoLookupResolvedType(type_idx, dex_cache, class_loader);
215 }
216 return type;
217}
218
Vladimir Markoba118822017-06-12 15:41:56 +0100219template <bool kThrowOnError, typename ClassGetter>
220inline bool ClassLinker::CheckInvokeClassMismatch(ObjPtr<mirror::DexCache> dex_cache,
221 InvokeType type,
222 ClassGetter class_getter) {
223 switch (type) {
224 case kStatic:
225 case kSuper:
226 break;
227 case kInterface: {
228 // We have to check whether the method id really belongs to an interface (dex static bytecode
229 // constraints A15, A16). Otherwise you must not invoke-interface on it.
230 ObjPtr<mirror::Class> klass = class_getter();
231 if (UNLIKELY(!klass->IsInterface())) {
232 if (kThrowOnError) {
233 ThrowIncompatibleClassChangeError(klass,
234 "Found class %s, but interface was expected",
235 klass->PrettyDescriptor().c_str());
236 }
237 return true;
238 }
239 break;
240 }
241 case kDirect:
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800242 if (dex_cache->GetDexFile()->SupportsDefaultMethods()) {
Vladimir Markoba118822017-06-12 15:41:56 +0100243 break;
244 }
245 FALLTHROUGH_INTENDED;
246 case kVirtual: {
247 // Similarly, invoke-virtual (and invoke-direct without default methods) must reference
248 // a non-interface class (dex static bytecode constraint A24, A25).
249 ObjPtr<mirror::Class> klass = class_getter();
250 if (UNLIKELY(klass->IsInterface())) {
251 if (kThrowOnError) {
252 ThrowIncompatibleClassChangeError(klass,
253 "Found interface %s, but class was expected",
254 klass->PrettyDescriptor().c_str());
255 }
256 return true;
257 }
258 break;
259 }
260 default:
261 LOG(FATAL) << "Unreachable - invocation type: " << type;
262 UNREACHABLE();
263 }
264 return false;
265}
266
267template <bool kThrow>
268inline bool ClassLinker::CheckInvokeClassMismatch(ObjPtr<mirror::DexCache> dex_cache,
269 InvokeType type,
270 uint32_t method_idx,
271 ObjPtr<mirror::ClassLoader> class_loader) {
272 return CheckInvokeClassMismatch<kThrow>(
273 dex_cache,
274 type,
275 [this, dex_cache, method_idx, class_loader]() REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800276 const dex::MethodId& method_id = dex_cache->GetDexFile()->GetMethodId(method_idx);
Vladimir Markoba118822017-06-12 15:41:56 +0100277 ObjPtr<mirror::Class> klass =
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000278 LookupResolvedType(method_id.class_idx_, dex_cache, class_loader);
Vladimir Markoba118822017-06-12 15:41:56 +0100279 DCHECK(klass != nullptr);
280 return klass;
281 });
282}
283
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100284inline ArtMethod* ClassLinker::LookupResolvedMethod(uint32_t method_idx,
285 ObjPtr<mirror::DexCache> dex_cache,
286 ObjPtr<mirror::ClassLoader> class_loader) {
287 PointerSize pointer_size = image_pointer_size_;
288 ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx, pointer_size);
289 if (resolved == nullptr) {
290 const DexFile& dex_file = *dex_cache->GetDexFile();
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800291 const dex::MethodId& method_id = dex_file.GetMethodId(method_idx);
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100292 ObjPtr<mirror::Class> klass = LookupResolvedType(method_id.class_idx_, dex_cache, class_loader);
293 if (klass != nullptr) {
Nicolas Geoffrayea179f42018-02-08 22:30:18 +0000294 resolved = FindResolvedMethod(klass, dex_cache, class_loader, method_idx);
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100295 }
296 }
297 return resolved;
298}
299
Vladimir Markoba118822017-06-12 15:41:56 +0100300template <InvokeType type, ClassLinker::ResolveMode kResolveMode>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700301inline ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, ArtMethod* referrer) {
Vladimir Markoba118822017-06-12 15:41:56 +0100302 DCHECK(referrer != nullptr);
303 // Note: The referrer can be a Proxy constructor. In that case, we need to do the
304 // lookup in the context of the original method from where it steals the code.
305 // However, we delay the GetInterfaceMethodIfProxy() until needed.
306 DCHECK(!referrer->IsProxyMethod() || referrer->IsConstructor());
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000307 // We do not need the read barrier for getting the DexCache for the initial resolved method
308 // lookup as both from-space and to-space copies point to the same native resolved methods array.
Vladimir Marko5122e6b2017-08-17 16:10:09 +0100309 ArtMethod* resolved_method = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedMethod(
310 method_idx, image_pointer_size_);
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100311 if (resolved_method == nullptr) {
Mathieu Chartier0cd81352014-05-22 16:48:55 -0700312 return nullptr;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800313 }
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100314 DCHECK(!resolved_method->IsRuntimeMethod());
Vladimir Markoba118822017-06-12 15:41:56 +0100315 if (kResolveMode == ResolveMode::kCheckICCEAndIAE) {
316 referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
317 // Check if the invoke type matches the class type.
318 ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
319 ObjPtr<mirror::ClassLoader> class_loader = referrer->GetClassLoader();
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700320 if (CheckInvokeClassMismatch</* kThrow= */ false>(dex_cache, type, method_idx, class_loader)) {
Vladimir Markoba118822017-06-12 15:41:56 +0100321 return nullptr;
322 }
323 // Check access.
324 ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
325 if (!referring_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
326 resolved_method,
327 dex_cache,
328 method_idx)) {
329 return nullptr;
330 }
331 // Check if the invoke type matches the method type.
332 if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
333 return nullptr;
334 }
Alex Lightfedd91d2016-01-07 14:49:16 -0800335 }
Vladimir Markoba118822017-06-12 15:41:56 +0100336 return resolved_method;
Alex Lightfedd91d2016-01-07 14:49:16 -0800337}
338
Andreas Gampe42ef8ab2015-12-03 17:27:32 -0800339template <ClassLinker::ResolveMode kResolveMode>
Mathieu Chartierc77f3ab2015-09-03 19:41:50 -0700340inline ArtMethod* ClassLinker::ResolveMethod(Thread* self,
341 uint32_t method_idx,
342 ArtMethod* referrer,
343 InvokeType type) {
Vladimir Markoba118822017-06-12 15:41:56 +0100344 DCHECK(referrer != nullptr);
345 // Note: The referrer can be a Proxy constructor. In that case, we need to do the
346 // lookup in the context of the original method from where it steals the code.
347 // However, we delay the GetInterfaceMethodIfProxy() until needed.
348 DCHECK(!referrer->IsProxyMethod() || referrer->IsConstructor());
Mathieu Chartiera59d9b22016-09-26 18:13:17 -0700349 Thread::PoisonObjectPointersIfDebug();
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000350 // We do not need the read barrier for getting the DexCache for the initial resolved method
351 // lookup as both from-space and to-space copies point to the same native resolved methods array.
Vladimir Marko5122e6b2017-08-17 16:10:09 +0100352 ArtMethod* resolved_method = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedMethod(
353 method_idx, image_pointer_size_);
Vladimir Marko07bfbac2017-07-06 14:55:02 +0100354 DCHECK(resolved_method == nullptr || !resolved_method->IsRuntimeMethod());
355 if (UNLIKELY(resolved_method == nullptr)) {
Vladimir Markoba118822017-06-12 15:41:56 +0100356 referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700357 ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700358 StackHandleScope<2> hs(self);
Alex Light4ba388a2017-01-27 10:26:49 -0800359 Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer->GetDexCache()));
Mathieu Chartiere401d142015-04-22 13:56:20 -0700360 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
Vladimir Marko89011192017-12-11 13:45:05 +0000361 resolved_method = ResolveMethod<kResolveMode>(method_idx,
Andreas Gampe42ef8ab2015-12-03 17:27:32 -0800362 h_dex_cache,
363 h_class_loader,
364 referrer,
365 type);
Vladimir Markoba118822017-06-12 15:41:56 +0100366 } else if (kResolveMode == ResolveMode::kCheckICCEAndIAE) {
367 referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
368 // Check if the invoke type matches the class type.
369 ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
370 ObjPtr<mirror::ClassLoader> class_loader = referrer->GetClassLoader();
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700371 if (CheckInvokeClassMismatch</* kThrow= */ true>(dex_cache, type, method_idx, class_loader)) {
Vladimir Markoba118822017-06-12 15:41:56 +0100372 DCHECK(Thread::Current()->IsExceptionPending());
373 return nullptr;
374 }
375 // Check access.
376 ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
377 if (!referring_class->CheckResolvedMethodAccess(resolved_method->GetDeclaringClass(),
378 resolved_method,
379 dex_cache,
380 method_idx,
381 type)) {
382 DCHECK(Thread::Current()->IsExceptionPending());
383 return nullptr;
384 }
385 // Check if the invoke type matches the method type.
386 if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
387 ThrowIncompatibleClassChangeError(type,
388 resolved_method->GetInvokeType(),
389 resolved_method,
390 referrer);
391 return nullptr;
392 }
Mathieu Chartier0cd81352014-05-22 16:48:55 -0700393 }
Andreas Gampe58a5af82014-07-31 16:23:49 -0700394 // Note: We cannot check here to see whether we added the method to the cache. It
395 // might be an erroneous class, which results in it being hidden from us.
Mathieu Chartier0cd81352014-05-22 16:48:55 -0700396 return resolved_method;
397}
398
Vladimir Markof44d36c2017-03-14 14:18:46 +0000399inline ArtField* ClassLinker::LookupResolvedField(uint32_t field_idx,
400 ArtMethod* referrer,
401 bool is_static) {
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000402 // We do not need the read barrier for getting the DexCache for the initial resolved field
403 // lookup as both from-space and to-space copies point to the same native resolved fields array.
404 ArtField* field = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedField(
405 field_idx, image_pointer_size_);
Vladimir Markof44d36c2017-03-14 14:18:46 +0000406 if (field == nullptr) {
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000407 ObjPtr<mirror::ClassLoader> class_loader = referrer->GetDeclaringClass()->GetClassLoader();
408 field = LookupResolvedField(field_idx, referrer->GetDexCache(), class_loader, is_static);
Vladimir Markof44d36c2017-03-14 14:18:46 +0000409 }
410 return field;
Mathieu Chartier0cd81352014-05-22 16:48:55 -0700411}
412
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700413inline ArtField* ClassLinker::ResolveField(uint32_t field_idx,
414 ArtMethod* referrer,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700415 bool is_static) {
Mathieu Chartiera59d9b22016-09-26 18:13:17 -0700416 Thread::PoisonObjectPointersIfDebug();
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000417 // We do not need the read barrier for getting the DexCache for the initial resolved field
418 // lookup as both from-space and to-space copies point to the same native resolved fields array.
419 ArtField* resolved_field = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedField(
420 field_idx, image_pointer_size_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700421 if (UNLIKELY(resolved_field == nullptr)) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700422 StackHandleScope<2> hs(Thread::Current());
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000423 ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
Alex Lightdba61482016-12-21 08:20:29 -0800424 Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache()));
Vladimir Marko666ee3d2017-12-11 18:37:36 +0000425 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referring_class->GetClassLoader()));
Vladimir Markoe11dd502017-12-08 14:09:45 +0000426 resolved_field = ResolveField(field_idx, dex_cache, class_loader, is_static);
Andreas Gampe58a5af82014-07-31 16:23:49 -0700427 // Note: We cannot check here to see whether we added the field to the cache. The type
428 // might be an erroneous class, which results in it being hidden from us.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800429 }
430 return resolved_field;
431}
432
Mathieu Chartier72041a02017-07-14 18:23:25 -0700433template <class Visitor>
434inline void ClassLinker::VisitClassTables(const Visitor& visitor) {
435 Thread* const self = Thread::Current();
436 WriterMutexLock mu(self, *Locks::classlinker_classes_lock_);
437 for (const ClassLoaderData& data : class_loaders_) {
438 if (data.class_table != nullptr) {
439 visitor(data.class_table);
440 }
441 }
442}
443
Andreas Gampe88dbad32018-06-26 19:54:12 -0700444template <ReadBarrierOption kReadBarrierOption>
445inline ObjPtr<mirror::ObjectArray<mirror::Class>> ClassLinker::GetClassRoots() {
446 ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots =
447 class_roots_.Read<kReadBarrierOption>();
448 DCHECK(class_roots != nullptr);
449 return class_roots;
450}
451
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800452} // namespace art
453
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700454#endif // ART_RUNTIME_CLASS_LINKER_INL_H_