1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "class.h"
18
19 #include <unordered_set>
20 #include <string_view>
21
22 #include "android-base/macros.h"
23 #include "android-base/stringprintf.h"
24
25 #include "array-inl.h"
26 #include "art_field-inl.h"
27 #include "art_method-inl.h"
28 #include "base/logging.h" // For VLOG.
29 #include "base/pointer_size.h"
30 #include "base/sdk_version.h"
31 #include "base/utils.h"
32 #include "class-inl.h"
33 #include "class_ext-inl.h"
34 #include "class_linker-inl.h"
35 #include "class_loader.h"
36 #include "class_root-inl.h"
37 #include "dex/descriptors_names.h"
38 #include "dex/dex_file-inl.h"
39 #include "dex/dex_file_annotations.h"
40 #include "dex/signature-inl.h"
41 #include "dex_cache-inl.h"
42 #include "field.h"
43 #include "gc/accounting/card_table-inl.h"
44 #include "gc/heap-inl.h"
45 #include "handle_scope-inl.h"
46 #include "hidden_api.h"
47 #include "jni_id_type.h"
48 #include "subtype_check.h"
49 #include "method.h"
50 #include "object-inl.h"
51 #include "object-refvisitor-inl.h"
52 #include "object_array-alloc-inl.h"
53 #include "object_array-inl.h"
54 #include "object_lock.h"
55 #include "string-inl.h"
56 #include "runtime.h"
57 #include "thread.h"
58 #include "throwable.h"
59 #include "well_known_classes.h"
60
61 namespace art HIDDEN {
62
63 namespace mirror {
64
65 using android::base::StringPrintf;
66
IsMirrored()67 bool Class::IsMirrored() {
68 if (LIKELY(!IsBootStrapClassLoaded())) {
69 return false;
70 }
71 if (IsPrimitive() || IsArrayClass() || IsProxyClass()) {
72 return true;
73 }
74 std::string name_storage;
75 const std::string_view name(this->GetDescriptor(&name_storage));
76 return IsMirroredDescriptor(name);
77 }
78
GetPrimitiveClass(ObjPtr<mirror::String> name)79 ObjPtr<mirror::Class> Class::GetPrimitiveClass(ObjPtr<mirror::String> name) {
80 const char* expected_name = nullptr;
81 ClassRoot class_root = ClassRoot::kJavaLangObject; // Invalid.
82 if (name != nullptr && name->GetLength() >= 2) {
83 // Perfect hash for the expected values: from the second letters of the primitive types,
84 // only 'y' has the bit 0x10 set, so use it to change 'b' to 'B'.
85 char hash = name->CharAt(0) ^ ((name->CharAt(1) & 0x10) << 1);
86 switch (hash) {
87 case 'b': expected_name = "boolean"; class_root = ClassRoot::kPrimitiveBoolean; break;
88 case 'B': expected_name = "byte"; class_root = ClassRoot::kPrimitiveByte; break;
89 case 'c': expected_name = "char"; class_root = ClassRoot::kPrimitiveChar; break;
90 case 'd': expected_name = "double"; class_root = ClassRoot::kPrimitiveDouble; break;
91 case 'f': expected_name = "float"; class_root = ClassRoot::kPrimitiveFloat; break;
92 case 'i': expected_name = "int"; class_root = ClassRoot::kPrimitiveInt; break;
93 case 'l': expected_name = "long"; class_root = ClassRoot::kPrimitiveLong; break;
94 case 's': expected_name = "short"; class_root = ClassRoot::kPrimitiveShort; break;
95 case 'v': expected_name = "void"; class_root = ClassRoot::kPrimitiveVoid; break;
96 default: break;
97 }
98 }
99 if (expected_name != nullptr && name->Equals(expected_name)) {
100 ObjPtr<mirror::Class> klass = GetClassRoot(class_root);
101 DCHECK(klass != nullptr);
102 return klass;
103 } else {
104 Thread* self = Thread::Current();
105 if (name == nullptr) {
106 // Note: ThrowNullPointerException() requires a message which we deliberately want to omit.
107 self->ThrowNewException("Ljava/lang/NullPointerException;", /* msg= */ nullptr);
108 } else {
109 self->ThrowNewException("Ljava/lang/ClassNotFoundException;", name->ToModifiedUtf8().c_str());
110 }
111 return nullptr;
112 }
113 }
114
EnsureExtDataPresent(Handle<Class> h_this,Thread * self)115 ObjPtr<ClassExt> Class::EnsureExtDataPresent(Handle<Class> h_this, Thread* self) {
116 ObjPtr<ClassExt> existing(h_this->GetExtData());
117 if (!existing.IsNull()) {
118 return existing;
119 }
120 StackHandleScope<2> hs(self);
121 // Clear exception so we can allocate.
122 Handle<Throwable> throwable(hs.NewHandle(self->GetException()));
123 self->ClearException();
124 // Allocate the ClassExt
125 Handle<ClassExt> new_ext(hs.NewHandle(ClassExt::Alloc(self)));
126 if (new_ext == nullptr) {
127 // OOM allocating the classExt.
128 // TODO Should we restore the suppressed exception?
129 self->AssertPendingOOMException();
130 return nullptr;
131 } else {
132 MemberOffset ext_offset(OFFSET_OF_OBJECT_MEMBER(Class, ext_data_));
133 bool set;
134 // Set the ext_data_ field using CAS semantics.
135 if (Runtime::Current()->IsActiveTransaction()) {
136 set = h_this->CasFieldObject<true>(ext_offset,
137 nullptr,
138 new_ext.Get(),
139 CASMode::kStrong,
140 std::memory_order_seq_cst);
141 } else {
142 set = h_this->CasFieldObject<false>(ext_offset,
143 nullptr,
144 new_ext.Get(),
145 CASMode::kStrong,
146 std::memory_order_seq_cst);
147 }
148 ObjPtr<ClassExt> ret(set ? new_ext.Get() : h_this->GetExtData());
149 DCHECK_IMPLIES(set, h_this->GetExtData() == new_ext.Get());
150 CHECK(!ret.IsNull());
151 // Restore the exception if there was one.
152 if (throwable != nullptr) {
153 self->SetException(throwable.Get());
154 }
155 return ret;
156 }
157 }
158
159 template <typename T>
CheckSetStatus(Thread * self,T thiz,ClassStatus new_status,ClassStatus old_status)160 static void CheckSetStatus(Thread* self, T thiz, ClassStatus new_status, ClassStatus old_status)
161 REQUIRES_SHARED(Locks::mutator_lock_) {
162 if (UNLIKELY(new_status <= old_status && new_status != ClassStatus::kErrorUnresolved &&
163 new_status != ClassStatus::kErrorResolved && new_status != ClassStatus::kRetired)) {
164 LOG(FATAL) << "Unexpected change back of class status for " << thiz->PrettyClass() << " "
165 << old_status << " -> " << new_status;
166 }
167 if (old_status == ClassStatus::kInitialized) {
168 // We do not hold the lock for making the class visibly initialized
169 // as this is unnecessary and could lead to deadlocks.
170 CHECK_EQ(new_status, ClassStatus::kVisiblyInitialized);
171 } else if ((new_status >= ClassStatus::kResolved || old_status >= ClassStatus::kResolved) &&
172 !Locks::mutator_lock_->IsExclusiveHeld(self)) {
173 // When classes are being resolved the resolution code should hold the
174 // lock or have everything else suspended
175 CHECK_EQ(thiz->GetLockOwnerThreadId(), self->GetThreadId())
176 << "Attempt to change status of class while not holding its lock: " << thiz->PrettyClass()
177 << " " << old_status << " -> " << new_status;
178 }
179 if (UNLIKELY(Locks::mutator_lock_->IsExclusiveHeld(self))) {
180 CHECK(!Class::IsErroneous(new_status))
181 << "status " << new_status
182 << " cannot be set while suspend-all is active. Would require allocations.";
183 CHECK(thiz->IsResolved())
184 << thiz->PrettyClass()
185 << " not resolved during suspend-all status change. Waiters might be missed!";
186 }
187 }
188
SetStatusInternal(ClassStatus new_status)189 void Class::SetStatusInternal(ClassStatus new_status) {
190 if (kBitstringSubtypeCheckEnabled) {
191 // FIXME: This looks broken with respect to aborted transactions.
192 SubtypeCheck<ObjPtr<mirror::Class>>::WriteStatus(this, new_status);
193 } else {
194 // The ClassStatus is always in the 4 most-significant bits of status_.
195 static_assert(sizeof(status_) == sizeof(uint32_t), "Size of status_ not equal to uint32");
196 uint32_t new_status_value = static_cast<uint32_t>(new_status) << (32 - kClassStatusBitSize);
197 if (Runtime::Current()->IsActiveTransaction()) {
198 SetField32Volatile<true>(StatusOffset(), new_status_value);
199 } else {
200 SetField32Volatile<false>(StatusOffset(), new_status_value);
201 }
202 }
203 }
204
SetStatusLocked(ClassStatus new_status)205 void Class::SetStatusLocked(ClassStatus new_status) {
206 ClassStatus old_status = GetStatus();
207 CheckSetStatus(Thread::Current(), this, new_status, old_status);
208 SetStatusInternal(new_status);
209 }
210
SetStatus(Handle<Class> h_this,ClassStatus new_status,Thread * self)211 void Class::SetStatus(Handle<Class> h_this, ClassStatus new_status, Thread* self) {
212 ClassStatus old_status = h_this->GetStatus();
213 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
214 bool class_linker_initialized = class_linker != nullptr && class_linker->IsInitialized();
215 if (LIKELY(class_linker_initialized)) {
216 CheckSetStatus(self, h_this, new_status, old_status);
217 }
218 if (UNLIKELY(IsErroneous(new_status))) {
219 CHECK(!h_this->IsErroneous())
220 << "Attempt to set as erroneous an already erroneous class "
221 << h_this->PrettyClass()
222 << " old_status: " << old_status << " new_status: " << new_status;
223 CHECK_EQ(new_status == ClassStatus::kErrorResolved, old_status >= ClassStatus::kResolved);
224 if (VLOG_IS_ON(class_linker)) {
225 LOG(ERROR) << "Setting " << h_this->PrettyDescriptor() << " to erroneous.";
226 if (self->IsExceptionPending()) {
227 LOG(ERROR) << "Exception: " << self->GetException()->Dump();
228 }
229 }
230
231 ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self));
232 if (!ext.IsNull()) {
233 self->AssertPendingException();
234 ext->SetErroneousStateError(self->GetException());
235 } else {
236 self->AssertPendingOOMException();
237 }
238 self->AssertPendingException();
239 }
240
241 h_this->SetStatusInternal(new_status);
242
243 // Setting the object size alloc fast path needs to be after the status write so that if the
244 // alloc path sees a valid object size, we would know that it's initialized as long as it has a
245 // load-acquire/fake dependency.
246 if (new_status == ClassStatus::kVisiblyInitialized && !h_this->IsVariableSize()) {
247 DCHECK_EQ(h_this->GetObjectSizeAllocFastPath(), std::numeric_limits<uint32_t>::max());
248 // Finalizable objects must always go slow path.
249 if (!h_this->IsFinalizable()) {
250 h_this->SetObjectSizeAllocFastPath(RoundUp(h_this->GetObjectSize(), kObjectAlignment));
251 }
252 }
253
254 if (!class_linker_initialized) {
255 // When the class linker is being initialized its single threaded and by definition there can be
256 // no waiters. During initialization classes may appear temporary but won't be retired as their
257 // size was statically computed.
258 } else {
259 // Classes that are being resolved or initialized need to notify waiters that the class status
260 // changed. See ClassLinker::EnsureResolved and ClassLinker::WaitForInitializeClass.
261 if (h_this->IsTemp()) {
262 // Class is a temporary one, ensure that waiters for resolution get notified of retirement
263 // so that they can grab the new version of the class from the class linker's table.
264 CHECK_LT(new_status, ClassStatus::kResolved) << h_this->PrettyDescriptor();
265 if (new_status == ClassStatus::kRetired || new_status == ClassStatus::kErrorUnresolved) {
266 h_this->NotifyAll(self);
267 }
268 } else if (old_status == ClassStatus::kInitialized) {
269 // Do not notify for transition from kInitialized to ClassStatus::kVisiblyInitialized.
270 // This is a hidden transition, not observable by bytecode.
271 DCHECK_EQ(new_status, ClassStatus::kVisiblyInitialized); // Already CHECK()ed above.
272 } else {
273 CHECK_NE(new_status, ClassStatus::kRetired);
274 if (old_status >= ClassStatus::kResolved || new_status >= ClassStatus::kResolved) {
275 h_this->NotifyAll(self);
276 }
277 }
278 }
279 }
280
SetStatusForPrimitiveOrArray(ClassStatus new_status)281 void Class::SetStatusForPrimitiveOrArray(ClassStatus new_status) {
282 DCHECK(IsPrimitive<kVerifyNone>() || IsArrayClass<kVerifyNone>());
283 DCHECK(!IsErroneous(new_status));
284 DCHECK(!IsErroneous(GetStatus<kVerifyNone>()));
285 DCHECK_GT(new_status, GetStatus<kVerifyNone>());
286
287 if (kBitstringSubtypeCheckEnabled) {
288 LOG(FATAL) << "Unimplemented";
289 }
290 // The ClassStatus is always in the 4 most-significant bits of status_.
291 static_assert(sizeof(status_) == sizeof(uint32_t), "Size of status_ not equal to uint32");
292 uint32_t new_status_value = static_cast<uint32_t>(new_status) << (32 - kClassStatusBitSize);
293 // Use normal store. For primitives and core arrays classes (Object[],
294 // Class[], String[] and primitive arrays), the status is set while the
295 // process is still single threaded. For other arrays classes, it is set
296 // in a pre-fence visitor which initializes all fields and the subsequent
297 // fence together with address dependency shall ensure memory visibility.
298 SetField32</*kTransactionActive=*/ false,
299 /*kCheckTransaction=*/ false,
300 kVerifyNone>(StatusOffset(), new_status_value);
301
302 // Do not update `object_alloc_fast_path_`. Arrays are variable size and
303 // instances of primitive classes cannot be created at all.
304
305 // There can be no waiters to notify as these classes are initialized
306 // before another thread can see them.
307 }
308
SetDexCache(ObjPtr<DexCache> new_dex_cache)309 void Class::SetDexCache(ObjPtr<DexCache> new_dex_cache) {
310 SetFieldObjectTransaction(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache);
311 }
312
SetClassSize(uint32_t new_class_size)313 void Class::SetClassSize(uint32_t new_class_size) {
314 if (kIsDebugBuild && new_class_size < GetClassSize()) {
315 DumpClass(LOG_STREAM(FATAL_WITHOUT_ABORT), kDumpClassFullDetail);
316 LOG(FATAL_WITHOUT_ABORT) << new_class_size << " vs " << GetClassSize();
317 LOG(FATAL) << "class=" << PrettyTypeOf();
318 }
319 SetField32</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
320 OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size);
321 }
322
GetObsoleteClass()323 ObjPtr<Class> Class::GetObsoleteClass() {
324 ObjPtr<ClassExt> ext(GetExtData());
325 if (ext.IsNull()) {
326 return nullptr;
327 } else {
328 return ext->GetObsoleteClass();
329 }
330 }
331
332 // Return the class' name. The exact format is bizarre, but it's the specified behavior for
333 // Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int"
334 // but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than
335 // slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness.
ComputeName(Handle<Class> h_this)336 ObjPtr<String> Class::ComputeName(Handle<Class> h_this) {
337 ObjPtr<String> name = h_this->GetName();
338 if (name != nullptr) {
339 return name;
340 }
341 std::string temp;
342 const char* descriptor = h_this->GetDescriptor(&temp);
343 Thread* self = Thread::Current();
344 if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
345 // The descriptor indicates that this is the class for
346 // a primitive type; special-case the return value.
347 const char* c_name = nullptr;
348 switch (descriptor[0]) {
349 case 'Z': c_name = "boolean"; break;
350 case 'B': c_name = "byte"; break;
351 case 'C': c_name = "char"; break;
352 case 'S': c_name = "short"; break;
353 case 'I': c_name = "int"; break;
354 case 'J': c_name = "long"; break;
355 case 'F': c_name = "float"; break;
356 case 'D': c_name = "double"; break;
357 case 'V': c_name = "void"; break;
358 default:
359 LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
360 }
361 name = String::AllocFromModifiedUtf8(self, c_name);
362 } else {
363 // Convert the UTF-8 name to a java.lang.String. The name must use '.' to separate package
364 // components.
365 name = String::AllocFromModifiedUtf8(self, DescriptorToDot(descriptor).c_str());
366 }
367 h_this->SetName(name);
368 return name;
369 }
370
DumpClass(std::ostream & os,int flags)371 void Class::DumpClass(std::ostream& os, int flags) {
372 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
373 if ((flags & kDumpClassFullDetail) == 0) {
374 os << PrettyClass();
375 if ((flags & kDumpClassClassLoader) != 0) {
376 os << ' ' << GetClassLoader();
377 }
378 if ((flags & kDumpClassInitialized) != 0) {
379 os << ' ' << GetStatus();
380 }
381 os << "\n";
382 return;
383 }
384
385 ObjPtr<Class> super = GetSuperClass();
386 auto image_pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
387
388 std::string temp;
389 os << "----- " << (IsInterface() ? "interface" : "class") << " "
390 << "'" << GetDescriptor(&temp) << "' cl=" << GetClassLoader() << " -----\n"
391 << " objectSize=" << SizeOf() << " "
392 << "(" << (super != nullptr ? super->SizeOf() : -1) << " from super)\n"
393 << StringPrintf(" access=0x%04x.%04x\n",
394 GetAccessFlags() >> 16,
395 GetAccessFlags() & kAccJavaFlagsMask);
396 if (super != nullptr) {
397 os << " super='" << super->PrettyClass() << "' (cl=" << super->GetClassLoader() << ")\n";
398 }
399 if (IsArrayClass()) {
400 os << " componentType=" << PrettyClass(GetComponentType()) << "\n";
401 }
402 const size_t num_direct_interfaces = NumDirectInterfaces();
403 if (num_direct_interfaces > 0) {
404 os << " interfaces (" << num_direct_interfaces << "):\n";
405 for (size_t i = 0; i < num_direct_interfaces; ++i) {
406 ObjPtr<Class> interface = GetDirectInterface(i);
407 if (interface == nullptr) {
408 os << StringPrintf(" %2zd: nullptr!\n", i);
409 } else {
410 ObjPtr<ClassLoader> cl = interface->GetClassLoader();
411 os << StringPrintf(" %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl.Ptr());
412 }
413 }
414 }
415 if (!IsLoaded()) {
416 os << " class not yet loaded";
417 } else {
418 os << " vtable (" << NumVirtualMethods() << " entries, "
419 << (super != nullptr ? super->NumVirtualMethods() : 0) << " in super):\n";
420 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
421 os << StringPrintf(" %2zd: %s\n", i, ArtMethod::PrettyMethod(
422 GetVirtualMethodDuringLinking(i, image_pointer_size)).c_str());
423 }
424 os << " direct methods (" << NumDirectMethods() << " entries):\n";
425 for (size_t i = 0; i < NumDirectMethods(); ++i) {
426 os << StringPrintf(" %2zd: %s\n", i, ArtMethod::PrettyMethod(
427 GetDirectMethod(i, image_pointer_size)).c_str());
428 }
429 if (NumStaticFields() > 0) {
430 os << " static fields (" << NumStaticFields() << " entries):\n";
431 if (IsResolved()) {
432 for (size_t i = 0; i < NumStaticFields(); ++i) {
433 os << StringPrintf(" %2zd: %s\n", i, ArtField::PrettyField(GetStaticField(i)).c_str());
434 }
435 } else {
436 os << " <not yet available>";
437 }
438 }
439 if (NumInstanceFields() > 0) {
440 os << " instance fields (" << NumInstanceFields() << " entries):\n";
441 if (IsResolved()) {
442 for (size_t i = 0; i < NumInstanceFields(); ++i) {
443 os << StringPrintf(" %2zd: %s\n", i,
444 ArtField::PrettyField(GetInstanceField(i)).c_str());
445 }
446 } else {
447 os << " <not yet available>";
448 }
449 }
450 }
451 }
452
SetReferenceInstanceOffsets(uint32_t new_reference_offsets)453 void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
454 if (kIsDebugBuild) {
455 // Check that the number of bits set in the reference offset bitmap
456 // agrees with the number of references.
457 uint32_t count = 0;
458 for (ObjPtr<Class> c = this; c != nullptr; c = c->GetSuperClass()) {
459 count += c->NumReferenceInstanceFieldsDuringLinking();
460 }
461 uint32_t pop_cnt;
462 if ((new_reference_offsets & kVisitReferencesSlowpathMask) == 0) {
463 pop_cnt = static_cast<uint32_t>(POPCOUNT(new_reference_offsets));
464 } else {
465 uint32_t bitmap_num_words = new_reference_offsets & ~kVisitReferencesSlowpathMask;
466 uint32_t* overflow_bitmap =
467 reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(this) +
468 (GetClassSize() - bitmap_num_words * sizeof(uint32_t)));
469 pop_cnt = 0;
470 for (uint32_t i = 0; i < bitmap_num_words; i++) {
471 pop_cnt += static_cast<uint32_t>(POPCOUNT(overflow_bitmap[i]));
472 }
473 }
474 // +1 for the Class in Object.
475 CHECK_EQ(pop_cnt + 1, count);
476 }
477 // Not called within a transaction.
478 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
479 new_reference_offsets);
480 }
481
IsInSamePackage(std::string_view descriptor1,std::string_view descriptor2)482 bool Class::IsInSamePackage(std::string_view descriptor1, std::string_view descriptor2) {
483 static_assert(std::string_view::npos + 1u == 0u);
484 size_t d1_after_package = descriptor1.rfind('/') + 1u;
485 return descriptor2.starts_with(descriptor1.substr(0u, d1_after_package)) &&
486 descriptor2.find('/', d1_after_package) == std::string_view::npos;
487 }
488
IsInSamePackage(ObjPtr<Class> that)489 bool Class::IsInSamePackage(ObjPtr<Class> that) {
490 ObjPtr<Class> klass1 = this;
491 ObjPtr<Class> klass2 = that;
492 if (klass1 == klass2) {
493 return true;
494 }
495 // Class loaders must match.
496 if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
497 return false;
498 }
499 // Arrays are in the same package when their element classes are.
500 while (klass1->IsArrayClass()) {
501 klass1 = klass1->GetComponentType();
502 }
503 while (klass2->IsArrayClass()) {
504 klass2 = klass2->GetComponentType();
505 }
506 // trivial check again for array types
507 if (klass1 == klass2) {
508 return true;
509 }
510 // Compare the package part of the descriptor string.
511 if (UNLIKELY(klass1->IsProxyClass()) || UNLIKELY(klass2->IsProxyClass())) {
512 std::string temp1, temp2;
513 return IsInSamePackage(klass1->GetDescriptor(&temp1), klass2->GetDescriptor(&temp2));
514 }
515 if (UNLIKELY(klass1->IsPrimitive()) || UNLIKELY(klass2->IsPrimitive())) {
516 if (klass1->IsPrimitive() && klass2->IsPrimitive()) {
517 return true;
518 }
519 ObjPtr<Class> other_class = klass1->IsPrimitive() ? klass2 : klass1;
520 return other_class->GetDescriptorView().find('/') == std::string_view::npos;
521 }
522 return IsInSamePackage(klass1->GetDescriptorView(), klass2->GetDescriptorView());
523 }
524
IsThrowableClass()525 bool Class::IsThrowableClass() {
526 return GetClassRoot<mirror::Throwable>()->IsAssignableFrom(this);
527 }
528
529 template <typename SignatureType>
FindInterfaceMethodWithSignature(ObjPtr<Class> klass,std::string_view name,const SignatureType & signature,PointerSize pointer_size)530 static inline ArtMethod* FindInterfaceMethodWithSignature(ObjPtr<Class> klass,
531 std::string_view name,
532 const SignatureType& signature,
533 PointerSize pointer_size)
534 REQUIRES_SHARED(Locks::mutator_lock_) {
535 // If the current class is not an interface, skip the search of its declared methods;
536 // such lookup is used only to distinguish between IncompatibleClassChangeError and
537 // NoSuchMethodError and the caller has already tried to search methods in the class.
538 if (LIKELY(klass->IsInterface())) {
539 // Search declared methods, both direct and virtual.
540 // (This lookup is used also for invoke-static on interface classes.)
541 for (ArtMethod& method : klass->GetDeclaredMethodsSlice(pointer_size)) {
542 if (method.GetNameView() == name && method.GetSignature() == signature) {
543 return &method;
544 }
545 }
546 }
547
548 // TODO: If there is a unique maximally-specific non-abstract superinterface method,
549 // we should return it, otherwise an arbitrary one can be returned.
550 ObjPtr<IfTable> iftable = klass->GetIfTable();
551 for (int32_t i = 0, iftable_count = iftable->Count(); i < iftable_count; ++i) {
552 ObjPtr<Class> iface = iftable->GetInterface(i);
553 for (ArtMethod& method : iface->GetVirtualMethodsSlice(pointer_size)) {
554 if (method.GetNameView() == name && method.GetSignature() == signature) {
555 return &method;
556 }
557 }
558 }
559
560 // Then search for public non-static methods in the java.lang.Object.
561 if (LIKELY(klass->IsInterface())) {
562 ObjPtr<Class> object_class = klass->GetSuperClass();
563 DCHECK(object_class->IsObjectClass());
564 for (ArtMethod& method : object_class->GetDeclaredMethodsSlice(pointer_size)) {
565 if (method.IsPublic() && !method.IsStatic() &&
566 method.GetNameView() == name && method.GetSignature() == signature) {
567 return &method;
568 }
569 }
570 }
571 return nullptr;
572 }
573
FindInterfaceMethod(std::string_view name,std::string_view signature,PointerSize pointer_size)574 ArtMethod* Class::FindInterfaceMethod(std::string_view name,
575 std::string_view signature,
576 PointerSize pointer_size) {
577 return FindInterfaceMethodWithSignature(this, name, signature, pointer_size);
578 }
579
FindInterfaceMethod(std::string_view name,const Signature & signature,PointerSize pointer_size)580 ArtMethod* Class::FindInterfaceMethod(std::string_view name,
581 const Signature& signature,
582 PointerSize pointer_size) {
583 return FindInterfaceMethodWithSignature(this, name, signature, pointer_size);
584 }
585
FindInterfaceMethod(ObjPtr<DexCache> dex_cache,uint32_t dex_method_idx,PointerSize pointer_size)586 ArtMethod* Class::FindInterfaceMethod(ObjPtr<DexCache> dex_cache,
587 uint32_t dex_method_idx,
588 PointerSize pointer_size) {
589 // We always search by name and signature, ignoring the type index in the MethodId.
590 const DexFile& dex_file = *dex_cache->GetDexFile();
591 const dex::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
592 std::string_view name = dex_file.GetStringView(method_id.name_idx_);
593 const Signature signature = dex_file.GetMethodSignature(method_id);
594 return FindInterfaceMethod(name, signature, pointer_size);
595 }
596
IsValidInheritanceCheck(ObjPtr<mirror::Class> klass,ObjPtr<mirror::Class> declaring_class)597 static inline bool IsValidInheritanceCheck(ObjPtr<mirror::Class> klass,
598 ObjPtr<mirror::Class> declaring_class)
599 REQUIRES_SHARED(Locks::mutator_lock_) {
600 if (klass->IsArrayClass()) {
601 return declaring_class->IsObjectClass();
602 } else if (klass->IsInterface()) {
603 return declaring_class->IsObjectClass() || declaring_class == klass;
604 } else {
605 return klass->IsSubClass(declaring_class);
606 }
607 }
608
IsInheritedMethod(ObjPtr<mirror::Class> klass,ObjPtr<mirror::Class> declaring_class,ArtMethod & method)609 static inline bool IsInheritedMethod(ObjPtr<mirror::Class> klass,
610 ObjPtr<mirror::Class> declaring_class,
611 ArtMethod& method)
612 REQUIRES_SHARED(Locks::mutator_lock_) {
613 DCHECK_EQ(declaring_class, method.GetDeclaringClass());
614 DCHECK_NE(klass, declaring_class);
615 DCHECK(IsValidInheritanceCheck(klass, declaring_class));
616 uint32_t access_flags = method.GetAccessFlags();
617 if ((access_flags & (kAccPublic | kAccProtected)) != 0) {
618 return true;
619 }
620 if ((access_flags & kAccPrivate) != 0) {
621 return false;
622 }
623 for (; klass != declaring_class; klass = klass->GetSuperClass()) {
624 if (!klass->IsInSamePackage(declaring_class)) {
625 return false;
626 }
627 }
628 return true;
629 }
630
631 template <typename SignatureType>
FindClassMethodWithSignature(ObjPtr<Class> this_klass,std::string_view name,const SignatureType & signature,PointerSize pointer_size)632 static inline ArtMethod* FindClassMethodWithSignature(ObjPtr<Class> this_klass,
633 std::string_view name,
634 const SignatureType& signature,
635 PointerSize pointer_size)
636 REQUIRES_SHARED(Locks::mutator_lock_) {
637 // Search declared methods first.
638 for (ArtMethod& method : this_klass->GetDeclaredMethodsSlice(pointer_size)) {
639 ArtMethod* np_method = method.GetInterfaceMethodIfProxy(pointer_size);
640 if (np_method->GetNameView() == name && np_method->GetSignature() == signature) {
641 return &method;
642 }
643 }
644
645 // Then search the superclass chain. If we find an inherited method, return it.
646 // If we find a method that's not inherited because of access restrictions,
647 // try to find a method inherited from an interface in copied methods.
648 ObjPtr<Class> klass = this_klass->GetSuperClass();
649 ArtMethod* uninherited_method = nullptr;
650 for (; klass != nullptr; klass = klass->GetSuperClass()) {
651 DCHECK(!klass->IsProxyClass());
652 for (ArtMethod& method : klass->GetDeclaredMethodsSlice(pointer_size)) {
653 if (method.GetNameView() == name && method.GetSignature() == signature) {
654 if (IsInheritedMethod(this_klass, klass, method)) {
655 return &method;
656 }
657 uninherited_method = &method;
658 break;
659 }
660 }
661 if (uninherited_method != nullptr) {
662 break;
663 }
664 }
665
666 // Then search copied methods.
667 // If we found a method that's not inherited, stop the search in its declaring class.
668 ObjPtr<Class> end_klass = klass;
669 DCHECK_EQ(uninherited_method != nullptr, end_klass != nullptr);
670 klass = this_klass;
671 if (UNLIKELY(klass->IsProxyClass())) {
672 DCHECK(klass->GetCopiedMethodsSlice(pointer_size).empty());
673 klass = klass->GetSuperClass();
674 }
675 for (; klass != end_klass; klass = klass->GetSuperClass()) {
676 DCHECK(!klass->IsProxyClass());
677 for (ArtMethod& method : klass->GetCopiedMethodsSlice(pointer_size)) {
678 if (method.GetNameView() == name && method.GetSignature() == signature) {
679 return &method; // No further check needed, copied methods are inherited by definition.
680 }
681 }
682 }
683 return uninherited_method; // Return the `uninherited_method` if any.
684 }
685
686
FindClassMethod(std::string_view name,std::string_view signature,PointerSize pointer_size)687 ArtMethod* Class::FindClassMethod(std::string_view name,
688 std::string_view signature,
689 PointerSize pointer_size) {
690 return FindClassMethodWithSignature(this, name, signature, pointer_size);
691 }
692
FindClassMethod(std::string_view name,const Signature & signature,PointerSize pointer_size)693 ArtMethod* Class::FindClassMethod(std::string_view name,
694 const Signature& signature,
695 PointerSize pointer_size) {
696 return FindClassMethodWithSignature(this, name, signature, pointer_size);
697 }
698
699 // Binary search a range with a three-way compare function.
700 //
701 // Return a tuple consisting of a `success` value, the index of the match (`mid`) and
702 // the remaining range when we found the match (`begin` and `end`). This is useful for
703 // subsequent binary search with a secondary comparator, see `ClassMemberBinarySearch()`.
704 template <typename Compare>
705 ALWAYS_INLINE
BinarySearch(uint32_t begin,uint32_t end,Compare && cmp)706 std::tuple<bool, uint32_t, uint32_t, uint32_t> BinarySearch(uint32_t begin,
707 uint32_t end,
708 Compare&& cmp)
709 REQUIRES_SHARED(Locks::mutator_lock_) {
710 while (begin != end) {
711 uint32_t mid = (begin + end) >> 1;
712 auto cmp_result = cmp(mid);
713 if (cmp_result == 0) {
714 return {true, mid, begin, end};
715 }
716 if (cmp_result > 0) {
717 begin = mid + 1u;
718 } else {
719 end = mid;
720 }
721 }
722 return {false, 0u, 0u, 0u};
723 }
724
725 // Binary search for class members. The range passed to this search must be sorted, so
726 // declared methods or fields cannot be searched directly but declared direct methods,
727 // declared virtual methods, declared static fields or declared instance fields can.
728 template <typename NameCompare, typename SecondCompare, typename NameIndexGetter>
729 ALWAYS_INLINE
ClassMemberBinarySearch(uint32_t begin,uint32_t end,NameCompare && name_cmp,SecondCompare && second_cmp,NameIndexGetter && get_name_idx)730 std::tuple<bool, uint32_t> ClassMemberBinarySearch(uint32_t begin,
731 uint32_t end,
732 NameCompare&& name_cmp,
733 SecondCompare&& second_cmp,
734 NameIndexGetter&& get_name_idx)
735 REQUIRES_SHARED(Locks::mutator_lock_) {
736 // First search for the item with the given name.
737 bool success;
738 uint32_t mid;
739 std::tie(success, mid, begin, end) = BinarySearch(begin, end, name_cmp);
740 if (!success) {
741 return {false, 0u};
742 }
743 // If found, do the secondary comparison.
744 auto second_cmp_result = second_cmp(mid);
745 if (second_cmp_result == 0) {
746 return {true, mid};
747 }
748 // We have matched the name but not the secondary comparison. We no longer need to
749 // search for the name as string as we know the matching name string index.
750 // Repeat the above binary searches and secondary comparisons with a simpler name
751 // index compare until the search range contains only matching name.
752 auto name_idx = get_name_idx(mid);
753 if (second_cmp_result > 0) {
754 do {
755 begin = mid + 1u;
756 auto name_index_cmp = [&](uint32_t mid2) REQUIRES_SHARED(Locks::mutator_lock_) {
757 DCHECK_LE(name_idx, get_name_idx(mid2));
758 return (name_idx != get_name_idx(mid2)) ? -1 : 0;
759 };
760 std::tie(success, mid, begin, end) = BinarySearch(begin, end, name_index_cmp);
761 if (!success) {
762 return {false, 0u};
763 }
764 second_cmp_result = second_cmp(mid);
765 } while (second_cmp_result > 0);
766 end = mid;
767 } else {
768 do {
769 end = mid;
770 auto name_index_cmp = [&](uint32_t mid2) REQUIRES_SHARED(Locks::mutator_lock_) {
771 DCHECK_GE(name_idx, get_name_idx(mid2));
772 return (name_idx != get_name_idx(mid2)) ? 1 : 0;
773 };
774 std::tie(success, mid, begin, end) = BinarySearch(begin, end, name_index_cmp);
775 if (!success) {
776 return {false, 0u};
777 }
778 second_cmp_result = second_cmp(mid);
779 } while (second_cmp_result < 0);
780 begin = mid + 1u;
781 }
782 if (second_cmp_result == 0) {
783 return {true, mid};
784 }
785 // All items in the remaining range have a matching name, so search with secondary comparison.
786 std::tie(success, mid, std::ignore, std::ignore) = BinarySearch(begin, end, second_cmp);
787 return {success, mid};
788 }
789
FindDeclaredClassMethod(ObjPtr<mirror::Class> klass,const DexFile & dex_file,std::string_view name,Signature signature,PointerSize pointer_size)790 static std::tuple<bool, ArtMethod*> FindDeclaredClassMethod(ObjPtr<mirror::Class> klass,
791 const DexFile& dex_file,
792 std::string_view name,
793 Signature signature,
794 PointerSize pointer_size)
795 REQUIRES_SHARED(Locks::mutator_lock_) {
796 DCHECK(&klass->GetDexFile() == &dex_file);
797 DCHECK(!name.empty());
798
799 ArraySlice<ArtMethod> declared_methods = klass->GetDeclaredMethodsSlice(pointer_size);
800 DCHECK(!declared_methods.empty());
801 auto get_method_id = [&](uint32_t mid) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE
802 -> const dex::MethodId& {
803 ArtMethod& method = declared_methods[mid];
804 DCHECK(method.GetDexFile() == &dex_file);
805 DCHECK_NE(method.GetDexMethodIndex(), dex::kDexNoIndex);
806 return dex_file.GetMethodId(method.GetDexMethodIndex());
807 };
808 auto name_cmp = [&](uint32_t mid) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE {
809 // Do not use ArtMethod::GetNameView() to avoid reloading dex file through the same
810 // declaring class from different methods and also avoid the runtime method check.
811 const dex::MethodId& method_id = get_method_id(mid);
812 return DexFile::CompareMemberNames(name, dex_file.GetMethodNameView(method_id));
813 };
814 auto signature_cmp = [&](uint32_t mid) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE {
815 // Do not use ArtMethod::GetSignature() to avoid reloading dex file through the same
816 // declaring class from different methods and also avoid the runtime method check.
817 const dex::MethodId& method_id = get_method_id(mid);
818 return signature.Compare(dex_file.GetMethodSignature(method_id));
819 };
820 auto get_name_idx = [&](uint32_t mid) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE {
821 const dex::MethodId& method_id = get_method_id(mid);
822 return method_id.name_idx_;
823 };
824
825 // Use binary search in the sorted direct methods, then in the sorted virtual methods.
826 uint32_t num_direct_methods = klass->NumDirectMethods();
827 uint32_t num_declared_methods = dchecked_integral_cast<uint32_t>(declared_methods.size());
828 DCHECK_LE(num_direct_methods, num_declared_methods);
829 const uint32_t ranges[2][2] = {
830 {0u, num_direct_methods}, // Declared direct methods.
831 {num_direct_methods, num_declared_methods} // Declared virtual methods.
832 };
833 for (const uint32_t (&range)[2] : ranges) {
834 auto [success, mid] =
835 ClassMemberBinarySearch(range[0], range[1], name_cmp, signature_cmp, get_name_idx);
836 if (success) {
837 return {true, &declared_methods[mid]};
838 }
839 }
840
841 // Did not find a declared method in either slice.
842 return {false, nullptr};
843 }
844
845 FLATTEN
FindClassMethod(ObjPtr<DexCache> dex_cache,uint32_t dex_method_idx,PointerSize pointer_size)846 ArtMethod* Class::FindClassMethod(ObjPtr<DexCache> dex_cache,
847 uint32_t dex_method_idx,
848 PointerSize pointer_size) {
849 // FIXME: Hijacking a proxy class by a custom class loader can break this assumption.
850 DCHECK(!IsProxyClass());
851
852 // First try to find a declared method by dex_method_idx if we have a dex_cache match.
853 ObjPtr<DexCache> this_dex_cache = GetDexCache();
854 if (this_dex_cache == dex_cache) {
855 // Lookup is always performed in the class referenced by the MethodId.
856 DCHECK_EQ(dex_type_idx_, GetDexFile().GetMethodId(dex_method_idx).class_idx_.index_);
857 for (ArtMethod& method : GetDeclaredMethodsSlice(pointer_size)) {
858 if (method.GetDexMethodIndex() == dex_method_idx) {
859 return &method;
860 }
861 }
862 }
863
864 // If not found, we need to search by name and signature.
865 const DexFile& dex_file = *dex_cache->GetDexFile();
866 const dex::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
867 const Signature signature = dex_file.GetMethodSignature(method_id);
868 std::string_view name; // Do not touch the dex file string data until actually needed.
869
870 // If we do not have a dex_cache match, try to find the declared method in this class now.
871 if (this_dex_cache != dex_cache && !GetDeclaredMethodsSlice(pointer_size).empty()) {
872 DCHECK(name.empty());
873 name = dex_file.GetMethodNameView(method_id);
874 auto [success, method] = FindDeclaredClassMethod(
875 this, *this_dex_cache->GetDexFile(), name, signature, pointer_size);
876 DCHECK_EQ(success, method != nullptr);
877 if (success) {
878 return method;
879 }
880 }
881
882 // Then search the superclass chain. If we find an inherited method, return it.
883 // If we find a method that's not inherited because of access restrictions,
884 // try to find a method inherited from an interface in copied methods.
885 ArtMethod* uninherited_method = nullptr;
886 ObjPtr<Class> klass = GetSuperClass();
887 for (; klass != nullptr; klass = klass->GetSuperClass()) {
888 ArtMethod* candidate_method = nullptr;
889 ArraySlice<ArtMethod> declared_methods = klass->GetDeclaredMethodsSlice(pointer_size);
890 ObjPtr<DexCache> klass_dex_cache = klass->GetDexCache();
891 if (klass_dex_cache == dex_cache) {
892 // Matching dex_cache. We cannot compare the `dex_method_idx` anymore because
893 // the type index differs, so compare the name index and proto index.
894 for (ArtMethod& method : declared_methods) {
895 const dex::MethodId& cmp_method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
896 if (cmp_method_id.name_idx_ == method_id.name_idx_ &&
897 cmp_method_id.proto_idx_ == method_id.proto_idx_) {
898 candidate_method = &method;
899 break;
900 }
901 }
902 } else if (!declared_methods.empty()) {
903 if (name.empty()) {
904 name = dex_file.GetMethodNameView(method_id);
905 }
906 auto [success, method] = FindDeclaredClassMethod(
907 klass, *klass_dex_cache->GetDexFile(), name, signature, pointer_size);
908 DCHECK_EQ(success, method != nullptr);
909 if (success) {
910 candidate_method = method;
911 }
912 }
913 if (candidate_method != nullptr) {
914 if (IsInheritedMethod(this, klass, *candidate_method)) {
915 return candidate_method;
916 } else {
917 uninherited_method = candidate_method;
918 break;
919 }
920 }
921 }
922
923 // Then search copied methods.
924 // If we found a method that's not inherited, stop the search in its declaring class.
925 ObjPtr<Class> end_klass = klass;
926 DCHECK_EQ(uninherited_method != nullptr, end_klass != nullptr);
927 // After we have searched the declared methods of the super-class chain,
928 // search copied methods which can contain methods from interfaces.
929 for (klass = this; klass != end_klass; klass = klass->GetSuperClass()) {
930 ArraySlice<ArtMethod> copied_methods = klass->GetCopiedMethodsSlice(pointer_size);
931 if (!copied_methods.empty() && name.empty()) {
932 name = dex_file.GetMethodNameView(method_id);
933 }
934 for (ArtMethod& method : copied_methods) {
935 if (method.GetNameView() == name && method.GetSignature() == signature) {
936 return &method; // No further check needed, copied methods are inherited by definition.
937 }
938 }
939 }
940 return uninherited_method; // Return the `uninherited_method` if any.
941 }
942
FindConstructor(std::string_view signature,PointerSize pointer_size)943 ArtMethod* Class::FindConstructor(std::string_view signature, PointerSize pointer_size) {
944 // Internal helper, never called on proxy classes. We can skip GetInterfaceMethodIfProxy().
945 DCHECK(!IsProxyClass());
946 std::string_view name("<init>");
947 for (ArtMethod& method : GetDirectMethodsSliceUnchecked(pointer_size)) {
948 if (method.GetName() == name && method.GetSignature() == signature) {
949 return &method;
950 }
951 }
952 return nullptr;
953 }
954
FindDeclaredDirectMethodByName(std::string_view name,PointerSize pointer_size)955 ArtMethod* Class::FindDeclaredDirectMethodByName(std::string_view name, PointerSize pointer_size) {
956 for (auto& method : GetDirectMethods(pointer_size)) {
957 ArtMethod* const np_method = method.GetInterfaceMethodIfProxy(pointer_size);
958 if (name == np_method->GetName()) {
959 return &method;
960 }
961 }
962 return nullptr;
963 }
964
FindDeclaredVirtualMethodByName(std::string_view name,PointerSize pointer_size)965 ArtMethod* Class::FindDeclaredVirtualMethodByName(std::string_view name, PointerSize pointer_size) {
966 for (auto& method : GetVirtualMethods(pointer_size)) {
967 ArtMethod* const np_method = method.GetInterfaceMethodIfProxy(pointer_size);
968 if (name == np_method->GetName()) {
969 return &method;
970 }
971 }
972 return nullptr;
973 }
974
FindVirtualMethodForInterfaceSuper(ArtMethod * method,PointerSize pointer_size)975 ArtMethod* Class::FindVirtualMethodForInterfaceSuper(ArtMethod* method, PointerSize pointer_size) {
976 DCHECK(method->GetDeclaringClass()->IsInterface());
977 DCHECK(IsInterface()) << "Should only be called on a interface class";
978 // Check if we have one defined on this interface first. This includes searching copied ones to
979 // get any conflict methods. Conflict methods are copied into each subtype from the supertype. We
980 // don't do any indirect method checks here.
981 for (ArtMethod& iface_method : GetVirtualMethods(pointer_size)) {
982 if (method->HasSameNameAndSignature(&iface_method)) {
983 return &iface_method;
984 }
985 }
986
987 std::vector<ArtMethod*> abstract_methods;
988 // Search through the IFTable for a working version. We don't need to check for conflicts
989 // because if there was one it would appear in this classes virtual_methods_ above.
990
991 Thread* self = Thread::Current();
992 StackHandleScope<2> hs(self);
993 MutableHandle<IfTable> iftable(hs.NewHandle(GetIfTable()));
994 MutableHandle<Class> iface(hs.NewHandle<Class>(nullptr));
995 size_t iftable_count = GetIfTableCount();
996 // Find the method. We don't need to check for conflicts because they would have been in the
997 // copied virtuals of this interface. Order matters, traverse in reverse topological order; most
998 // subtypiest interfaces get visited first.
999 for (size_t k = iftable_count; k != 0;) {
1000 k--;
1001 DCHECK_LT(k, iftable->Count());
1002 iface.Assign(iftable->GetInterface(k));
1003 // Iterate through every declared method on this interface. Each direct method's name/signature
1004 // is unique so the order of the inner loop doesn't matter.
1005 for (auto& method_iter : iface->GetDeclaredVirtualMethods(pointer_size)) {
1006 ArtMethod* current_method = &method_iter;
1007 if (current_method->HasSameNameAndSignature(method)) {
1008 if (current_method->IsDefault()) {
1009 // Handle JLS soft errors, a default method from another superinterface tree can
1010 // "override" an abstract method(s) from another superinterface tree(s). To do this,
1011 // ignore any [default] method which are dominated by the abstract methods we've seen so
1012 // far. Check if overridden by any in abstract_methods. We do not need to check for
1013 // default_conflicts because we would hit those before we get to this loop.
1014 bool overridden = false;
1015 for (ArtMethod* possible_override : abstract_methods) {
1016 DCHECK(possible_override->HasSameNameAndSignature(current_method));
1017 if (iface->IsAssignableFrom(possible_override->GetDeclaringClass())) {
1018 overridden = true;
1019 break;
1020 }
1021 }
1022 if (!overridden) {
1023 return current_method;
1024 }
1025 } else {
1026 // Is not default.
1027 // This might override another default method. Just stash it for now.
1028 abstract_methods.push_back(current_method);
1029 }
1030 }
1031 }
1032 }
1033 // If we reach here we either never found any declaration of the method (in which case
1034 // 'abstract_methods' is empty or we found no non-overriden default methods in which case
1035 // 'abstract_methods' contains a number of abstract implementations of the methods. We choose one
1036 // of these arbitrarily.
1037 return abstract_methods.empty() ? nullptr : abstract_methods[0];
1038 }
1039
FindClassInitializer(PointerSize pointer_size)1040 ArtMethod* Class::FindClassInitializer(PointerSize pointer_size) {
1041 for (ArtMethod& method : GetDirectMethods(pointer_size)) {
1042 if (method.IsClassInitializer()) {
1043 DCHECK_STREQ(method.GetName(), "<clinit>");
1044 DCHECK_STREQ(method.GetSignature().ToString().c_str(), "()V");
1045 return &method;
1046 }
1047 }
1048 return nullptr;
1049 }
1050
FindFieldByNameAndType(const DexFile & dex_file,LengthPrefixedArray<ArtField> * fields,std::string_view name,std::string_view type)1051 static std::tuple<bool, ArtField*> FindFieldByNameAndType(const DexFile& dex_file,
1052 LengthPrefixedArray<ArtField>* fields,
1053 std::string_view name,
1054 std::string_view type)
1055 REQUIRES_SHARED(Locks::mutator_lock_) {
1056 DCHECK(fields != nullptr);
1057 DCHECK(!name.empty());
1058 DCHECK(!type.empty());
1059
1060 // Fields are sorted by class, then name, then type descriptor. This is verified in dex file
1061 // verifier. There can be multiple fields with the same name in the same class due to proguard.
1062 // Note: `std::string_view::compare()` uses lexicographical comparison and treats the `char`
1063 // as unsigned; for Modified-UTF-8 without embedded nulls this is consistent with the
1064 // `CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues()` ordering.
1065 auto get_field_id = [&](uint32_t mid) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE
1066 -> const dex::FieldId& {
1067 ArtField& field = fields->At(mid);
1068 DCHECK(field.GetDexFile() == &dex_file);
1069 return dex_file.GetFieldId(field.GetDexFieldIndex());
1070 };
1071 auto name_cmp = [&](uint32_t mid) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE {
1072 const dex::FieldId& field_id = get_field_id(mid);
1073 return DexFile::CompareMemberNames(name, dex_file.GetFieldNameView(field_id));
1074 };
1075 auto type_cmp = [&](uint32_t mid) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE {
1076 const dex::FieldId& field_id = get_field_id(mid);
1077 return DexFile::CompareDescriptors(
1078 type, dex_file.GetTypeDescriptorView(dex_file.GetTypeId(field_id.type_idx_)));
1079 };
1080 auto get_name_idx = [&](uint32_t mid) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE {
1081 const dex::FieldId& field_id = get_field_id(mid);
1082 return field_id.name_idx_;
1083 };
1084
1085 // Use binary search in the sorted fields.
1086 auto [success, mid] =
1087 ClassMemberBinarySearch(/*begin=*/ 0u, fields->size(), name_cmp, type_cmp, get_name_idx);
1088
1089 if (kIsDebugBuild) {
1090 ArtField* found = nullptr;
1091 for (ArtField& field : MakeIterationRangeFromLengthPrefixedArray(fields)) {
1092 if (name == field.GetName() && type == field.GetTypeDescriptor()) {
1093 found = &field;
1094 break;
1095 }
1096 }
1097
1098 ArtField* ret = success ? &fields->At(mid) : nullptr;
1099 CHECK_EQ(found, ret)
1100 << "Found " << ArtField::PrettyField(found) << " vs " << ArtField::PrettyField(ret);
1101 }
1102
1103 if (success) {
1104 return {true, &fields->At(mid)};
1105 }
1106
1107 return {false, nullptr};
1108 }
1109
FindDeclaredInstanceField(std::string_view name,std::string_view type)1110 ArtField* Class::FindDeclaredInstanceField(std::string_view name, std::string_view type) {
1111 // Binary search by name. Interfaces are not relevant because they can't contain instance fields.
1112 LengthPrefixedArray<ArtField>* ifields = GetIFieldsPtr();
1113 if (ifields == nullptr) {
1114 return nullptr;
1115 }
1116 DCHECK(!IsProxyClass());
1117 auto [success, field] = FindFieldByNameAndType(GetDexFile(), ifields, name, type);
1118 DCHECK_EQ(success, field != nullptr);
1119 return field;
1120 }
1121
FindDeclaredInstanceField(ObjPtr<DexCache> dex_cache,uint32_t dex_field_idx)1122 ArtField* Class::FindDeclaredInstanceField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx) {
1123 if (GetDexCache() == dex_cache) {
1124 for (ArtField& field : GetIFields()) {
1125 if (field.GetDexFieldIndex() == dex_field_idx) {
1126 return &field;
1127 }
1128 }
1129 }
1130 return nullptr;
1131 }
1132
FindInstanceField(std::string_view name,std::string_view type)1133 ArtField* Class::FindInstanceField(std::string_view name, std::string_view type) {
1134 // Is the field in this class, or any of its superclasses?
1135 // Interfaces are not relevant because they can't contain instance fields.
1136 for (ObjPtr<Class> c = this; c != nullptr; c = c->GetSuperClass()) {
1137 ArtField* f = c->FindDeclaredInstanceField(name, type);
1138 if (f != nullptr) {
1139 return f;
1140 }
1141 }
1142 return nullptr;
1143 }
1144
FindDeclaredStaticField(std::string_view name,std::string_view type)1145 ArtField* Class::FindDeclaredStaticField(std::string_view name, std::string_view type) {
1146 DCHECK(!type.empty());
1147 LengthPrefixedArray<ArtField>* sfields = GetSFieldsPtr();
1148 if (sfields == nullptr) {
1149 return nullptr;
1150 }
1151 if (UNLIKELY(IsProxyClass())) {
1152 // Proxy fields do not have appropriate dex field indexes required by
1153 // `FindFieldByNameAndType()`. However, each proxy class has exactly
1154 // the same artificial fields created by the `ClassLinker`.
1155 DCHECK_EQ(sfields->size(), 2u);
1156 DCHECK_EQ(strcmp(sfields->At(0).GetName(), "interfaces"), 0);
1157 DCHECK_EQ(strcmp(sfields->At(0).GetTypeDescriptor(), "[Ljava/lang/Class;"), 0);
1158 DCHECK_EQ(strcmp(sfields->At(1).GetName(), "throws"), 0);
1159 DCHECK_EQ(strcmp(sfields->At(1).GetTypeDescriptor(), "[[Ljava/lang/Class;"), 0);
1160 if (name == "interfaces") {
1161 return (type == "[Ljava/lang/Class;") ? &sfields->At(0) : nullptr;
1162 } else if (name == "throws") {
1163 return (type == "[[Ljava/lang/Class;") ? &sfields->At(1) : nullptr;
1164 } else {
1165 return nullptr;
1166 }
1167 }
1168 auto [success, field] = FindFieldByNameAndType(GetDexFile(), sfields, name, type);
1169 DCHECK_EQ(success, field != nullptr);
1170 return field;
1171 }
1172
FindDeclaredStaticField(ObjPtr<DexCache> dex_cache,uint32_t dex_field_idx)1173 ArtField* Class::FindDeclaredStaticField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx) {
1174 if (dex_cache == GetDexCache()) {
1175 for (ArtField& field : GetSFields()) {
1176 if (field.GetDexFieldIndex() == dex_field_idx) {
1177 return &field;
1178 }
1179 }
1180 }
1181 return nullptr;
1182 }
1183
GetDeclaredFields(Thread * self,bool public_only,bool force_resolve)1184 ObjPtr<mirror::ObjectArray<mirror::Field>> Class::GetDeclaredFields(
1185 Thread* self,
1186 bool public_only,
1187 bool force_resolve) REQUIRES_SHARED(Locks::mutator_lock_) {
1188 if (UNLIKELY(IsObsoleteObject())) {
1189 ThrowRuntimeException("Obsolete Object!");
1190 return nullptr;
1191 }
1192 StackHandleScope<1> hs(self);
1193 IterationRange<StrideIterator<ArtField>> ifields = GetIFields();
1194 IterationRange<StrideIterator<ArtField>> sfields = GetSFields();
1195 size_t array_size = NumInstanceFields() + NumStaticFields();
1196 auto hiddenapi_context = hiddenapi::GetReflectionCallerAccessContext(self);
1197 // Lets go subtract all the non discoverable fields.
1198 for (ArtField& field : ifields) {
1199 if (!IsDiscoverable(public_only, hiddenapi_context, &field)) {
1200 --array_size;
1201 }
1202 }
1203 for (ArtField& field : sfields) {
1204 if (!IsDiscoverable(public_only, hiddenapi_context, &field)) {
1205 --array_size;
1206 }
1207 }
1208 size_t array_idx = 0;
1209 auto object_array = hs.NewHandle(mirror::ObjectArray<mirror::Field>::Alloc(
1210 self, GetClassRoot<mirror::ObjectArray<mirror::Field>>(), array_size));
1211 if (object_array == nullptr) {
1212 return nullptr;
1213 }
1214 for (ArtField& field : ifields) {
1215 if (IsDiscoverable(public_only, hiddenapi_context, &field)) {
1216 ObjPtr<mirror::Field> reflect_field =
1217 mirror::Field::CreateFromArtField(self, &field, force_resolve);
1218 if (reflect_field == nullptr) {
1219 if (kIsDebugBuild) {
1220 self->AssertPendingException();
1221 }
1222 // Maybe null due to OOME or type resolving exception.
1223 return nullptr;
1224 }
1225 // We're initializing a newly allocated object, so we do not need to record that under
1226 // a transaction. If the transaction is aborted, the whole object shall be unreachable.
1227 object_array->SetWithoutChecks</*kTransactionActive=*/ false,
1228 /*kCheckTransaction=*/ false>(
1229 array_idx++, reflect_field);
1230 }
1231 }
1232 for (ArtField& field : sfields) {
1233 if (IsDiscoverable(public_only, hiddenapi_context, &field)) {
1234 ObjPtr<mirror::Field> reflect_field =
1235 mirror::Field::CreateFromArtField(self, &field, force_resolve);
1236 if (reflect_field == nullptr) {
1237 if (kIsDebugBuild) {
1238 self->AssertPendingException();
1239 }
1240 return nullptr;
1241 }
1242 // We're initializing a newly allocated object, so we do not need to record that under
1243 // a transaction. If the transaction is aborted, the whole object shall be unreachable.
1244 object_array->SetWithoutChecks</*kTransactionActive=*/ false,
1245 /*kCheckTransaction=*/ false>(
1246 array_idx++, reflect_field);
1247 }
1248 }
1249 DCHECK_EQ(array_idx, array_size);
1250 return object_array.Get();
1251 }
1252
FindStaticField(std::string_view name,std::string_view type)1253 ArtField* Class::FindStaticField(std::string_view name, std::string_view type) {
1254 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
1255 // Is the field in this class (or its interfaces), or any of its
1256 // superclasses (or their interfaces)?
1257 for (ObjPtr<Class> k = this; k != nullptr; k = k->GetSuperClass()) {
1258 // Is the field in this class?
1259 ArtField* f = k->FindDeclaredStaticField(name, type);
1260 if (f != nullptr) {
1261 return f;
1262 }
1263 // Is this field in any of this class' interfaces?
1264 for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
1265 ObjPtr<Class> interface = k->GetDirectInterface(i);
1266 DCHECK(interface != nullptr);
1267 f = interface->FindStaticField(name, type);
1268 if (f != nullptr) {
1269 return f;
1270 }
1271 }
1272 }
1273 return nullptr;
1274 }
1275
1276 // Find a field using the JLS field resolution order.
1277 // Template arguments can be used to limit the search to either static or instance fields.
1278 // The search should be limited only if we know that a full search would yield a field of
1279 // the right type or no field at all. This can be known for field references in a method
1280 // if we have previously verified that method and did not find a field type mismatch.
1281 template <bool kSearchInstanceFields, bool kSearchStaticFields>
1282 ALWAYS_INLINE
FindFieldImpl(ObjPtr<mirror::Class> klass,ObjPtr<mirror::DexCache> dex_cache,uint32_t field_idx)1283 ArtField* FindFieldImpl(ObjPtr<mirror::Class> klass,
1284 ObjPtr<mirror::DexCache> dex_cache,
1285 uint32_t field_idx) REQUIRES_SHARED(Locks::mutator_lock_) {
1286 static_assert(kSearchInstanceFields || kSearchStaticFields);
1287
1288 // FIXME: Hijacking a proxy class by a custom class loader can break this assumption.
1289 DCHECK(!klass->IsProxyClass());
1290
1291 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
1292
1293 // First try to find a declared field by `field_idx` if we have a `dex_cache` match.
1294 ObjPtr<DexCache> klass_dex_cache = klass->GetDexCache();
1295 if (klass_dex_cache == dex_cache) {
1296 // Lookup is always performed in the class referenced by the FieldId.
1297 DCHECK_EQ(klass->GetDexTypeIndex(),
1298 klass_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_);
1299 ArtField* f = kSearchInstanceFields
1300 ? klass->FindDeclaredInstanceField(klass_dex_cache, field_idx)
1301 : nullptr;
1302 if (kSearchStaticFields && f == nullptr) {
1303 f = klass->FindDeclaredStaticField(klass_dex_cache, field_idx);
1304 }
1305 if (f != nullptr) {
1306 return f;
1307 }
1308 }
1309
1310 const DexFile& dex_file = *dex_cache->GetDexFile();
1311 const dex::FieldId& field_id = dex_file.GetFieldId(field_idx);
1312
1313 std::string_view name; // Do not touch the dex file string data until actually needed.
1314 std::string_view type;
1315 auto ensure_name_and_type_initialized = [&]() REQUIRES_SHARED(Locks::mutator_lock_) {
1316 if (name.empty()) {
1317 name = dex_file.GetFieldNameView(field_id);
1318 type = dex_file.GetFieldTypeDescriptorView(field_id);
1319 }
1320 };
1321
1322 auto search_direct_interfaces = [&](ObjPtr<mirror::Class> k)
1323 REQUIRES_SHARED(Locks::mutator_lock_) {
1324 // TODO: The `FindStaticField()` performs a recursive search and it's possible to
1325 // construct interface hierarchies that make the time complexity exponential in depth.
1326 // Rewrite this with a `HashSet<mirror::Class*>` to mark classes we have already
1327 // searched for the field, so that we call `FindDeclaredStaticField()` only once
1328 // on each interface. And use a work queue to avoid unlimited recursion depth.
1329 // TODO: Once we call `FindDeclaredStaticField()` directly, use search by indexes
1330 // instead of strings if the interface's dex cache matches `dex_cache`. This shall
1331 // allow delaying the `ensure_name_and_type_initialized()` call further.
1332 uint32_t num_interfaces = k->NumDirectInterfaces();
1333 if (num_interfaces != 0u) {
1334 ensure_name_and_type_initialized();
1335 for (uint32_t i = 0; i != num_interfaces; ++i) {
1336 ObjPtr<Class> interface = k->GetDirectInterface(i);
1337 DCHECK(interface != nullptr);
1338 ArtField* f = interface->FindStaticField(name, type);
1339 if (f != nullptr) {
1340 return f;
1341 }
1342 }
1343 }
1344 return static_cast<ArtField*>(nullptr);
1345 };
1346
1347 auto find_field_by_name_and_type = [&](ObjPtr<mirror::Class> k, ObjPtr<DexCache> k_dex_cache)
1348 REQUIRES_SHARED(Locks::mutator_lock_) -> std::tuple<bool, ArtField*> {
1349 if ((!kSearchInstanceFields || k->GetIFieldsPtr() == nullptr) &&
1350 (!kSearchStaticFields || k->GetSFieldsPtr() == nullptr)) {
1351 return {false, nullptr};
1352 }
1353 ensure_name_and_type_initialized();
1354 const DexFile& k_dex_file = *k_dex_cache->GetDexFile();
1355 if (kSearchInstanceFields && k->GetIFieldsPtr() != nullptr) {
1356 auto [success, field] = FindFieldByNameAndType(k_dex_file, k->GetIFieldsPtr(), name, type);
1357 DCHECK_EQ(success, field != nullptr);
1358 if (success) {
1359 return {true, field};
1360 }
1361 }
1362 if (kSearchStaticFields && k->GetSFieldsPtr() != nullptr) {
1363 auto [success, field] = FindFieldByNameAndType(k_dex_file, k->GetSFieldsPtr(), name, type);
1364 DCHECK_EQ(success, field != nullptr);
1365 if (success) {
1366 return {true, field};
1367 }
1368 }
1369 return {false, nullptr};
1370 };
1371
1372 // If we had a dex cache mismatch, search declared fields by name and type.
1373 if (klass_dex_cache != dex_cache) {
1374 auto [success, field] = find_field_by_name_and_type(klass, klass_dex_cache);
1375 DCHECK_EQ(success, field != nullptr);
1376 if (success) {
1377 return field;
1378 }
1379 }
1380
1381 // Search direct interfaces for static fields.
1382 if (kSearchStaticFields) {
1383 ArtField* f = search_direct_interfaces(klass);
1384 if (f != nullptr) {
1385 return f;
1386 }
1387 }
1388
1389 // Continue searching in superclasses.
1390 for (ObjPtr<Class> k = klass->GetSuperClass(); k != nullptr; k = k->GetSuperClass()) {
1391 // Is the field in this class?
1392 ObjPtr<DexCache> k_dex_cache = k->GetDexCache();
1393 if (k_dex_cache == dex_cache) {
1394 // Matching dex_cache. We cannot compare the `field_idx` anymore because
1395 // the type index differs, so compare the name index and type index.
1396 if (kSearchInstanceFields) {
1397 for (ArtField& field : k->GetIFields()) {
1398 const dex::FieldId& other_field_id = dex_file.GetFieldId(field.GetDexFieldIndex());
1399 if (other_field_id.name_idx_ == field_id.name_idx_ &&
1400 other_field_id.type_idx_ == field_id.type_idx_) {
1401 return &field;
1402 }
1403 }
1404 }
1405 if (kSearchStaticFields) {
1406 for (ArtField& field : k->GetSFields()) {
1407 const dex::FieldId& other_field_id = dex_file.GetFieldId(field.GetDexFieldIndex());
1408 if (other_field_id.name_idx_ == field_id.name_idx_ &&
1409 other_field_id.type_idx_ == field_id.type_idx_) {
1410 return &field;
1411 }
1412 }
1413 }
1414 } else {
1415 auto [success, field] = find_field_by_name_and_type(k, k_dex_cache);
1416 DCHECK_EQ(success, field != nullptr);
1417 if (success) {
1418 return field;
1419 }
1420 }
1421 if (kSearchStaticFields) {
1422 // Is this field in any of this class' interfaces?
1423 ArtField* f = search_direct_interfaces(k);
1424 if (f != nullptr) {
1425 return f;
1426 }
1427 }
1428 }
1429 return nullptr;
1430 }
1431
1432 FLATTEN
FindField(ObjPtr<mirror::DexCache> dex_cache,uint32_t field_idx)1433 ArtField* Class::FindField(ObjPtr<mirror::DexCache> dex_cache, uint32_t field_idx) {
1434 return FindFieldImpl</*kSearchInstanceFields=*/ true,
1435 /*kSearchStaticFields*/ true>(this, dex_cache, field_idx);
1436 }
1437
1438 FLATTEN
FindInstanceField(ObjPtr<mirror::DexCache> dex_cache,uint32_t field_idx)1439 ArtField* Class::FindInstanceField(ObjPtr<mirror::DexCache> dex_cache, uint32_t field_idx) {
1440 return FindFieldImpl</*kSearchInstanceFields=*/ true,
1441 /*kSearchStaticFields*/ false>(this, dex_cache, field_idx);
1442 }
1443
1444 FLATTEN
FindStaticField(ObjPtr<mirror::DexCache> dex_cache,uint32_t field_idx)1445 ArtField* Class::FindStaticField(ObjPtr<mirror::DexCache> dex_cache, uint32_t field_idx) {
1446 return FindFieldImpl</*kSearchInstanceFields=*/ false,
1447 /*kSearchStaticFields*/ true>(this, dex_cache, field_idx);
1448 }
1449
ClearSkipAccessChecksFlagOnAllMethods(PointerSize pointer_size)1450 void Class::ClearSkipAccessChecksFlagOnAllMethods(PointerSize pointer_size) {
1451 DCHECK(IsVerified());
1452 for (auto& m : GetMethods(pointer_size)) {
1453 if (m.IsManagedAndInvokable()) {
1454 m.ClearSkipAccessChecks();
1455 }
1456 }
1457 }
1458
ClearMustCountLocksFlagOnAllMethods(PointerSize pointer_size)1459 void Class::ClearMustCountLocksFlagOnAllMethods(PointerSize pointer_size) {
1460 DCHECK(IsVerified());
1461 for (auto& m : GetMethods(pointer_size)) {
1462 if (m.IsManagedAndInvokable()) {
1463 m.ClearMustCountLocks();
1464 }
1465 }
1466 }
1467
ClearDontCompileFlagOnAllMethods(PointerSize pointer_size)1468 void Class::ClearDontCompileFlagOnAllMethods(PointerSize pointer_size) {
1469 DCHECK(IsVerified());
1470 for (auto& m : GetMethods(pointer_size)) {
1471 if (m.IsManagedAndInvokable()) {
1472 m.ClearDontCompile();
1473 }
1474 }
1475 }
1476
SetSkipAccessChecksFlagOnAllMethods(PointerSize pointer_size)1477 void Class::SetSkipAccessChecksFlagOnAllMethods(PointerSize pointer_size) {
1478 DCHECK(IsVerified());
1479 for (auto& m : GetMethods(pointer_size)) {
1480 // Copied methods that have code come from default interface methods. The
1481 // flag should be set on these copied methods at the point of copy, which is
1482 // after the interface has been verified.
1483 if (m.IsManagedAndInvokable() && !m.IsCopied()) {
1484 m.SetSkipAccessChecks();
1485 }
1486 }
1487 }
1488
GetDescriptor(std::string * storage)1489 const char* Class::GetDescriptor(std::string* storage) {
1490 size_t dim = 0u;
1491 ObjPtr<mirror::Class> klass = this;
1492 while (klass->IsArrayClass()) {
1493 ++dim;
1494 // No read barrier needed, we're reading a chain of constant references for comparison
1495 // with null. Then we follow up below with reading constant references to read constant
1496 // primitive data in both proxy and non-proxy paths. See ReadBarrierOption.
1497 klass = klass->GetComponentType<kDefaultVerifyFlags, kWithoutReadBarrier>();
1498 }
1499 if (klass->IsProxyClass()) {
1500 // No read barrier needed, the `name` field is constant for proxy classes and
1501 // the contents of the String are also constant. See ReadBarrierOption.
1502 ObjPtr<mirror::String> name = klass->GetName<kVerifyNone, kWithoutReadBarrier>();
1503 DCHECK(name != nullptr);
1504 *storage = DotToDescriptor(name->ToModifiedUtf8().c_str());
1505 } else {
1506 const char* descriptor;
1507 if (klass->IsPrimitive()) {
1508 descriptor = Primitive::Descriptor(klass->GetPrimitiveType());
1509 } else {
1510 const DexFile& dex_file = klass->GetDexFile();
1511 const dex::TypeId& type_id = dex_file.GetTypeId(klass->GetDexTypeIndex());
1512 descriptor = dex_file.GetTypeDescriptor(type_id);
1513 }
1514 if (dim == 0) {
1515 return descriptor;
1516 }
1517 *storage = descriptor;
1518 }
1519 storage->insert(0u, dim, '[');
1520 return storage->c_str();
1521 }
1522
GetClassDef()1523 const dex::ClassDef* Class::GetClassDef() {
1524 uint16_t class_def_idx = GetDexClassDefIndex();
1525 if (class_def_idx == DexFile::kDexNoIndex16) {
1526 return nullptr;
1527 }
1528 return &GetDexFile().GetClassDef(class_def_idx);
1529 }
1530
GetDirectInterfaceTypeIdx(uint32_t idx)1531 dex::TypeIndex Class::GetDirectInterfaceTypeIdx(uint32_t idx) {
1532 DCHECK(!IsPrimitive());
1533 DCHECK(!IsArrayClass());
1534 return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
1535 }
1536
GetDirectInterface(uint32_t idx)1537 ObjPtr<Class> Class::GetDirectInterface(uint32_t idx) {
1538 DCHECK(!IsPrimitive());
1539 if (IsArrayClass()) {
1540 ObjPtr<IfTable> iftable = GetIfTable();
1541 DCHECK(iftable != nullptr);
1542 DCHECK_EQ(iftable->Count(), 2u);
1543 DCHECK_LT(idx, 2u);
1544 ObjPtr<Class> interface = iftable->GetInterface(idx);
1545 DCHECK(interface != nullptr);
1546 return interface;
1547 } else if (IsProxyClass()) {
1548 ObjPtr<ObjectArray<Class>> interfaces = GetProxyInterfaces();
1549 DCHECK(interfaces != nullptr);
1550 return interfaces->Get(idx);
1551 } else {
1552 dex::TypeIndex type_idx = GetDirectInterfaceTypeIdx(idx);
1553 ObjPtr<Class> interface = Runtime::Current()->GetClassLinker()->LookupResolvedType(
1554 type_idx, GetDexCache(), GetClassLoader());
1555 return interface;
1556 }
1557 }
1558
ResolveDirectInterface(Thread * self,Handle<Class> klass,uint32_t idx)1559 ObjPtr<Class> Class::ResolveDirectInterface(Thread* self, Handle<Class> klass, uint32_t idx) {
1560 ObjPtr<Class> interface = klass->GetDirectInterface(idx);
1561 if (interface == nullptr) {
1562 DCHECK(!klass->IsArrayClass());
1563 DCHECK(!klass->IsProxyClass());
1564 dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx);
1565 interface = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, klass.Get());
1566 CHECK_IMPLIES(interface == nullptr, self->IsExceptionPending());
1567 }
1568 return interface;
1569 }
1570
GetCommonSuperClass(Handle<Class> klass)1571 ObjPtr<Class> Class::GetCommonSuperClass(Handle<Class> klass) {
1572 DCHECK(klass != nullptr);
1573 DCHECK(!klass->IsInterface());
1574 DCHECK(!IsInterface());
1575 ObjPtr<Class> common_super_class = this;
1576 while (!common_super_class->IsAssignableFrom(klass.Get())) {
1577 ObjPtr<Class> old_common = common_super_class;
1578 common_super_class = old_common->GetSuperClass();
1579 DCHECK(common_super_class != nullptr) << old_common->PrettyClass();
1580 }
1581 return common_super_class;
1582 }
1583
GetSourceFile()1584 const char* Class::GetSourceFile() {
1585 const DexFile& dex_file = GetDexFile();
1586 const dex::ClassDef* dex_class_def = GetClassDef();
1587 if (dex_class_def == nullptr) {
1588 // Generated classes have no class def.
1589 return nullptr;
1590 }
1591 return dex_file.GetSourceFile(*dex_class_def);
1592 }
1593
GetLocation()1594 std::string Class::GetLocation() {
1595 ObjPtr<DexCache> dex_cache = GetDexCache();
1596 if (dex_cache != nullptr && !IsProxyClass()) {
1597 return dex_cache->GetLocation()->ToModifiedUtf8();
1598 }
1599 // Arrays and proxies are generated and have no corresponding dex file location.
1600 return "generated class";
1601 }
1602
GetInterfaceTypeList()1603 const dex::TypeList* Class::GetInterfaceTypeList() {
1604 const dex::ClassDef* class_def = GetClassDef();
1605 if (class_def == nullptr) {
1606 return nullptr;
1607 }
1608 return GetDexFile().GetInterfacesList(*class_def);
1609 }
1610
PopulateEmbeddedVTable(PointerSize pointer_size)1611 void Class::PopulateEmbeddedVTable(PointerSize pointer_size) {
1612 ObjPtr<PointerArray> table = GetVTableDuringLinking();
1613 CHECK(table != nullptr) << PrettyClass();
1614 const size_t table_length = table->GetLength();
1615 SetEmbeddedVTableLength(table_length);
1616 for (size_t i = 0; i < table_length; i++) {
1617 SetEmbeddedVTableEntry(i, table->GetElementPtrSize<ArtMethod*>(i, pointer_size), pointer_size);
1618 }
1619 // Keep java.lang.Object class's vtable around for since it's easier
1620 // to be reused by array classes during their linking.
1621 if (!IsObjectClass()) {
1622 SetVTable(nullptr);
1623 }
1624 }
1625
1626 // Set the bitmap of reference instance field offsets.
PopulateReferenceOffsetBitmap()1627 void Class::PopulateReferenceOffsetBitmap() {
1628 size_t num_reference_fields;
1629 ObjPtr<mirror::Class> super_class;
1630 ObjPtr<Class> klass;
1631 // Find the first class with non-zero instance reference fields.
1632 for (klass = this; klass != nullptr; klass = super_class) {
1633 super_class = klass->GetSuperClass();
1634 num_reference_fields = klass->NumReferenceInstanceFieldsDuringLinking();
1635 if (num_reference_fields != 0) {
1636 break;
1637 }
1638 }
1639
1640 uint32_t ref_offsets = 0;
1641 // Leave the reference offsets as 0 for mirror::Object (the class field is handled specially).
1642 if (super_class != nullptr) {
1643 // All of the reference fields added by this class are guaranteed to be grouped in memory
1644 // starting at an appropriately aligned address after super class object data.
1645 uint32_t start_offset =
1646 RoundUp(super_class->GetObjectSize(), sizeof(mirror::HeapReference<mirror::Object>));
1647 uint32_t start_bit =
1648 (start_offset - mirror::kObjectHeaderSize) / sizeof(mirror::HeapReference<mirror::Object>);
1649 uint32_t end_bit = start_bit + num_reference_fields;
1650 bool overflowing = end_bit > 31;
1651 uint32_t* overflow_bitmap; // Pointer to the last word of overflow bitmap to be written into.
1652 uint32_t overflow_words_to_write; // Number of overflow bitmap words remaining to write.
1653 // Index in 'overflow_bitmap' from where to start writing bitmap words (in reverse order).
1654 int32_t overflow_bitmap_word_idx;
1655 if (overflowing) {
1656 // We will write overflow bitmap in reverse.
1657 overflow_bitmap =
1658 reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(this) + GetClassSize());
1659 DCHECK_ALIGNED(overflow_bitmap, sizeof(uint32_t));
1660 overflow_bitmap_word_idx = 0;
1661 overflow_words_to_write = RoundUp(end_bit, 32) / 32;
1662 }
1663 // TODO: Simplify by copying the bitmap from the super-class and then
1664 // appending the reference fields added by this class.
1665 while (true) {
1666 if (UNLIKELY(overflowing)) {
1667 // Write all the bitmap words which got skipped between previous
1668 // super-class and the current one.
1669 for (uint32_t new_words_to_write = RoundUp(end_bit, 32) / 32;
1670 overflow_words_to_write > new_words_to_write;
1671 overflow_words_to_write--) {
1672 overflow_bitmap[--overflow_bitmap_word_idx] = ref_offsets;
1673 ref_offsets = 0;
1674 }
1675 // Handle the references in the current super-class.
1676 if (num_reference_fields != 0u) {
1677 uint32_t aligned_end_bit = RoundDown(end_bit, 32);
1678 uint32_t aligned_start_bit = RoundUp(start_bit, 32);
1679 // Handle the case where a class' references are spanning across multiple 32-bit
1680 // words of the overflow bitmap.
1681 if (aligned_end_bit >= aligned_start_bit) {
1682 // handle the unaligned end first
1683 if (aligned_end_bit < end_bit) {
1684 ref_offsets |= 0xffffffffu >> (32 - (end_bit - aligned_end_bit));
1685 overflow_bitmap[--overflow_bitmap_word_idx] = ref_offsets;
1686 overflow_words_to_write--;
1687 ref_offsets = 0;
1688 }
1689 // store all the 32-bit bitmap words in between
1690 for (; aligned_end_bit > aligned_start_bit; aligned_end_bit -= 32) {
1691 overflow_bitmap[--overflow_bitmap_word_idx] = 0xffffffffu;
1692 overflow_words_to_write--;
1693 }
1694 CHECK_EQ(ref_offsets, 0u);
1695 // handle the unaligned start now
1696 if (aligned_start_bit > start_bit) {
1697 ref_offsets = 0xffffffffu << (32 - (aligned_start_bit - start_bit));
1698 }
1699 } else {
1700 DCHECK_EQ(aligned_start_bit - aligned_end_bit, 32u);
1701 ref_offsets |= (0xffffffffu << (32 - (aligned_start_bit - start_bit))) &
1702 (0xffffffffu >> (32 - (end_bit - aligned_end_bit)));
1703 }
1704 }
1705 } else if (num_reference_fields != 0u) {
1706 ref_offsets |= (0xffffffffu << start_bit) & (0xffffffffu >> (32 - end_bit));
1707 }
1708
1709 klass = super_class;
1710 super_class = klass->GetSuperClass();
1711 if (super_class == nullptr) {
1712 break;
1713 }
1714 num_reference_fields = klass->NumReferenceInstanceFieldsDuringLinking();
1715 start_offset =
1716 RoundUp(super_class->GetObjectSize(), sizeof(mirror::HeapReference<mirror::Object>));
1717 start_bit = (start_offset - mirror::kObjectHeaderSize) /
1718 sizeof(mirror::HeapReference<mirror::Object>);
1719 end_bit = start_bit + num_reference_fields;
1720 }
1721 if (overflowing) {
1722 // We should not have more than one word left to write in the overflow bitmap.
1723 DCHECK_LE(overflow_words_to_write, 1u)
1724 << "overflow_bitmap_word_idx:" << -overflow_bitmap_word_idx;
1725 if (overflow_words_to_write > 0) {
1726 overflow_bitmap[--overflow_bitmap_word_idx] = ref_offsets;
1727 }
1728 ref_offsets = -overflow_bitmap_word_idx | kVisitReferencesSlowpathMask;
1729 }
1730 }
1731 SetReferenceInstanceOffsets(ref_offsets);
1732 }
1733
1734 class ReadBarrierOnNativeRootsVisitor {
1735 public:
operator ()(ObjPtr<Object> obj,MemberOffset offset,bool is_static) const1736 void operator()([[maybe_unused]] ObjPtr<Object> obj,
1737 [[maybe_unused]] MemberOffset offset,
1738 [[maybe_unused]] bool is_static) const {}
1739
VisitRootIfNonNull(CompressedReference<Object> * root) const1740 void VisitRootIfNonNull(CompressedReference<Object>* root) const
1741 REQUIRES_SHARED(Locks::mutator_lock_) {
1742 if (!root->IsNull()) {
1743 VisitRoot(root);
1744 }
1745 }
1746
VisitRoot(CompressedReference<Object> * root) const1747 void VisitRoot(CompressedReference<Object>* root) const
1748 REQUIRES_SHARED(Locks::mutator_lock_) {
1749 ObjPtr<Object> old_ref = root->AsMirrorPtr();
1750 ObjPtr<Object> new_ref = ReadBarrier::BarrierForRoot(root);
1751 if (old_ref != new_ref) {
1752 // Update the field atomically. This may fail if mutator updates before us, but it's ok.
1753 auto* atomic_root =
1754 reinterpret_cast<Atomic<CompressedReference<Object>>*>(root);
1755 atomic_root->CompareAndSetStrongSequentiallyConsistent(
1756 CompressedReference<Object>::FromMirrorPtr(old_ref.Ptr()),
1757 CompressedReference<Object>::FromMirrorPtr(new_ref.Ptr()));
1758 }
1759 }
1760 };
1761
1762 // The pre-fence visitor for Class::CopyOf().
1763 class CopyClassVisitor {
1764 public:
CopyClassVisitor(Thread * self,Handle<Class> * orig,size_t new_length,size_t copy_bytes,ImTable * imt,PointerSize pointer_size)1765 CopyClassVisitor(Thread* self,
1766 Handle<Class>* orig,
1767 size_t new_length,
1768 size_t copy_bytes,
1769 ImTable* imt,
1770 PointerSize pointer_size)
1771 : self_(self), orig_(orig), new_length_(new_length),
1772 copy_bytes_(copy_bytes), imt_(imt), pointer_size_(pointer_size) {
1773 }
1774
operator ()(ObjPtr<Object> obj,size_t usable_size) const1775 void operator()(ObjPtr<Object> obj, [[maybe_unused]] size_t usable_size) const
1776 REQUIRES_SHARED(Locks::mutator_lock_) {
1777 StackHandleScope<1> hs(self_);
1778 Handle<mirror::Class> h_new_class_obj(hs.NewHandle(obj->AsClass()));
1779 Object::CopyObject(h_new_class_obj.Get(), orig_->Get(), copy_bytes_);
1780 Class::SetStatus(h_new_class_obj, ClassStatus::kResolving, self_);
1781 h_new_class_obj->PopulateEmbeddedVTable(pointer_size_);
1782 h_new_class_obj->SetImt(imt_, pointer_size_);
1783 h_new_class_obj->SetClassSize(new_length_);
1784 h_new_class_obj->PopulateReferenceOffsetBitmap();
1785 // Visit all of the references to make sure there is no from space references in the native
1786 // roots.
1787 h_new_class_obj->Object::VisitReferences(ReadBarrierOnNativeRootsVisitor(), VoidFunctor());
1788 }
1789
1790 private:
1791 Thread* const self_;
1792 Handle<Class>* const orig_;
1793 const size_t new_length_;
1794 const size_t copy_bytes_;
1795 ImTable* imt_;
1796 const PointerSize pointer_size_;
1797 DISALLOW_COPY_AND_ASSIGN(CopyClassVisitor);
1798 };
1799
CopyOf(Handle<Class> h_this,Thread * self,int32_t new_length,ImTable * imt,PointerSize pointer_size)1800 ObjPtr<Class> Class::CopyOf(Handle<Class> h_this,
1801 Thread* self,
1802 int32_t new_length,
1803 ImTable* imt,
1804 PointerSize pointer_size) {
1805 DCHECK_GE(new_length, static_cast<int32_t>(sizeof(Class)));
1806 // We may get copied by a compacting GC.
1807 Runtime* runtime = Runtime::Current();
1808 gc::Heap* heap = runtime->GetHeap();
1809 // The num_bytes (3rd param) is sizeof(Class) as opposed to SizeOf()
1810 // to skip copying the tail part that we will overwrite here.
1811 CopyClassVisitor visitor(self, &h_this, new_length, sizeof(Class), imt, pointer_size);
1812 ObjPtr<mirror::Class> java_lang_Class = GetClassRoot<mirror::Class>(runtime->GetClassLinker());
1813 ObjPtr<Object> new_class = kMovingClasses ?
1814 heap->AllocObject(self, java_lang_Class, new_length, visitor) :
1815 heap->AllocNonMovableObject(self, java_lang_Class, new_length, visitor);
1816 if (UNLIKELY(new_class == nullptr)) {
1817 self->AssertPendingOOMException();
1818 return nullptr;
1819 }
1820 return new_class->AsClass();
1821 }
1822
DescriptorEquals(ObjPtr<mirror::Class> match)1823 bool Class::DescriptorEquals(ObjPtr<mirror::Class> match) {
1824 DCHECK(match != nullptr);
1825 ObjPtr<mirror::Class> klass = this;
1826 while (klass->IsArrayClass()) {
1827 // No read barrier needed, we're reading a chain of constant references for comparison
1828 // with null. Then we follow up below with reading constant references to read constant
1829 // primitive data in both proxy and non-proxy paths. See ReadBarrierOption.
1830 klass = klass->GetComponentType<kDefaultVerifyFlags, kWithoutReadBarrier>();
1831 DCHECK(klass != nullptr);
1832 match = match->GetComponentType<kDefaultVerifyFlags, kWithoutReadBarrier>();
1833 if (match == nullptr){
1834 return false;
1835 }
1836 }
1837 if (match->IsArrayClass()) {
1838 return false;
1839 }
1840
1841 if (UNLIKELY(klass->IsPrimitive()) || UNLIKELY(match->IsPrimitive())) {
1842 return klass->GetPrimitiveType() == match->GetPrimitiveType();
1843 }
1844
1845 if (UNLIKELY(klass->IsProxyClass())) {
1846 return klass->ProxyDescriptorEquals(match);
1847 }
1848 if (UNLIKELY(match->IsProxyClass())) {
1849 return match->ProxyDescriptorEquals(klass);
1850 }
1851
1852 const DexFile& klass_dex_file = klass->GetDexFile();
1853 const DexFile& match_dex_file = match->GetDexFile();
1854 dex::TypeIndex klass_type_index = klass->GetDexTypeIndex();
1855 dex::TypeIndex match_type_index = match->GetDexTypeIndex();
1856 if (&klass_dex_file == &match_dex_file) {
1857 return klass_type_index == match_type_index;
1858 }
1859 std::string_view klass_descriptor = klass_dex_file.GetTypeDescriptorView(klass_type_index);
1860 std::string_view match_descriptor = match_dex_file.GetTypeDescriptorView(match_type_index);
1861 return klass_descriptor == match_descriptor;
1862 }
1863
ProxyDescriptorEquals(ObjPtr<mirror::Class> match)1864 bool Class::ProxyDescriptorEquals(ObjPtr<mirror::Class> match) {
1865 DCHECK(IsProxyClass());
1866 ObjPtr<mirror::String> name = GetName<kVerifyNone, kWithoutReadBarrier>();
1867 DCHECK(name != nullptr);
1868
1869 DCHECK(match != nullptr);
1870 DCHECK(!match->IsArrayClass());
1871 DCHECK(!match->IsPrimitive());
1872 if (match->IsProxyClass()) {
1873 ObjPtr<mirror::String> match_name = match->GetName<kVerifyNone, kWithoutReadBarrier>();
1874 DCHECK(name != nullptr);
1875 return name->Equals(match_name);
1876 }
1877
1878 // Note: Proxy descriptor should never match a non-proxy descriptor but ART does not enforce that.
1879 std::string descriptor = DotToDescriptor(name->ToModifiedUtf8().c_str());
1880 std::string_view match_descriptor =
1881 match->GetDexFile().GetTypeDescriptorView(match->GetDexTypeIndex());
1882 return descriptor == match_descriptor;
1883 }
1884
ProxyDescriptorEquals(std::string_view match)1885 bool Class::ProxyDescriptorEquals(std::string_view match) {
1886 DCHECK(IsProxyClass());
1887 std::string storage;
1888 const char* descriptor = GetDescriptor(&storage);
1889 DCHECK(descriptor == storage.c_str());
1890 return storage == match;
1891 }
1892
UpdateHashForProxyClass(uint32_t hash,ObjPtr<mirror::Class> proxy_class)1893 uint32_t Class::UpdateHashForProxyClass(uint32_t hash, ObjPtr<mirror::Class> proxy_class) {
1894 // No read barrier needed, the `name` field is constant for proxy classes and
1895 // the contents of the String are also constant. See ReadBarrierOption.
1896 // Note: The `proxy_class` can be a from-space reference.
1897 DCHECK(proxy_class->IsProxyClass());
1898 ObjPtr<mirror::String> name = proxy_class->GetName<kVerifyNone, kWithoutReadBarrier>();
1899 DCHECK(name != nullptr);
1900 // Update hash for characters we would get from `DotToDescriptor(name->ToModifiedUtf8())`.
1901 DCHECK_NE(name->GetLength(), 0);
1902 DCHECK_NE(name->CharAt(0), '[');
1903 hash = UpdateModifiedUtf8Hash(hash, 'L');
1904 if (name->IsCompressed()) {
1905 std::string_view dot_name(reinterpret_cast<const char*>(name->GetValueCompressed()),
1906 name->GetLength());
1907 for (char c : dot_name) {
1908 hash = UpdateModifiedUtf8Hash(hash, (c != '.') ? c : '/');
1909 }
1910 } else {
1911 std::string dot_name = name->ToModifiedUtf8();
1912 for (char c : dot_name) {
1913 hash = UpdateModifiedUtf8Hash(hash, (c != '.') ? c : '/');
1914 }
1915 }
1916 hash = UpdateModifiedUtf8Hash(hash, ';');
1917 return hash;
1918 }
1919
1920 // TODO: Move this to java_lang_Class.cc?
GetDeclaredConstructor(Thread * self,Handle<ObjectArray<Class>> args,PointerSize pointer_size)1921 ArtMethod* Class::GetDeclaredConstructor(
1922 Thread* self, Handle<ObjectArray<Class>> args, PointerSize pointer_size) {
1923 for (auto& m : GetDirectMethods(pointer_size)) {
1924 // Skip <clinit> which is a static constructor, as well as non constructors.
1925 if (m.IsStatic() || !m.IsConstructor()) {
1926 continue;
1927 }
1928 // May cause thread suspension and exceptions.
1929 if (m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->EqualParameters(args)) {
1930 return &m;
1931 }
1932 if (UNLIKELY(self->IsExceptionPending())) {
1933 return nullptr;
1934 }
1935 }
1936 return nullptr;
1937 }
1938
Depth()1939 uint32_t Class::Depth() {
1940 uint32_t depth = 0;
1941 for (ObjPtr<Class> cls = this; cls->GetSuperClass() != nullptr; cls = cls->GetSuperClass()) {
1942 depth++;
1943 }
1944 return depth;
1945 }
1946
FindTypeIndexInOtherDexFile(const DexFile & dex_file)1947 dex::TypeIndex Class::FindTypeIndexInOtherDexFile(const DexFile& dex_file) {
1948 std::string_view descriptor;
1949 std::optional<std::string> temp;
1950 if (IsPrimitive() || IsArrayClass() || IsProxyClass()) {
1951 temp.emplace();
1952 descriptor = GetDescriptor(&temp.value());
1953 } else {
1954 descriptor = GetDescriptorView();
1955 }
1956 const dex::TypeId* type_id = dex_file.FindTypeId(descriptor);
1957 return (type_id == nullptr) ? dex::TypeIndex() : dex_file.GetIndexForTypeId(*type_id);
1958 }
1959
1960 ALWAYS_INLINE
IsMethodPreferredOver(ArtMethod * orig_method,bool orig_method_hidden,ArtMethod * new_method,bool new_method_hidden)1961 static bool IsMethodPreferredOver(ArtMethod* orig_method,
1962 bool orig_method_hidden,
1963 ArtMethod* new_method,
1964 bool new_method_hidden) {
1965 DCHECK(new_method != nullptr);
1966
1967 // Is this the first result?
1968 if (orig_method == nullptr) {
1969 return true;
1970 }
1971
1972 // Original method is hidden, the new one is not?
1973 if (orig_method_hidden && !new_method_hidden) {
1974 return true;
1975 }
1976
1977 // We iterate over virtual methods first and then over direct ones,
1978 // so we can never be in situation where `orig_method` is direct and
1979 // `new_method` is virtual.
1980 DCHECK_IMPLIES(orig_method->IsDirect(), new_method->IsDirect());
1981
1982 // Original method is synthetic, the new one is not?
1983 if (orig_method->IsSynthetic() && !new_method->IsSynthetic()) {
1984 return true;
1985 }
1986
1987 return false;
1988 }
1989
1990 template <PointerSize kPointerSize>
GetDeclaredMethodInternal(Thread * self,ObjPtr<Class> klass,ObjPtr<String> name,ObjPtr<ObjectArray<Class>> args,const std::function<hiddenapi::AccessContext ()> & fn_get_access_context)1991 ObjPtr<Method> Class::GetDeclaredMethodInternal(
1992 Thread* self,
1993 ObjPtr<Class> klass,
1994 ObjPtr<String> name,
1995 ObjPtr<ObjectArray<Class>> args,
1996 const std::function<hiddenapi::AccessContext()>& fn_get_access_context) {
1997 // Covariant return types (or smali) permit the class to define
1998 // multiple methods with the same name and parameter types.
1999 // Prefer (in decreasing order of importance):
2000 // 1) non-hidden method over hidden
2001 // 2) virtual methods over direct
2002 // 3) non-synthetic methods over synthetic
2003 // We never return miranda methods that were synthesized by the runtime.
2004 StackHandleScope<3> hs(self);
2005 auto h_method_name = hs.NewHandle(name);
2006 if (UNLIKELY(h_method_name == nullptr)) {
2007 ThrowNullPointerException("name == null");
2008 return nullptr;
2009 }
2010 auto h_args = hs.NewHandle(args);
2011 Handle<Class> h_klass = hs.NewHandle(klass);
2012 constexpr hiddenapi::AccessMethod access_method = hiddenapi::AccessMethod::kNone;
2013 ArtMethod* result = nullptr;
2014 bool result_hidden = false;
2015 for (auto& m : h_klass->GetDeclaredVirtualMethods(kPointerSize)) {
2016 if (m.IsMiranda()) {
2017 continue;
2018 }
2019 ArtMethod* np_method = m.GetInterfaceMethodIfProxy(kPointerSize);
2020 if (!np_method->NameEquals(h_method_name.Get())) {
2021 continue;
2022 }
2023 // `ArtMethod::EqualParameters()` may throw when resolving types.
2024 if (!np_method->EqualParameters(h_args)) {
2025 if (UNLIKELY(self->IsExceptionPending())) {
2026 return nullptr;
2027 }
2028 continue;
2029 }
2030 bool m_hidden = hiddenapi::ShouldDenyAccessToMember(&m, fn_get_access_context, access_method);
2031 if (!m_hidden && !m.IsSynthetic()) {
2032 // Non-hidden, virtual, non-synthetic. Best possible result, exit early.
2033 return Method::CreateFromArtMethod<kPointerSize>(self, &m);
2034 } else if (IsMethodPreferredOver(result, result_hidden, &m, m_hidden)) {
2035 // Remember as potential result.
2036 result = &m;
2037 result_hidden = m_hidden;
2038 }
2039 }
2040
2041 if ((result != nullptr) && !result_hidden) {
2042 // We have not found a non-hidden, virtual, non-synthetic method, but
2043 // if we have found a non-hidden, virtual, synthetic method, we cannot
2044 // do better than that later.
2045 DCHECK(!result->IsDirect());
2046 DCHECK(result->IsSynthetic());
2047 } else {
2048 for (auto& m : h_klass->GetDirectMethods(kPointerSize)) {
2049 auto modifiers = m.GetAccessFlags();
2050 if ((modifiers & kAccConstructor) != 0) {
2051 continue;
2052 }
2053 ArtMethod* np_method = m.GetInterfaceMethodIfProxy(kPointerSize);
2054 if (!np_method->NameEquals(h_method_name.Get())) {
2055 continue;
2056 }
2057 // `ArtMethod::EqualParameters()` may throw when resolving types.
2058 if (!np_method->EqualParameters(h_args)) {
2059 if (UNLIKELY(self->IsExceptionPending())) {
2060 return nullptr;
2061 }
2062 continue;
2063 }
2064 DCHECK(!m.IsMiranda()); // Direct methods cannot be miranda methods.
2065 bool m_hidden = hiddenapi::ShouldDenyAccessToMember(&m, fn_get_access_context, access_method);
2066 if (!m_hidden && !m.IsSynthetic()) {
2067 // Non-hidden, direct, non-synthetic. Any virtual result could only have been
2068 // hidden, therefore this is the best possible match. Exit now.
2069 DCHECK((result == nullptr) || result_hidden);
2070 return Method::CreateFromArtMethod<kPointerSize>(self, &m);
2071 } else if (IsMethodPreferredOver(result, result_hidden, &m, m_hidden)) {
2072 // Remember as potential result.
2073 result = &m;
2074 result_hidden = m_hidden;
2075 }
2076 }
2077 }
2078
2079 return result != nullptr
2080 ? Method::CreateFromArtMethod<kPointerSize>(self, result)
2081 : nullptr;
2082 }
2083
2084 template
2085 ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k32>(
2086 Thread* self,
2087 ObjPtr<Class> klass,
2088 ObjPtr<String> name,
2089 ObjPtr<ObjectArray<Class>> args,
2090 const std::function<hiddenapi::AccessContext()>& fn_get_access_context);
2091 template
2092 ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k64>(
2093 Thread* self,
2094 ObjPtr<Class> klass,
2095 ObjPtr<String> name,
2096 ObjPtr<ObjectArray<Class>> args,
2097 const std::function<hiddenapi::AccessContext()>& fn_get_access_context);
2098
2099 template <PointerSize kPointerSize>
GetDeclaredConstructorInternal(Thread * self,ObjPtr<Class> klass,ObjPtr<ObjectArray<Class>> args)2100 ObjPtr<Constructor> Class::GetDeclaredConstructorInternal(
2101 Thread* self,
2102 ObjPtr<Class> klass,
2103 ObjPtr<ObjectArray<Class>> args) {
2104 StackHandleScope<1> hs(self);
2105 ArtMethod* result = klass->GetDeclaredConstructor(self, hs.NewHandle(args), kPointerSize);
2106 return result != nullptr
2107 ? Constructor::CreateFromArtMethod<kPointerSize>(self, result)
2108 : nullptr;
2109 }
2110
2111 // Constructor::CreateFromArtMethod<kTransactionActive>(self, result)
2112
2113 template
2114 ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k32>(
2115 Thread* self,
2116 ObjPtr<Class> klass,
2117 ObjPtr<ObjectArray<Class>> args);
2118 template
2119 ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k64>(
2120 Thread* self,
2121 ObjPtr<Class> klass,
2122 ObjPtr<ObjectArray<Class>> args);
2123
GetInnerClassFlags(Handle<Class> h_this,int32_t default_value)2124 int32_t Class::GetInnerClassFlags(Handle<Class> h_this, int32_t default_value) {
2125 if (h_this->IsProxyClass() || h_this->GetDexCache() == nullptr) {
2126 return default_value;
2127 }
2128 uint32_t flags;
2129 if (!annotations::GetInnerClassFlags(h_this, &flags)) {
2130 return default_value;
2131 }
2132 return flags;
2133 }
2134
SetObjectSizeAllocFastPath(uint32_t new_object_size)2135 void Class::SetObjectSizeAllocFastPath(uint32_t new_object_size) {
2136 if (Runtime::Current()->IsActiveTransaction()) {
2137 SetField32Volatile<true>(ObjectSizeAllocFastPathOffset(), new_object_size);
2138 } else {
2139 SetField32Volatile<false>(ObjectSizeAllocFastPathOffset(), new_object_size);
2140 }
2141 }
2142
PrettyDescriptor(ObjPtr<mirror::Class> klass)2143 std::string Class::PrettyDescriptor(ObjPtr<mirror::Class> klass) {
2144 if (klass == nullptr) {
2145 return "null";
2146 }
2147 return klass->PrettyDescriptor();
2148 }
2149
PrettyDescriptor()2150 std::string Class::PrettyDescriptor() {
2151 std::string temp;
2152 return art::PrettyDescriptor(GetDescriptor(&temp));
2153 }
2154
PrettyClass(ObjPtr<mirror::Class> c)2155 std::string Class::PrettyClass(ObjPtr<mirror::Class> c) {
2156 if (c == nullptr) {
2157 return "null";
2158 }
2159 return c->PrettyClass();
2160 }
2161
PrettyClass()2162 std::string Class::PrettyClass() {
2163 std::string result;
2164 if (IsObsoleteObject()) {
2165 result += "(Obsolete)";
2166 }
2167 if (IsRetired()) {
2168 result += "(Retired)";
2169 }
2170 result += "java.lang.Class<";
2171 result += PrettyDescriptor();
2172 result += ">";
2173 return result;
2174 }
2175
PrettyClassAndClassLoader(ObjPtr<mirror::Class> c)2176 std::string Class::PrettyClassAndClassLoader(ObjPtr<mirror::Class> c) {
2177 if (c == nullptr) {
2178 return "null";
2179 }
2180 return c->PrettyClassAndClassLoader();
2181 }
2182
PrettyClassAndClassLoader()2183 std::string Class::PrettyClassAndClassLoader() {
2184 std::string result;
2185 result += "java.lang.Class<";
2186 result += PrettyDescriptor();
2187 result += ",";
2188 result += mirror::Object::PrettyTypeOf(GetClassLoader());
2189 // TODO: add an identifying hash value for the loader
2190 result += ">";
2191 return result;
2192 }
2193
GetAccessFlagsDCheck()2194 template<VerifyObjectFlags kVerifyFlags> void Class::GetAccessFlagsDCheck() {
2195 // Check class is loaded/retired or this is java.lang.String that has a
2196 // circularity issue during loading the names of its members
2197 DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
2198 IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
2199 this == GetClassRoot<String>())
2200 << "IsIdxLoaded=" << IsIdxLoaded<kVerifyFlags>()
2201 << " IsRetired=" << IsRetired<kVerifyFlags>()
2202 << " IsErroneous=" <<
2203 IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>()
2204 << " IsString=" << (this == GetClassRoot<String>())
2205 << " status= " << GetStatus<kVerifyFlags>()
2206 << " descriptor=" << PrettyDescriptor();
2207 }
2208 // Instantiate the common cases.
2209 template void Class::GetAccessFlagsDCheck<kVerifyNone>();
2210 template void Class::GetAccessFlagsDCheck<kVerifyThis>();
2211 template void Class::GetAccessFlagsDCheck<kVerifyReads>();
2212 template void Class::GetAccessFlagsDCheck<kVerifyWrites>();
2213 template void Class::GetAccessFlagsDCheck<kVerifyAll>();
2214
GetMethodIds()2215 ObjPtr<Object> Class::GetMethodIds() {
2216 ObjPtr<ClassExt> ext(GetExtData());
2217 if (ext.IsNull()) {
2218 return nullptr;
2219 } else {
2220 return ext->GetJMethodIDs();
2221 }
2222 }
EnsureMethodIds(Handle<Class> h_this)2223 bool Class::EnsureMethodIds(Handle<Class> h_this) {
2224 DCHECK_NE(Runtime::Current()->GetJniIdType(), JniIdType::kPointer) << "JNI Ids are pointers!";
2225 Thread* self = Thread::Current();
2226 ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self));
2227 if (ext.IsNull()) {
2228 self->AssertPendingOOMException();
2229 return false;
2230 }
2231 return ext->EnsureJMethodIDsArrayPresent(h_this->NumMethods());
2232 }
2233
GetStaticFieldIds()2234 ObjPtr<Object> Class::GetStaticFieldIds() {
2235 ObjPtr<ClassExt> ext(GetExtData());
2236 if (ext.IsNull()) {
2237 return nullptr;
2238 } else {
2239 return ext->GetStaticJFieldIDs();
2240 }
2241 }
EnsureStaticFieldIds(Handle<Class> h_this)2242 bool Class::EnsureStaticFieldIds(Handle<Class> h_this) {
2243 DCHECK_NE(Runtime::Current()->GetJniIdType(), JniIdType::kPointer) << "JNI Ids are pointers!";
2244 Thread* self = Thread::Current();
2245 ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self));
2246 if (ext.IsNull()) {
2247 self->AssertPendingOOMException();
2248 return false;
2249 }
2250 return ext->EnsureStaticJFieldIDsArrayPresent(h_this->NumStaticFields());
2251 }
GetInstanceFieldIds()2252 ObjPtr<Object> Class::GetInstanceFieldIds() {
2253 ObjPtr<ClassExt> ext(GetExtData());
2254 if (ext.IsNull()) {
2255 return nullptr;
2256 } else {
2257 return ext->GetInstanceJFieldIDs();
2258 }
2259 }
EnsureInstanceFieldIds(Handle<Class> h_this)2260 bool Class::EnsureInstanceFieldIds(Handle<Class> h_this) {
2261 DCHECK_NE(Runtime::Current()->GetJniIdType(), JniIdType::kPointer) << "JNI Ids are pointers!";
2262 Thread* self = Thread::Current();
2263 ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self));
2264 if (ext.IsNull()) {
2265 self->AssertPendingOOMException();
2266 return false;
2267 }
2268 return ext->EnsureInstanceJFieldIDsArrayPresent(h_this->NumInstanceFields());
2269 }
2270
GetStaticFieldIdOffset(ArtField * field)2271 size_t Class::GetStaticFieldIdOffset(ArtField* field) {
2272 DCHECK_LT(reinterpret_cast<uintptr_t>(field),
2273 reinterpret_cast<uintptr_t>(&*GetSFieldsPtr()->end()))
2274 << "field not part of the current class. " << field->PrettyField() << " class is "
2275 << PrettyClass();
2276 DCHECK_GE(reinterpret_cast<uintptr_t>(field),
2277 reinterpret_cast<uintptr_t>(&*GetSFieldsPtr()->begin()))
2278 << "field not part of the current class. " << field->PrettyField() << " class is "
2279 << PrettyClass();
2280 uintptr_t start = reinterpret_cast<uintptr_t>(&GetSFieldsPtr()->At(0));
2281 uintptr_t fld = reinterpret_cast<uintptr_t>(field);
2282 size_t res = (fld - start) / sizeof(ArtField);
2283 DCHECK_EQ(&GetSFieldsPtr()->At(res), field)
2284 << "Incorrect field computation expected: " << field->PrettyField()
2285 << " got: " << GetSFieldsPtr()->At(res).PrettyField();
2286 return res;
2287 }
2288
GetInstanceFieldIdOffset(ArtField * field)2289 size_t Class::GetInstanceFieldIdOffset(ArtField* field) {
2290 DCHECK_LT(reinterpret_cast<uintptr_t>(field),
2291 reinterpret_cast<uintptr_t>(&*GetIFieldsPtr()->end()))
2292 << "field not part of the current class. " << field->PrettyField() << " class is "
2293 << PrettyClass();
2294 DCHECK_GE(reinterpret_cast<uintptr_t>(field),
2295 reinterpret_cast<uintptr_t>(&*GetIFieldsPtr()->begin()))
2296 << "field not part of the current class. " << field->PrettyField() << " class is "
2297 << PrettyClass();
2298 uintptr_t start = reinterpret_cast<uintptr_t>(&GetIFieldsPtr()->At(0));
2299 uintptr_t fld = reinterpret_cast<uintptr_t>(field);
2300 size_t res = (fld - start) / sizeof(ArtField);
2301 DCHECK_EQ(&GetIFieldsPtr()->At(res), field)
2302 << "Incorrect field computation expected: " << field->PrettyField()
2303 << " got: " << GetIFieldsPtr()->At(res).PrettyField();
2304 return res;
2305 }
2306
GetMethodIdOffset(ArtMethod * method,PointerSize pointer_size)2307 size_t Class::GetMethodIdOffset(ArtMethod* method, PointerSize pointer_size) {
2308 DCHECK(GetMethodsSlice(kRuntimePointerSize).Contains(method))
2309 << "method not part of the current class. " << method->PrettyMethod() << "( " << reinterpret_cast<void*>(method) << ")" << " class is "
2310 << PrettyClass() << [&]() REQUIRES_SHARED(Locks::mutator_lock_) {
2311 std::ostringstream os;
2312 os << " Methods are [";
2313 for (ArtMethod& m : GetMethodsSlice(kRuntimePointerSize)) {
2314 os << m.PrettyMethod() << "( " << reinterpret_cast<void*>(&m) << "), ";
2315 }
2316 os << "]";
2317 return os.str();
2318 }();
2319 uintptr_t start = reinterpret_cast<uintptr_t>(&*GetMethodsSlice(pointer_size).begin());
2320 uintptr_t fld = reinterpret_cast<uintptr_t>(method);
2321 size_t art_method_size = ArtMethod::Size(pointer_size);
2322 size_t art_method_align = ArtMethod::Alignment(pointer_size);
2323 size_t res = (fld - start) / art_method_size;
2324 DCHECK_EQ(&GetMethodsPtr()->At(res, art_method_size, art_method_align), method)
2325 << "Incorrect method computation expected: " << method->PrettyMethod()
2326 << " got: " << GetMethodsPtr()->At(res, art_method_size, art_method_align).PrettyMethod();
2327 return res;
2328 }
2329
CheckIsVisibleWithTargetSdk(Thread * self)2330 bool Class::CheckIsVisibleWithTargetSdk(Thread* self) {
2331 uint32_t targetSdkVersion = Runtime::Current()->GetTargetSdkVersion();
2332 if (IsSdkVersionSetAndAtMost(targetSdkVersion, SdkVersion::kT)) {
2333 ObjPtr<mirror::Class> java_lang_ClassValue =
2334 WellKnownClasses::ToClass(WellKnownClasses::java_lang_ClassValue);
2335 if (this == java_lang_ClassValue.Ptr()) {
2336 self->ThrowNewException("Ljava/lang/ClassNotFoundException;", "java.lang.ClassValue");
2337 return false;
2338 }
2339 }
2340 return true;
2341 }
2342
2343 ALWAYS_INLINE
IsInterfaceMethodAccessible(ArtMethod * interface_method)2344 static bool IsInterfaceMethodAccessible(ArtMethod* interface_method)
2345 REQUIRES_SHARED(Locks::mutator_lock_) {
2346 // If the interface method is part of the public SDK, return it.
2347 if ((hiddenapi::GetRuntimeFlags(interface_method) & kAccPublicApi) != 0) {
2348 hiddenapi::ApiList api_list(hiddenapi::detail::GetDexFlags(interface_method));
2349 // The kAccPublicApi flag is also used as an optimization to avoid
2350 // other hiddenapi checks to always go on the slow path. Therefore, we
2351 // need to check here if the method is in the SDK list.
2352 if (api_list.IsSdkApi()) {
2353 return true;
2354 }
2355 }
2356 return false;
2357 }
2358
FindAccessibleInterfaceMethod(ArtMethod * implementation_method,PointerSize pointer_size)2359 ArtMethod* Class::FindAccessibleInterfaceMethod(ArtMethod* implementation_method,
2360 PointerSize pointer_size)
2361 REQUIRES_SHARED(Locks::mutator_lock_) {
2362 ObjPtr<mirror::IfTable> iftable = GetIfTable();
2363 if (IsInterface()) { // Interface class doesn't resolve methods into the iftable.
2364 for (int32_t i = 0, iftable_count = iftable->Count(); i < iftable_count; ++i) {
2365 ObjPtr<mirror::Class> iface = iftable->GetInterface(i);
2366 for (ArtMethod& interface_method : iface->GetVirtualMethodsSlice(pointer_size)) {
2367 if (implementation_method->HasSameNameAndSignature(&interface_method) &&
2368 IsInterfaceMethodAccessible(&interface_method)) {
2369 return &interface_method;
2370 }
2371 }
2372 }
2373 } else {
2374 for (int32_t i = 0, iftable_count = iftable->Count(); i < iftable_count; ++i) {
2375 ObjPtr<mirror::PointerArray> methods = iftable->GetMethodArrayOrNull(i);
2376 if (methods == nullptr) {
2377 continue;
2378 }
2379 for (size_t j = 0, count = iftable->GetMethodArrayCount(i); j < count; ++j) {
2380 if (implementation_method == methods->GetElementPtrSize<ArtMethod*>(j, pointer_size)) {
2381 ObjPtr<mirror::Class> iface = iftable->GetInterface(i);
2382 ArtMethod* interface_method = &iface->GetVirtualMethodsSlice(pointer_size)[j];
2383 if (IsInterfaceMethodAccessible(interface_method)) {
2384 return interface_method;
2385 }
2386 }
2387 }
2388 }
2389 }
2390 return nullptr;
2391 }
2392
2393
2394 } // namespace mirror
2395 } // namespace art
2396