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