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