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