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