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 "android-base/stringprintf.h"
20
21 #include "art_field-inl.h"
22 #include "art_method-inl.h"
23 #include "class_ext.h"
24 #include "class_linker-inl.h"
25 #include "class_loader.h"
26 #include "class-inl.h"
27 #include "dex_cache.h"
28 #include "dex_file-inl.h"
29 #include "dex_file_annotations.h"
30 #include "gc/accounting/card_table-inl.h"
31 #include "handle_scope-inl.h"
32 #include "method.h"
33 #include "object_array-inl.h"
34 #include "object-inl.h"
35 #include "object-refvisitor-inl.h"
36 #include "object_lock.h"
37 #include "runtime.h"
38 #include "thread.h"
39 #include "throwable.h"
40 #include "utils.h"
41 #include "well_known_classes.h"
42
43 namespace art {
44 namespace mirror {
45
46 using android::base::StringPrintf;
47
48 GcRoot<Class> Class::java_lang_Class_;
49
SetClassClass(ObjPtr<Class> java_lang_Class)50 void Class::SetClassClass(ObjPtr<Class> java_lang_Class) {
51 CHECK(java_lang_Class_.IsNull())
52 << java_lang_Class_.Read()
53 << " " << java_lang_Class;
54 CHECK(java_lang_Class != nullptr);
55 java_lang_Class->SetClassFlags(kClassFlagClass);
56 java_lang_Class_ = GcRoot<Class>(java_lang_Class);
57 }
58
ResetClass()59 void Class::ResetClass() {
60 CHECK(!java_lang_Class_.IsNull());
61 java_lang_Class_ = GcRoot<Class>(nullptr);
62 }
63
VisitRoots(RootVisitor * visitor)64 void Class::VisitRoots(RootVisitor* visitor) {
65 java_lang_Class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
66 }
67
EnsureExtDataPresent(Thread * self)68 ClassExt* Class::EnsureExtDataPresent(Thread* self) {
69 ObjPtr<ClassExt> existing(GetExtData());
70 if (!existing.IsNull()) {
71 return existing.Ptr();
72 }
73 StackHandleScope<3> hs(self);
74 // Handlerize 'this' since we are allocating here.
75 Handle<Class> h_this(hs.NewHandle(this));
76 // Clear exception so we can allocate.
77 Handle<Throwable> throwable(hs.NewHandle(self->GetException()));
78 self->ClearException();
79 // Allocate the ClassExt
80 Handle<ClassExt> new_ext(hs.NewHandle(ClassExt::Alloc(self)));
81 if (new_ext == nullptr) {
82 // OOM allocating the classExt.
83 // TODO Should we restore the suppressed exception?
84 self->AssertPendingOOMException();
85 return nullptr;
86 } else {
87 MemberOffset ext_offset(OFFSET_OF_OBJECT_MEMBER(Class, ext_data_));
88 bool set;
89 // Set the ext_data_ field using CAS semantics.
90 if (Runtime::Current()->IsActiveTransaction()) {
91 set = h_this->CasFieldStrongSequentiallyConsistentObject<true>(ext_offset,
92 ObjPtr<ClassExt>(nullptr),
93 new_ext.Get());
94 } else {
95 set = h_this->CasFieldStrongSequentiallyConsistentObject<false>(ext_offset,
96 ObjPtr<ClassExt>(nullptr),
97 new_ext.Get());
98 }
99 ObjPtr<ClassExt> ret(set ? new_ext.Get() : h_this->GetExtData());
100 DCHECK(!set || h_this->GetExtData() == new_ext.Get());
101 CHECK(!ret.IsNull());
102 // Restore the exception if there was one.
103 if (throwable != nullptr) {
104 self->SetException(throwable.Get());
105 }
106 return ret.Ptr();
107 }
108 }
109
SetStatus(Handle<Class> h_this,Status new_status,Thread * self)110 void Class::SetStatus(Handle<Class> h_this, Status new_status, Thread* self) {
111 Status old_status = h_this->GetStatus();
112 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
113 bool class_linker_initialized = class_linker != nullptr && class_linker->IsInitialized();
114 if (LIKELY(class_linker_initialized)) {
115 if (UNLIKELY(new_status <= old_status &&
116 new_status != kStatusErrorUnresolved &&
117 new_status != kStatusErrorResolved &&
118 new_status != kStatusRetired)) {
119 LOG(FATAL) << "Unexpected change back of class status for " << h_this->PrettyClass()
120 << " " << old_status << " -> " << new_status;
121 }
122 if (new_status >= kStatusResolved || old_status >= kStatusResolved) {
123 // When classes are being resolved the resolution code should hold the lock.
124 CHECK_EQ(h_this->GetLockOwnerThreadId(), self->GetThreadId())
125 << "Attempt to change status of class while not holding its lock: "
126 << h_this->PrettyClass() << " " << old_status << " -> " << new_status;
127 }
128 }
129 if (UNLIKELY(IsErroneous(new_status))) {
130 CHECK(!h_this->IsErroneous())
131 << "Attempt to set as erroneous an already erroneous class "
132 << h_this->PrettyClass()
133 << " old_status: " << old_status << " new_status: " << new_status;
134 CHECK_EQ(new_status == kStatusErrorResolved, old_status >= kStatusResolved);
135 if (VLOG_IS_ON(class_linker)) {
136 LOG(ERROR) << "Setting " << h_this->PrettyDescriptor() << " to erroneous.";
137 if (self->IsExceptionPending()) {
138 LOG(ERROR) << "Exception: " << self->GetException()->Dump();
139 }
140 }
141
142 ObjPtr<ClassExt> ext(h_this->EnsureExtDataPresent(self));
143 if (!ext.IsNull()) {
144 self->AssertPendingException();
145 ext->SetVerifyError(self->GetException());
146 } else {
147 self->AssertPendingOOMException();
148 }
149 self->AssertPendingException();
150 }
151
152 static_assert(sizeof(Status) == sizeof(uint32_t), "Size of status not equal to uint32");
153 if (Runtime::Current()->IsActiveTransaction()) {
154 h_this->SetField32Volatile<true>(StatusOffset(), new_status);
155 } else {
156 h_this->SetField32Volatile<false>(StatusOffset(), new_status);
157 }
158
159 // Setting the object size alloc fast path needs to be after the status write so that if the
160 // alloc path sees a valid object size, we would know that it's initialized as long as it has a
161 // load-acquire/fake dependency.
162 if (new_status == kStatusInitialized && !h_this->IsVariableSize()) {
163 DCHECK_EQ(h_this->GetObjectSizeAllocFastPath(), std::numeric_limits<uint32_t>::max());
164 // Finalizable objects must always go slow path.
165 if (!h_this->IsFinalizable()) {
166 h_this->SetObjectSizeAllocFastPath(RoundUp(h_this->GetObjectSize(), kObjectAlignment));
167 }
168 }
169
170 if (!class_linker_initialized) {
171 // When the class linker is being initialized its single threaded and by definition there can be
172 // no waiters. During initialization classes may appear temporary but won't be retired as their
173 // size was statically computed.
174 } else {
175 // Classes that are being resolved or initialized need to notify waiters that the class status
176 // changed. See ClassLinker::EnsureResolved and ClassLinker::WaitForInitializeClass.
177 if (h_this->IsTemp()) {
178 // Class is a temporary one, ensure that waiters for resolution get notified of retirement
179 // so that they can grab the new version of the class from the class linker's table.
180 CHECK_LT(new_status, kStatusResolved) << h_this->PrettyDescriptor();
181 if (new_status == kStatusRetired || new_status == kStatusErrorUnresolved) {
182 h_this->NotifyAll(self);
183 }
184 } else {
185 CHECK_NE(new_status, kStatusRetired);
186 if (old_status >= kStatusResolved || new_status >= kStatusResolved) {
187 h_this->NotifyAll(self);
188 }
189 }
190 }
191 }
192
SetDexCache(ObjPtr<DexCache> new_dex_cache)193 void Class::SetDexCache(ObjPtr<DexCache> new_dex_cache) {
194 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache);
195 }
196
SetClassSize(uint32_t new_class_size)197 void Class::SetClassSize(uint32_t new_class_size) {
198 if (kIsDebugBuild && new_class_size < GetClassSize()) {
199 DumpClass(LOG_STREAM(FATAL_WITHOUT_ABORT), kDumpClassFullDetail);
200 LOG(FATAL_WITHOUT_ABORT) << new_class_size << " vs " << GetClassSize();
201 LOG(FATAL) << "class=" << PrettyTypeOf();
202 }
203 // Not called within a transaction.
204 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size);
205 }
206
207 // Return the class' name. The exact format is bizarre, but it's the specified behavior for
208 // Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int"
209 // but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than
210 // slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness.
ComputeName(Handle<Class> h_this)211 String* Class::ComputeName(Handle<Class> h_this) {
212 String* name = h_this->GetName();
213 if (name != nullptr) {
214 return name;
215 }
216 std::string temp;
217 const char* descriptor = h_this->GetDescriptor(&temp);
218 Thread* self = Thread::Current();
219 if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
220 // The descriptor indicates that this is the class for
221 // a primitive type; special-case the return value.
222 const char* c_name = nullptr;
223 switch (descriptor[0]) {
224 case 'Z': c_name = "boolean"; break;
225 case 'B': c_name = "byte"; break;
226 case 'C': c_name = "char"; break;
227 case 'S': c_name = "short"; break;
228 case 'I': c_name = "int"; break;
229 case 'J': c_name = "long"; break;
230 case 'F': c_name = "float"; break;
231 case 'D': c_name = "double"; break;
232 case 'V': c_name = "void"; break;
233 default:
234 LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
235 }
236 name = String::AllocFromModifiedUtf8(self, c_name);
237 } else {
238 // Convert the UTF-8 name to a java.lang.String. The name must use '.' to separate package
239 // components.
240 name = String::AllocFromModifiedUtf8(self, DescriptorToDot(descriptor).c_str());
241 }
242 h_this->SetName(name);
243 return name;
244 }
245
DumpClass(std::ostream & os,int flags)246 void Class::DumpClass(std::ostream& os, int flags) {
247 if ((flags & kDumpClassFullDetail) == 0) {
248 os << PrettyClass();
249 if ((flags & kDumpClassClassLoader) != 0) {
250 os << ' ' << GetClassLoader();
251 }
252 if ((flags & kDumpClassInitialized) != 0) {
253 os << ' ' << GetStatus();
254 }
255 os << "\n";
256 return;
257 }
258
259 Thread* const self = Thread::Current();
260 StackHandleScope<2> hs(self);
261 Handle<Class> h_this(hs.NewHandle(this));
262 Handle<Class> h_super(hs.NewHandle(GetSuperClass()));
263 auto image_pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
264
265 std::string temp;
266 os << "----- " << (IsInterface() ? "interface" : "class") << " "
267 << "'" << GetDescriptor(&temp) << "' cl=" << GetClassLoader() << " -----\n",
268 os << " objectSize=" << SizeOf() << " "
269 << "(" << (h_super != nullptr ? h_super->SizeOf() : -1) << " from super)\n",
270 os << StringPrintf(" access=0x%04x.%04x\n",
271 GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
272 if (h_super != nullptr) {
273 os << " super='" << h_super->PrettyClass() << "' (cl=" << h_super->GetClassLoader()
274 << ")\n";
275 }
276 if (IsArrayClass()) {
277 os << " componentType=" << PrettyClass(GetComponentType()) << "\n";
278 }
279 const size_t num_direct_interfaces = NumDirectInterfaces();
280 if (num_direct_interfaces > 0) {
281 os << " interfaces (" << num_direct_interfaces << "):\n";
282 for (size_t i = 0; i < num_direct_interfaces; ++i) {
283 ObjPtr<Class> interface = GetDirectInterface(self, h_this.Get(), i);
284 if (interface == nullptr) {
285 os << StringPrintf(" %2zd: nullptr!\n", i);
286 } else {
287 ObjPtr<ClassLoader> cl = interface->GetClassLoader();
288 os << StringPrintf(" %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl.Ptr());
289 }
290 }
291 }
292 if (!IsLoaded()) {
293 os << " class not yet loaded";
294 } else {
295 // After this point, this may have moved due to GetDirectInterface.
296 os << " vtable (" << h_this->NumVirtualMethods() << " entries, "
297 << (h_super != nullptr ? h_super->NumVirtualMethods() : 0) << " in super):\n";
298 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
299 os << StringPrintf(" %2zd: %s\n", i, ArtMethod::PrettyMethod(
300 h_this->GetVirtualMethodDuringLinking(i, image_pointer_size)).c_str());
301 }
302 os << " direct methods (" << h_this->NumDirectMethods() << " entries):\n";
303 for (size_t i = 0; i < h_this->NumDirectMethods(); ++i) {
304 os << StringPrintf(" %2zd: %s\n", i, ArtMethod::PrettyMethod(
305 h_this->GetDirectMethod(i, image_pointer_size)).c_str());
306 }
307 if (h_this->NumStaticFields() > 0) {
308 os << " static fields (" << h_this->NumStaticFields() << " entries):\n";
309 if (h_this->IsResolved()) {
310 for (size_t i = 0; i < h_this->NumStaticFields(); ++i) {
311 os << StringPrintf(" %2zd: %s\n", i,
312 ArtField::PrettyField(h_this->GetStaticField(i)).c_str());
313 }
314 } else {
315 os << " <not yet available>";
316 }
317 }
318 if (h_this->NumInstanceFields() > 0) {
319 os << " instance fields (" << h_this->NumInstanceFields() << " entries):\n";
320 if (h_this->IsResolved()) {
321 for (size_t i = 0; i < h_this->NumInstanceFields(); ++i) {
322 os << StringPrintf(" %2zd: %s\n", i,
323 ArtField::PrettyField(h_this->GetInstanceField(i)).c_str());
324 }
325 } else {
326 os << " <not yet available>";
327 }
328 }
329 }
330 }
331
SetReferenceInstanceOffsets(uint32_t new_reference_offsets)332 void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
333 if (kIsDebugBuild && new_reference_offsets != kClassWalkSuper) {
334 // Sanity check that the number of bits set in the reference offset bitmap
335 // agrees with the number of references
336 uint32_t count = 0;
337 for (ObjPtr<Class> c = this; c != nullptr; c = c->GetSuperClass()) {
338 count += c->NumReferenceInstanceFieldsDuringLinking();
339 }
340 // +1 for the Class in Object.
341 CHECK_EQ(static_cast<uint32_t>(POPCOUNT(new_reference_offsets)) + 1, count);
342 }
343 // Not called within a transaction.
344 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
345 new_reference_offsets);
346 }
347
IsInSamePackage(const StringPiece & descriptor1,const StringPiece & descriptor2)348 bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
349 size_t i = 0;
350 size_t min_length = std::min(descriptor1.size(), descriptor2.size());
351 while (i < min_length && descriptor1[i] == descriptor2[i]) {
352 ++i;
353 }
354 if (descriptor1.find('/', i) != StringPiece::npos ||
355 descriptor2.find('/', i) != StringPiece::npos) {
356 return false;
357 } else {
358 return true;
359 }
360 }
361
IsInSamePackage(ObjPtr<Class> that)362 bool Class::IsInSamePackage(ObjPtr<Class> that) {
363 ObjPtr<Class> klass1 = this;
364 ObjPtr<Class> klass2 = that;
365 if (klass1 == klass2) {
366 return true;
367 }
368 // Class loaders must match.
369 if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
370 return false;
371 }
372 // Arrays are in the same package when their element classes are.
373 while (klass1->IsArrayClass()) {
374 klass1 = klass1->GetComponentType();
375 }
376 while (klass2->IsArrayClass()) {
377 klass2 = klass2->GetComponentType();
378 }
379 // trivial check again for array types
380 if (klass1 == klass2) {
381 return true;
382 }
383 // Compare the package part of the descriptor string.
384 std::string temp1, temp2;
385 return IsInSamePackage(klass1->GetDescriptor(&temp1), klass2->GetDescriptor(&temp2));
386 }
387
IsThrowableClass()388 bool Class::IsThrowableClass() {
389 return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this);
390 }
391
SetClassLoader(ObjPtr<ClassLoader> new_class_loader)392 void Class::SetClassLoader(ObjPtr<ClassLoader> new_class_loader) {
393 if (Runtime::Current()->IsActiveTransaction()) {
394 SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader);
395 } else {
396 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader);
397 }
398 }
399
FindInterfaceMethod(const StringPiece & name,const StringPiece & signature,PointerSize pointer_size)400 ArtMethod* Class::FindInterfaceMethod(const StringPiece& name,
401 const StringPiece& signature,
402 PointerSize pointer_size) {
403 // Check the current class before checking the interfaces.
404 ArtMethod* method = FindDeclaredVirtualMethod(name, signature, pointer_size);
405 if (method != nullptr) {
406 return method;
407 }
408
409 int32_t iftable_count = GetIfTableCount();
410 ObjPtr<IfTable> iftable = GetIfTable();
411 for (int32_t i = 0; i < iftable_count; ++i) {
412 method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature, pointer_size);
413 if (method != nullptr) {
414 return method;
415 }
416 }
417 return nullptr;
418 }
419
FindInterfaceMethod(const StringPiece & name,const Signature & signature,PointerSize pointer_size)420 ArtMethod* Class::FindInterfaceMethod(const StringPiece& name,
421 const Signature& signature,
422 PointerSize pointer_size) {
423 // Check the current class before checking the interfaces.
424 ArtMethod* method = FindDeclaredVirtualMethod(name, signature, pointer_size);
425 if (method != nullptr) {
426 return method;
427 }
428
429 int32_t iftable_count = GetIfTableCount();
430 ObjPtr<IfTable> iftable = GetIfTable();
431 for (int32_t i = 0; i < iftable_count; ++i) {
432 method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature, pointer_size);
433 if (method != nullptr) {
434 return method;
435 }
436 }
437 return nullptr;
438 }
439
FindInterfaceMethod(ObjPtr<DexCache> dex_cache,uint32_t dex_method_idx,PointerSize pointer_size)440 ArtMethod* Class::FindInterfaceMethod(ObjPtr<DexCache> dex_cache,
441 uint32_t dex_method_idx,
442 PointerSize pointer_size) {
443 // Check the current class before checking the interfaces.
444 ArtMethod* method = FindDeclaredVirtualMethod(dex_cache, dex_method_idx, pointer_size);
445 if (method != nullptr) {
446 return method;
447 }
448
449 int32_t iftable_count = GetIfTableCount();
450 ObjPtr<IfTable> iftable = GetIfTable();
451 for (int32_t i = 0; i < iftable_count; ++i) {
452 method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(
453 dex_cache, dex_method_idx, pointer_size);
454 if (method != nullptr) {
455 return method;
456 }
457 }
458 return nullptr;
459 }
460
FindDeclaredDirectMethod(const StringPiece & name,const StringPiece & signature,PointerSize pointer_size)461 ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name,
462 const StringPiece& signature,
463 PointerSize pointer_size) {
464 for (auto& method : GetDirectMethods(pointer_size)) {
465 if (name == method.GetName() && method.GetSignature() == signature) {
466 return &method;
467 }
468 }
469 return nullptr;
470 }
471
FindDeclaredDirectMethod(const StringPiece & name,const Signature & signature,PointerSize pointer_size)472 ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name,
473 const Signature& signature,
474 PointerSize pointer_size) {
475 for (auto& method : GetDirectMethods(pointer_size)) {
476 if (name == method.GetName() && signature == method.GetSignature()) {
477 return &method;
478 }
479 }
480 return nullptr;
481 }
482
FindDeclaredDirectMethod(ObjPtr<DexCache> dex_cache,uint32_t dex_method_idx,PointerSize pointer_size)483 ArtMethod* Class::FindDeclaredDirectMethod(ObjPtr<DexCache> dex_cache,
484 uint32_t dex_method_idx,
485 PointerSize pointer_size) {
486 if (GetDexCache() == dex_cache) {
487 for (auto& method : GetDirectMethods(pointer_size)) {
488 if (method.GetDexMethodIndex() == dex_method_idx) {
489 return &method;
490 }
491 }
492 }
493 return nullptr;
494 }
495
FindDirectMethod(const StringPiece & name,const StringPiece & signature,PointerSize pointer_size)496 ArtMethod* Class::FindDirectMethod(const StringPiece& name,
497 const StringPiece& signature,
498 PointerSize pointer_size) {
499 for (ObjPtr<Class> klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
500 ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature, pointer_size);
501 if (method != nullptr) {
502 return method;
503 }
504 }
505 return nullptr;
506 }
507
FindDirectMethod(const StringPiece & name,const Signature & signature,PointerSize pointer_size)508 ArtMethod* Class::FindDirectMethod(const StringPiece& name,
509 const Signature& signature,
510 PointerSize pointer_size) {
511 for (ObjPtr<Class> klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
512 ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature, pointer_size);
513 if (method != nullptr) {
514 return method;
515 }
516 }
517 return nullptr;
518 }
519
FindDirectMethod(ObjPtr<DexCache> dex_cache,uint32_t dex_method_idx,PointerSize pointer_size)520 ArtMethod* Class::FindDirectMethod(ObjPtr<DexCache> dex_cache,
521 uint32_t dex_method_idx,
522 PointerSize pointer_size) {
523 for (ObjPtr<Class> klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
524 ArtMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx, pointer_size);
525 if (method != nullptr) {
526 return method;
527 }
528 }
529 return nullptr;
530 }
531
FindDeclaredDirectMethodByName(const StringPiece & name,PointerSize pointer_size)532 ArtMethod* Class::FindDeclaredDirectMethodByName(const StringPiece& name,
533 PointerSize pointer_size) {
534 for (auto& method : GetDirectMethods(pointer_size)) {
535 ArtMethod* const np_method = method.GetInterfaceMethodIfProxy(pointer_size);
536 if (name == np_method->GetName()) {
537 return &method;
538 }
539 }
540 return nullptr;
541 }
542
543 // TODO These should maybe be changed to be named FindOwnedVirtualMethod or something similar
544 // because they do not only find 'declared' methods and will return copied methods. This behavior is
545 // desired and correct but the naming can lead to confusion because in the java language declared
546 // excludes interface methods which might be found by this.
FindDeclaredVirtualMethod(const StringPiece & name,const StringPiece & signature,PointerSize pointer_size)547 ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name,
548 const StringPiece& signature,
549 PointerSize pointer_size) {
550 for (auto& method : GetVirtualMethods(pointer_size)) {
551 ArtMethod* const np_method = method.GetInterfaceMethodIfProxy(pointer_size);
552 if (name == np_method->GetName() && np_method->GetSignature() == signature) {
553 return &method;
554 }
555 }
556 return nullptr;
557 }
558
FindDeclaredVirtualMethod(const StringPiece & name,const Signature & signature,PointerSize pointer_size)559 ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name,
560 const Signature& signature,
561 PointerSize pointer_size) {
562 for (auto& method : GetVirtualMethods(pointer_size)) {
563 ArtMethod* const np_method = method.GetInterfaceMethodIfProxy(pointer_size);
564 if (name == np_method->GetName() && signature == np_method->GetSignature()) {
565 return &method;
566 }
567 }
568 return nullptr;
569 }
570
FindDeclaredVirtualMethod(ObjPtr<DexCache> dex_cache,uint32_t dex_method_idx,PointerSize pointer_size)571 ArtMethod* Class::FindDeclaredVirtualMethod(ObjPtr<DexCache> dex_cache,
572 uint32_t dex_method_idx,
573 PointerSize pointer_size) {
574 if (GetDexCache() == dex_cache) {
575 for (auto& method : GetDeclaredVirtualMethods(pointer_size)) {
576 if (method.GetDexMethodIndex() == dex_method_idx) {
577 return &method;
578 }
579 }
580 }
581 return nullptr;
582 }
583
FindDeclaredVirtualMethodByName(const StringPiece & name,PointerSize pointer_size)584 ArtMethod* Class::FindDeclaredVirtualMethodByName(const StringPiece& name,
585 PointerSize pointer_size) {
586 for (auto& method : GetVirtualMethods(pointer_size)) {
587 ArtMethod* const np_method = method.GetInterfaceMethodIfProxy(pointer_size);
588 if (name == np_method->GetName()) {
589 return &method;
590 }
591 }
592 return nullptr;
593 }
594
FindVirtualMethod(const StringPiece & name,const StringPiece & signature,PointerSize pointer_size)595 ArtMethod* Class::FindVirtualMethod(const StringPiece& name,
596 const StringPiece& signature,
597 PointerSize pointer_size) {
598 for (ObjPtr<Class> klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
599 ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature, pointer_size);
600 if (method != nullptr) {
601 return method;
602 }
603 }
604 return nullptr;
605 }
606
FindVirtualMethod(const StringPiece & name,const Signature & signature,PointerSize pointer_size)607 ArtMethod* Class::FindVirtualMethod(const StringPiece& name,
608 const Signature& signature,
609 PointerSize pointer_size) {
610 for (ObjPtr<Class> klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
611 ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature, pointer_size);
612 if (method != nullptr) {
613 return method;
614 }
615 }
616 return nullptr;
617 }
618
FindVirtualMethod(ObjPtr<DexCache> dex_cache,uint32_t dex_method_idx,PointerSize pointer_size)619 ArtMethod* Class::FindVirtualMethod(ObjPtr<DexCache> dex_cache,
620 uint32_t dex_method_idx,
621 PointerSize pointer_size) {
622 for (ObjPtr<Class> klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
623 ArtMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx, pointer_size);
624 if (method != nullptr) {
625 return method;
626 }
627 }
628 return nullptr;
629 }
630
FindVirtualMethodForInterfaceSuper(ArtMethod * method,PointerSize pointer_size)631 ArtMethod* Class::FindVirtualMethodForInterfaceSuper(ArtMethod* method, PointerSize pointer_size) {
632 DCHECK(method->GetDeclaringClass()->IsInterface());
633 DCHECK(IsInterface()) << "Should only be called on a interface class";
634 // Check if we have one defined on this interface first. This includes searching copied ones to
635 // get any conflict methods. Conflict methods are copied into each subtype from the supertype. We
636 // don't do any indirect method checks here.
637 for (ArtMethod& iface_method : GetVirtualMethods(pointer_size)) {
638 if (method->HasSameNameAndSignature(&iface_method)) {
639 return &iface_method;
640 }
641 }
642
643 std::vector<ArtMethod*> abstract_methods;
644 // Search through the IFTable for a working version. We don't need to check for conflicts
645 // because if there was one it would appear in this classes virtual_methods_ above.
646
647 Thread* self = Thread::Current();
648 StackHandleScope<2> hs(self);
649 MutableHandle<IfTable> iftable(hs.NewHandle(GetIfTable()));
650 MutableHandle<Class> iface(hs.NewHandle<Class>(nullptr));
651 size_t iftable_count = GetIfTableCount();
652 // Find the method. We don't need to check for conflicts because they would have been in the
653 // copied virtuals of this interface. Order matters, traverse in reverse topological order; most
654 // subtypiest interfaces get visited first.
655 for (size_t k = iftable_count; k != 0;) {
656 k--;
657 DCHECK_LT(k, iftable->Count());
658 iface.Assign(iftable->GetInterface(k));
659 // Iterate through every declared method on this interface. Each direct method's name/signature
660 // is unique so the order of the inner loop doesn't matter.
661 for (auto& method_iter : iface->GetDeclaredVirtualMethods(pointer_size)) {
662 ArtMethod* current_method = &method_iter;
663 if (current_method->HasSameNameAndSignature(method)) {
664 if (current_method->IsDefault()) {
665 // Handle JLS soft errors, a default method from another superinterface tree can
666 // "override" an abstract method(s) from another superinterface tree(s). To do this,
667 // ignore any [default] method which are dominated by the abstract methods we've seen so
668 // far. Check if overridden by any in abstract_methods. We do not need to check for
669 // default_conflicts because we would hit those before we get to this loop.
670 bool overridden = false;
671 for (ArtMethod* possible_override : abstract_methods) {
672 DCHECK(possible_override->HasSameNameAndSignature(current_method));
673 if (iface->IsAssignableFrom(possible_override->GetDeclaringClass())) {
674 overridden = true;
675 break;
676 }
677 }
678 if (!overridden) {
679 return current_method;
680 }
681 } else {
682 // Is not default.
683 // This might override another default method. Just stash it for now.
684 abstract_methods.push_back(current_method);
685 }
686 }
687 }
688 }
689 // If we reach here we either never found any declaration of the method (in which case
690 // 'abstract_methods' is empty or we found no non-overriden default methods in which case
691 // 'abstract_methods' contains a number of abstract implementations of the methods. We choose one
692 // of these arbitrarily.
693 return abstract_methods.empty() ? nullptr : abstract_methods[0];
694 }
695
FindClassInitializer(PointerSize pointer_size)696 ArtMethod* Class::FindClassInitializer(PointerSize pointer_size) {
697 for (ArtMethod& method : GetDirectMethods(pointer_size)) {
698 if (method.IsClassInitializer()) {
699 DCHECK_STREQ(method.GetName(), "<clinit>");
700 DCHECK_STREQ(method.GetSignature().ToString().c_str(), "()V");
701 return &method;
702 }
703 }
704 return nullptr;
705 }
706
707 // Custom binary search to avoid double comparisons from std::binary_search.
FindFieldByNameAndType(LengthPrefixedArray<ArtField> * fields,const StringPiece & name,const StringPiece & type)708 static ArtField* FindFieldByNameAndType(LengthPrefixedArray<ArtField>* fields,
709 const StringPiece& name,
710 const StringPiece& type)
711 REQUIRES_SHARED(Locks::mutator_lock_) {
712 if (fields == nullptr) {
713 return nullptr;
714 }
715 size_t low = 0;
716 size_t high = fields->size();
717 ArtField* ret = nullptr;
718 while (low < high) {
719 size_t mid = (low + high) / 2;
720 ArtField& field = fields->At(mid);
721 // Fields are sorted by class, then name, then type descriptor. This is verified in dex file
722 // verifier. There can be multiple fields with the same in the same class name due to proguard.
723 int result = StringPiece(field.GetName()).Compare(name);
724 if (result == 0) {
725 result = StringPiece(field.GetTypeDescriptor()).Compare(type);
726 }
727 if (result < 0) {
728 low = mid + 1;
729 } else if (result > 0) {
730 high = mid;
731 } else {
732 ret = &field;
733 break;
734 }
735 }
736 if (kIsDebugBuild) {
737 ArtField* found = nullptr;
738 for (ArtField& field : MakeIterationRangeFromLengthPrefixedArray(fields)) {
739 if (name == field.GetName() && type == field.GetTypeDescriptor()) {
740 found = &field;
741 break;
742 }
743 }
744 CHECK_EQ(found, ret) << "Found " << found->PrettyField() << " vs " << ret->PrettyField();
745 }
746 return ret;
747 }
748
FindDeclaredInstanceField(const StringPiece & name,const StringPiece & type)749 ArtField* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) {
750 // Binary search by name. Interfaces are not relevant because they can't contain instance fields.
751 return FindFieldByNameAndType(GetIFieldsPtr(), name, type);
752 }
753
FindDeclaredInstanceField(ObjPtr<DexCache> dex_cache,uint32_t dex_field_idx)754 ArtField* Class::FindDeclaredInstanceField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx) {
755 if (GetDexCache() == dex_cache) {
756 for (ArtField& field : GetIFields()) {
757 if (field.GetDexFieldIndex() == dex_field_idx) {
758 return &field;
759 }
760 }
761 }
762 return nullptr;
763 }
764
FindInstanceField(const StringPiece & name,const StringPiece & type)765 ArtField* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) {
766 // Is the field in this class, or any of its superclasses?
767 // Interfaces are not relevant because they can't contain instance fields.
768 for (ObjPtr<Class> c = this; c != nullptr; c = c->GetSuperClass()) {
769 ArtField* f = c->FindDeclaredInstanceField(name, type);
770 if (f != nullptr) {
771 return f;
772 }
773 }
774 return nullptr;
775 }
776
FindInstanceField(ObjPtr<DexCache> dex_cache,uint32_t dex_field_idx)777 ArtField* Class::FindInstanceField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx) {
778 // Is the field in this class, or any of its superclasses?
779 // Interfaces are not relevant because they can't contain instance fields.
780 for (ObjPtr<Class> c = this; c != nullptr; c = c->GetSuperClass()) {
781 ArtField* f = c->FindDeclaredInstanceField(dex_cache, dex_field_idx);
782 if (f != nullptr) {
783 return f;
784 }
785 }
786 return nullptr;
787 }
788
FindDeclaredStaticField(const StringPiece & name,const StringPiece & type)789 ArtField* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) {
790 DCHECK(type != nullptr);
791 return FindFieldByNameAndType(GetSFieldsPtr(), name, type);
792 }
793
FindDeclaredStaticField(ObjPtr<DexCache> dex_cache,uint32_t dex_field_idx)794 ArtField* Class::FindDeclaredStaticField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx) {
795 if (dex_cache == GetDexCache()) {
796 for (ArtField& field : GetSFields()) {
797 if (field.GetDexFieldIndex() == dex_field_idx) {
798 return &field;
799 }
800 }
801 }
802 return nullptr;
803 }
804
FindStaticField(Thread * self,ObjPtr<Class> klass,const StringPiece & name,const StringPiece & type)805 ArtField* Class::FindStaticField(Thread* self,
806 ObjPtr<Class> klass,
807 const StringPiece& name,
808 const StringPiece& type) {
809 // Is the field in this class (or its interfaces), or any of its
810 // superclasses (or their interfaces)?
811 for (ObjPtr<Class> k = klass; k != nullptr; k = k->GetSuperClass()) {
812 // Is the field in this class?
813 ArtField* f = k->FindDeclaredStaticField(name, type);
814 if (f != nullptr) {
815 return f;
816 }
817 // Is this field in any of this class' interfaces?
818 for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
819 ObjPtr<Class> interface = GetDirectInterface(self, k, i);
820 DCHECK(interface != nullptr);
821 f = FindStaticField(self, interface, name, type);
822 if (f != nullptr) {
823 return f;
824 }
825 }
826 }
827 return nullptr;
828 }
829
FindStaticField(Thread * self,ObjPtr<Class> klass,ObjPtr<DexCache> dex_cache,uint32_t dex_field_idx)830 ArtField* Class::FindStaticField(Thread* self,
831 ObjPtr<Class> klass,
832 ObjPtr<DexCache> dex_cache,
833 uint32_t dex_field_idx) {
834 for (ObjPtr<Class> k = klass; k != nullptr; k = k->GetSuperClass()) {
835 // Is the field in this class?
836 ArtField* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx);
837 if (f != nullptr) {
838 return f;
839 }
840 // Though GetDirectInterface() should not cause thread suspension when called
841 // from here, it takes a Handle as an argument, so we need to wrap `k`.
842 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
843 // Is this field in any of this class' interfaces?
844 for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
845 ObjPtr<Class> interface = GetDirectInterface(self, k, i);
846 DCHECK(interface != nullptr);
847 f = FindStaticField(self, interface, dex_cache, dex_field_idx);
848 if (f != nullptr) {
849 return f;
850 }
851 }
852 }
853 return nullptr;
854 }
855
FindField(Thread * self,ObjPtr<Class> klass,const StringPiece & name,const StringPiece & type)856 ArtField* Class::FindField(Thread* self,
857 ObjPtr<Class> klass,
858 const StringPiece& name,
859 const StringPiece& type) {
860 // Find a field using the JLS field resolution order
861 for (ObjPtr<Class> k = klass; k != nullptr; k = k->GetSuperClass()) {
862 // Is the field in this class?
863 ArtField* f = k->FindDeclaredInstanceField(name, type);
864 if (f != nullptr) {
865 return f;
866 }
867 f = k->FindDeclaredStaticField(name, type);
868 if (f != nullptr) {
869 return f;
870 }
871 // Is this field in any of this class' interfaces?
872 for (uint32_t i = 0, num_interfaces = k->NumDirectInterfaces(); i != num_interfaces; ++i) {
873 ObjPtr<Class> interface = GetDirectInterface(self, k, i);
874 DCHECK(interface != nullptr);
875 f = FindStaticField(self, interface, name, type);
876 if (f != nullptr) {
877 return f;
878 }
879 }
880 }
881 return nullptr;
882 }
883
SetSkipAccessChecksFlagOnAllMethods(PointerSize pointer_size)884 void Class::SetSkipAccessChecksFlagOnAllMethods(PointerSize pointer_size) {
885 DCHECK(IsVerified());
886 for (auto& m : GetMethods(pointer_size)) {
887 if (!m.IsNative() && m.IsInvokable()) {
888 m.SetSkipAccessChecks();
889 }
890 }
891 }
892
GetDescriptor(std::string * storage)893 const char* Class::GetDescriptor(std::string* storage) {
894 if (IsPrimitive()) {
895 return Primitive::Descriptor(GetPrimitiveType());
896 } else if (IsArrayClass()) {
897 return GetArrayDescriptor(storage);
898 } else if (IsProxyClass()) {
899 *storage = Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this);
900 return storage->c_str();
901 } else {
902 const DexFile& dex_file = GetDexFile();
903 const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
904 return dex_file.GetTypeDescriptor(type_id);
905 }
906 }
907
GetArrayDescriptor(std::string * storage)908 const char* Class::GetArrayDescriptor(std::string* storage) {
909 std::string temp;
910 const char* elem_desc = GetComponentType()->GetDescriptor(&temp);
911 *storage = "[";
912 *storage += elem_desc;
913 return storage->c_str();
914 }
915
GetClassDef()916 const DexFile::ClassDef* Class::GetClassDef() {
917 uint16_t class_def_idx = GetDexClassDefIndex();
918 if (class_def_idx == DexFile::kDexNoIndex16) {
919 return nullptr;
920 }
921 return &GetDexFile().GetClassDef(class_def_idx);
922 }
923
GetDirectInterfaceTypeIdx(uint32_t idx)924 dex::TypeIndex Class::GetDirectInterfaceTypeIdx(uint32_t idx) {
925 DCHECK(!IsPrimitive());
926 DCHECK(!IsArrayClass());
927 return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
928 }
929
GetDirectInterface(Thread * self,ObjPtr<Class> klass,uint32_t idx)930 ObjPtr<Class> Class::GetDirectInterface(Thread* self, ObjPtr<Class> klass, uint32_t idx) {
931 DCHECK(klass != nullptr);
932 DCHECK(!klass->IsPrimitive());
933 if (klass->IsArrayClass()) {
934 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
935 // Use ClassLinker::LookupClass(); avoid poisoning ObjPtr<>s by ClassLinker::FindSystemClass().
936 ObjPtr<Class> interface;
937 if (idx == 0) {
938 interface = class_linker->LookupClass(self, "Ljava/lang/Cloneable;", nullptr);
939 } else {
940 DCHECK_EQ(1U, idx);
941 interface = class_linker->LookupClass(self, "Ljava/io/Serializable;", nullptr);
942 }
943 DCHECK(interface != nullptr);
944 return interface;
945 } else if (klass->IsProxyClass()) {
946 ObjPtr<ObjectArray<Class>> interfaces = klass->GetProxyInterfaces();
947 DCHECK(interfaces != nullptr);
948 return interfaces->Get(idx);
949 } else {
950 dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx);
951 ObjPtr<Class> interface = ClassLinker::LookupResolvedType(
952 type_idx, klass->GetDexCache(), klass->GetClassLoader());
953 return interface;
954 }
955 }
956
ResolveDirectInterface(Thread * self,Handle<Class> klass,uint32_t idx)957 ObjPtr<Class> Class::ResolveDirectInterface(Thread* self, Handle<Class> klass, uint32_t idx) {
958 ObjPtr<Class> interface = GetDirectInterface(self, klass.Get(), idx);
959 if (interface == nullptr) {
960 DCHECK(!klass->IsArrayClass());
961 DCHECK(!klass->IsProxyClass());
962 dex::TypeIndex type_idx = klass->GetDirectInterfaceTypeIdx(idx);
963 interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(),
964 type_idx,
965 klass.Get());
966 CHECK(interface != nullptr || self->IsExceptionPending());
967 }
968 return interface;
969 }
970
GetCommonSuperClass(Handle<Class> klass)971 ObjPtr<Class> Class::GetCommonSuperClass(Handle<Class> klass) {
972 DCHECK(klass != nullptr);
973 DCHECK(!klass->IsInterface());
974 DCHECK(!IsInterface());
975 ObjPtr<Class> common_super_class = this;
976 while (!common_super_class->IsAssignableFrom(klass.Get())) {
977 ObjPtr<Class> old_common = common_super_class;
978 common_super_class = old_common->GetSuperClass();
979 DCHECK(common_super_class != nullptr) << old_common->PrettyClass();
980 }
981 return common_super_class;
982 }
983
GetSourceFile()984 const char* Class::GetSourceFile() {
985 const DexFile& dex_file = GetDexFile();
986 const DexFile::ClassDef* dex_class_def = GetClassDef();
987 if (dex_class_def == nullptr) {
988 // Generated classes have no class def.
989 return nullptr;
990 }
991 return dex_file.GetSourceFile(*dex_class_def);
992 }
993
GetLocation()994 std::string Class::GetLocation() {
995 ObjPtr<DexCache> dex_cache = GetDexCache();
996 if (dex_cache != nullptr && !IsProxyClass()) {
997 return dex_cache->GetLocation()->ToModifiedUtf8();
998 }
999 // Arrays and proxies are generated and have no corresponding dex file location.
1000 return "generated class";
1001 }
1002
GetInterfaceTypeList()1003 const DexFile::TypeList* Class::GetInterfaceTypeList() {
1004 const DexFile::ClassDef* class_def = GetClassDef();
1005 if (class_def == nullptr) {
1006 return nullptr;
1007 }
1008 return GetDexFile().GetInterfacesList(*class_def);
1009 }
1010
PopulateEmbeddedVTable(PointerSize pointer_size)1011 void Class::PopulateEmbeddedVTable(PointerSize pointer_size) {
1012 PointerArray* table = GetVTableDuringLinking();
1013 CHECK(table != nullptr) << PrettyClass();
1014 const size_t table_length = table->GetLength();
1015 SetEmbeddedVTableLength(table_length);
1016 for (size_t i = 0; i < table_length; i++) {
1017 SetEmbeddedVTableEntry(i, table->GetElementPtrSize<ArtMethod*>(i, pointer_size), pointer_size);
1018 }
1019 // Keep java.lang.Object class's vtable around for since it's easier
1020 // to be reused by array classes during their linking.
1021 if (!IsObjectClass()) {
1022 SetVTable(nullptr);
1023 }
1024 }
1025
1026 class ReadBarrierOnNativeRootsVisitor {
1027 public:
operator ()(ObjPtr<Object> obj ATTRIBUTE_UNUSED,MemberOffset offset ATTRIBUTE_UNUSED,bool is_static ATTRIBUTE_UNUSED) const1028 void operator()(ObjPtr<Object> obj ATTRIBUTE_UNUSED,
1029 MemberOffset offset ATTRIBUTE_UNUSED,
1030 bool is_static ATTRIBUTE_UNUSED) const {}
1031
VisitRootIfNonNull(CompressedReference<Object> * root) const1032 void VisitRootIfNonNull(CompressedReference<Object>* root) const
1033 REQUIRES_SHARED(Locks::mutator_lock_) {
1034 if (!root->IsNull()) {
1035 VisitRoot(root);
1036 }
1037 }
1038
VisitRoot(CompressedReference<Object> * root) const1039 void VisitRoot(CompressedReference<Object>* root) const
1040 REQUIRES_SHARED(Locks::mutator_lock_) {
1041 ObjPtr<Object> old_ref = root->AsMirrorPtr();
1042 ObjPtr<Object> new_ref = ReadBarrier::BarrierForRoot(root);
1043 if (old_ref != new_ref) {
1044 // Update the field atomically. This may fail if mutator updates before us, but it's ok.
1045 auto* atomic_root =
1046 reinterpret_cast<Atomic<CompressedReference<Object>>*>(root);
1047 atomic_root->CompareExchangeStrongSequentiallyConsistent(
1048 CompressedReference<Object>::FromMirrorPtr(old_ref.Ptr()),
1049 CompressedReference<Object>::FromMirrorPtr(new_ref.Ptr()));
1050 }
1051 }
1052 };
1053
1054 // The pre-fence visitor for Class::CopyOf().
1055 class CopyClassVisitor {
1056 public:
CopyClassVisitor(Thread * self,Handle<Class> * orig,size_t new_length,size_t copy_bytes,ImTable * imt,PointerSize pointer_size)1057 CopyClassVisitor(Thread* self,
1058 Handle<Class>* orig,
1059 size_t new_length,
1060 size_t copy_bytes,
1061 ImTable* imt,
1062 PointerSize pointer_size)
1063 : self_(self), orig_(orig), new_length_(new_length),
1064 copy_bytes_(copy_bytes), imt_(imt), pointer_size_(pointer_size) {
1065 }
1066
operator ()(ObjPtr<Object> obj,size_t usable_size ATTRIBUTE_UNUSED) const1067 void operator()(ObjPtr<Object> obj, size_t usable_size ATTRIBUTE_UNUSED) const
1068 REQUIRES_SHARED(Locks::mutator_lock_) {
1069 StackHandleScope<1> hs(self_);
1070 Handle<mirror::Class> h_new_class_obj(hs.NewHandle(obj->AsClass()));
1071 Object::CopyObject(h_new_class_obj.Get(), orig_->Get(), copy_bytes_);
1072 Class::SetStatus(h_new_class_obj, Class::kStatusResolving, self_);
1073 h_new_class_obj->PopulateEmbeddedVTable(pointer_size_);
1074 h_new_class_obj->SetImt(imt_, pointer_size_);
1075 h_new_class_obj->SetClassSize(new_length_);
1076 // Visit all of the references to make sure there is no from space references in the native
1077 // roots.
1078 ObjPtr<Object>(h_new_class_obj.Get())->VisitReferences(
1079 ReadBarrierOnNativeRootsVisitor(), VoidFunctor());
1080 }
1081
1082 private:
1083 Thread* const self_;
1084 Handle<Class>* const orig_;
1085 const size_t new_length_;
1086 const size_t copy_bytes_;
1087 ImTable* imt_;
1088 const PointerSize pointer_size_;
1089 DISALLOW_COPY_AND_ASSIGN(CopyClassVisitor);
1090 };
1091
CopyOf(Thread * self,int32_t new_length,ImTable * imt,PointerSize pointer_size)1092 Class* Class::CopyOf(Thread* self, int32_t new_length, ImTable* imt, PointerSize pointer_size) {
1093 DCHECK_GE(new_length, static_cast<int32_t>(sizeof(Class)));
1094 // We may get copied by a compacting GC.
1095 StackHandleScope<1> hs(self);
1096 Handle<Class> h_this(hs.NewHandle(this));
1097 gc::Heap* heap = Runtime::Current()->GetHeap();
1098 // The num_bytes (3rd param) is sizeof(Class) as opposed to SizeOf()
1099 // to skip copying the tail part that we will overwrite here.
1100 CopyClassVisitor visitor(self, &h_this, new_length, sizeof(Class), imt, pointer_size);
1101 ObjPtr<Object> new_class = kMovingClasses ?
1102 heap->AllocObject<true>(self, java_lang_Class_.Read(), new_length, visitor) :
1103 heap->AllocNonMovableObject<true>(self, java_lang_Class_.Read(), new_length, visitor);
1104 if (UNLIKELY(new_class == nullptr)) {
1105 self->AssertPendingOOMException();
1106 return nullptr;
1107 }
1108 return new_class->AsClass();
1109 }
1110
ProxyDescriptorEquals(const char * match)1111 bool Class::ProxyDescriptorEquals(const char* match) {
1112 DCHECK(IsProxyClass());
1113 return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this) == match;
1114 }
1115
1116 // TODO: Move this to java_lang_Class.cc?
GetDeclaredConstructor(Thread * self,Handle<ObjectArray<Class>> args,PointerSize pointer_size)1117 ArtMethod* Class::GetDeclaredConstructor(
1118 Thread* self, Handle<ObjectArray<Class>> args, PointerSize pointer_size) {
1119 for (auto& m : GetDirectMethods(pointer_size)) {
1120 // Skip <clinit> which is a static constructor, as well as non constructors.
1121 if (m.IsStatic() || !m.IsConstructor()) {
1122 continue;
1123 }
1124 // May cause thread suspension and exceptions.
1125 if (m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->EqualParameters(args)) {
1126 return &m;
1127 }
1128 if (UNLIKELY(self->IsExceptionPending())) {
1129 return nullptr;
1130 }
1131 }
1132 return nullptr;
1133 }
1134
Depth()1135 uint32_t Class::Depth() {
1136 uint32_t depth = 0;
1137 for (ObjPtr<Class> klass = this; klass->GetSuperClass() != nullptr; klass = klass->GetSuperClass()) {
1138 depth++;
1139 }
1140 return depth;
1141 }
1142
FindTypeIndexInOtherDexFile(const DexFile & dex_file)1143 dex::TypeIndex Class::FindTypeIndexInOtherDexFile(const DexFile& dex_file) {
1144 std::string temp;
1145 const DexFile::TypeId* type_id = dex_file.FindTypeId(GetDescriptor(&temp));
1146 return (type_id == nullptr)
1147 ? dex::TypeIndex(DexFile::kDexNoIndex)
1148 : dex_file.GetIndexForTypeId(*type_id);
1149 }
1150
1151 template <PointerSize kPointerSize, bool kTransactionActive>
GetDeclaredMethodInternal(Thread * self,ObjPtr<Class> klass,ObjPtr<String> name,ObjPtr<ObjectArray<Class>> args)1152 ObjPtr<Method> Class::GetDeclaredMethodInternal(
1153 Thread* self,
1154 ObjPtr<Class> klass,
1155 ObjPtr<String> name,
1156 ObjPtr<ObjectArray<Class>> args) {
1157 // Covariant return types permit the class to define multiple
1158 // methods with the same name and parameter types. Prefer to
1159 // return a non-synthetic method in such situations. We may
1160 // still return a synthetic method to handle situations like
1161 // escalated visibility. We never return miranda methods that
1162 // were synthesized by the runtime.
1163 constexpr uint32_t kSkipModifiers = kAccMiranda | kAccSynthetic;
1164 StackHandleScope<3> hs(self);
1165 auto h_method_name = hs.NewHandle(name);
1166 if (UNLIKELY(h_method_name == nullptr)) {
1167 ThrowNullPointerException("name == null");
1168 return nullptr;
1169 }
1170 auto h_args = hs.NewHandle(args);
1171 Handle<Class> h_klass = hs.NewHandle(klass);
1172 ArtMethod* result = nullptr;
1173 for (auto& m : h_klass->GetDeclaredVirtualMethods(kPointerSize)) {
1174 auto* np_method = m.GetInterfaceMethodIfProxy(kPointerSize);
1175 // May cause thread suspension.
1176 ObjPtr<String> np_name = np_method->GetNameAsString(self);
1177 if (!np_name->Equals(h_method_name.Get()) || !np_method->EqualParameters(h_args)) {
1178 if (UNLIKELY(self->IsExceptionPending())) {
1179 return nullptr;
1180 }
1181 continue;
1182 }
1183 auto modifiers = m.GetAccessFlags();
1184 if ((modifiers & kSkipModifiers) == 0) {
1185 return Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, &m);
1186 }
1187 if ((modifiers & kAccMiranda) == 0) {
1188 result = &m; // Remember as potential result if it's not a miranda method.
1189 }
1190 }
1191 if (result == nullptr) {
1192 for (auto& m : h_klass->GetDirectMethods(kPointerSize)) {
1193 auto modifiers = m.GetAccessFlags();
1194 if ((modifiers & kAccConstructor) != 0) {
1195 continue;
1196 }
1197 auto* np_method = m.GetInterfaceMethodIfProxy(kPointerSize);
1198 // May cause thread suspension.
1199 ObjPtr<String> np_name = np_method->GetNameAsString(self);
1200 if (np_name == nullptr) {
1201 self->AssertPendingException();
1202 return nullptr;
1203 }
1204 if (!np_name->Equals(h_method_name.Get()) || !np_method->EqualParameters(h_args)) {
1205 if (UNLIKELY(self->IsExceptionPending())) {
1206 return nullptr;
1207 }
1208 continue;
1209 }
1210 if ((modifiers & kSkipModifiers) == 0) {
1211 return Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, &m);
1212 }
1213 // Direct methods cannot be miranda methods, so this potential result must be synthetic.
1214 result = &m;
1215 }
1216 }
1217 return result != nullptr
1218 ? Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, result)
1219 : nullptr;
1220 }
1221
1222 template
1223 ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
1224 Thread* self,
1225 ObjPtr<Class> klass,
1226 ObjPtr<String> name,
1227 ObjPtr<ObjectArray<Class>> args);
1228 template
1229 ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
1230 Thread* self,
1231 ObjPtr<Class> klass,
1232 ObjPtr<String> name,
1233 ObjPtr<ObjectArray<Class>> args);
1234 template
1235 ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
1236 Thread* self,
1237 ObjPtr<Class> klass,
1238 ObjPtr<String> name,
1239 ObjPtr<ObjectArray<Class>> args);
1240 template
1241 ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
1242 Thread* self,
1243 ObjPtr<Class> klass,
1244 ObjPtr<String> name,
1245 ObjPtr<ObjectArray<Class>> args);
1246
1247 template <PointerSize kPointerSize, bool kTransactionActive>
GetDeclaredConstructorInternal(Thread * self,ObjPtr<Class> klass,ObjPtr<ObjectArray<Class>> args)1248 ObjPtr<Constructor> Class::GetDeclaredConstructorInternal(
1249 Thread* self,
1250 ObjPtr<Class> klass,
1251 ObjPtr<ObjectArray<Class>> args) {
1252 StackHandleScope<1> hs(self);
1253 ArtMethod* result = klass->GetDeclaredConstructor(self, hs.NewHandle(args), kPointerSize);
1254 return result != nullptr
1255 ? Constructor::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, result)
1256 : nullptr;
1257 }
1258
1259 // Constructor::CreateFromArtMethod<kTransactionActive>(self, result)
1260
1261 template
1262 ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k32, false>(
1263 Thread* self,
1264 ObjPtr<Class> klass,
1265 ObjPtr<ObjectArray<Class>> args);
1266 template
1267 ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k32, true>(
1268 Thread* self,
1269 ObjPtr<Class> klass,
1270 ObjPtr<ObjectArray<Class>> args);
1271 template
1272 ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k64, false>(
1273 Thread* self,
1274 ObjPtr<Class> klass,
1275 ObjPtr<ObjectArray<Class>> args);
1276 template
1277 ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k64, true>(
1278 Thread* self,
1279 ObjPtr<Class> klass,
1280 ObjPtr<ObjectArray<Class>> args);
1281
GetInnerClassFlags(Handle<Class> h_this,int32_t default_value)1282 int32_t Class::GetInnerClassFlags(Handle<Class> h_this, int32_t default_value) {
1283 if (h_this->IsProxyClass() || h_this->GetDexCache() == nullptr) {
1284 return default_value;
1285 }
1286 uint32_t flags;
1287 if (!annotations::GetInnerClassFlags(h_this, &flags)) {
1288 return default_value;
1289 }
1290 return flags;
1291 }
1292
SetObjectSizeAllocFastPath(uint32_t new_object_size)1293 void Class::SetObjectSizeAllocFastPath(uint32_t new_object_size) {
1294 if (Runtime::Current()->IsActiveTransaction()) {
1295 SetField32Volatile<true>(ObjectSizeAllocFastPathOffset(), new_object_size);
1296 } else {
1297 SetField32Volatile<false>(ObjectSizeAllocFastPathOffset(), new_object_size);
1298 }
1299 }
1300
PrettyDescriptor(ObjPtr<mirror::Class> klass)1301 std::string Class::PrettyDescriptor(ObjPtr<mirror::Class> klass) {
1302 if (klass == nullptr) {
1303 return "null";
1304 }
1305 return klass->PrettyDescriptor();
1306 }
1307
PrettyDescriptor()1308 std::string Class::PrettyDescriptor() {
1309 std::string temp;
1310 return art::PrettyDescriptor(GetDescriptor(&temp));
1311 }
1312
PrettyClass(ObjPtr<mirror::Class> c)1313 std::string Class::PrettyClass(ObjPtr<mirror::Class> c) {
1314 if (c == nullptr) {
1315 return "null";
1316 }
1317 return c->PrettyClass();
1318 }
1319
PrettyClass()1320 std::string Class::PrettyClass() {
1321 std::string result;
1322 result += "java.lang.Class<";
1323 result += PrettyDescriptor();
1324 result += ">";
1325 return result;
1326 }
1327
PrettyClassAndClassLoader(ObjPtr<mirror::Class> c)1328 std::string Class::PrettyClassAndClassLoader(ObjPtr<mirror::Class> c) {
1329 if (c == nullptr) {
1330 return "null";
1331 }
1332 return c->PrettyClassAndClassLoader();
1333 }
1334
PrettyClassAndClassLoader()1335 std::string Class::PrettyClassAndClassLoader() {
1336 std::string result;
1337 result += "java.lang.Class<";
1338 result += PrettyDescriptor();
1339 result += ",";
1340 result += mirror::Object::PrettyTypeOf(GetClassLoader());
1341 // TODO: add an identifying hash value for the loader
1342 result += ">";
1343 return result;
1344 }
1345
GetAccessFlagsDCheck()1346 template<VerifyObjectFlags kVerifyFlags> void Class::GetAccessFlagsDCheck() {
1347 // Check class is loaded/retired or this is java.lang.String that has a
1348 // circularity issue during loading the names of its members
1349 DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
1350 IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
1351 this == String::GetJavaLangString())
1352 << "IsIdxLoaded=" << IsIdxLoaded<kVerifyFlags>()
1353 << " IsRetired=" << IsRetired<kVerifyFlags>()
1354 << " IsErroneous=" <<
1355 IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>()
1356 << " IsString=" << (this == String::GetJavaLangString())
1357 << " status= " << GetStatus<kVerifyFlags>()
1358 << " descriptor=" << PrettyDescriptor();
1359 }
1360 // Instantiate the common cases.
1361 template void Class::GetAccessFlagsDCheck<kVerifyNone>();
1362 template void Class::GetAccessFlagsDCheck<kVerifyThis>();
1363 template void Class::GetAccessFlagsDCheck<kVerifyReads>();
1364 template void Class::GetAccessFlagsDCheck<kVerifyWrites>();
1365 template void Class::GetAccessFlagsDCheck<kVerifyAll>();
1366
1367 } // namespace mirror
1368 } // namespace art
1369