class.cc revision 9103c86a98524e9ddfd14f8cee56e919f68eee9b
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 "art_field-inl.h" 20#include "art_method-inl.h" 21#include "class-inl.h" 22#include "class_linker.h" 23#include "class_loader.h" 24#include "dex_cache.h" 25#include "dex_file-inl.h" 26#include "gc/accounting/card_table-inl.h" 27#include "object-inl.h" 28#include "object_array-inl.h" 29#include "object_utils.h" 30#include "runtime.h" 31#include "sirt_ref.h" 32#include "thread.h" 33#include "throwable.h" 34#include "utils.h" 35#include "well_known_classes.h" 36 37namespace art { 38namespace mirror { 39 40Class* Class::java_lang_Class_ = NULL; 41 42void Class::SetClassClass(Class* java_lang_Class) { 43 CHECK(java_lang_Class_ == NULL) << java_lang_Class_ << " " << java_lang_Class; 44 CHECK(java_lang_Class != NULL); 45 java_lang_Class_ = java_lang_Class; 46} 47 48void Class::ResetClass() { 49 CHECK(java_lang_Class_ != NULL); 50 java_lang_Class_ = NULL; 51} 52 53void Class::VisitRoots(RootCallback* callback, void* arg) { 54 if (java_lang_Class_ != nullptr) { 55 callback(reinterpret_cast<mirror::Object**>(&java_lang_Class_), arg, 0, kRootStickyClass); 56 } 57} 58 59void Class::SetStatus(Status new_status, Thread* self) { 60 Status old_status = GetStatus(); 61 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 62 bool class_linker_initialized = class_linker != nullptr && class_linker->IsInitialized(); 63 if (LIKELY(class_linker_initialized)) { 64 if (UNLIKELY(new_status <= old_status && new_status != kStatusError)) { 65 LOG(FATAL) << "Unexpected change back of class status for " << PrettyClass(this) << " " 66 << old_status << " -> " << new_status; 67 } 68 if (new_status >= kStatusResolved || old_status >= kStatusResolved) { 69 // When classes are being resolved the resolution code should hold the lock. 70 CHECK_EQ(GetLockOwnerThreadId(), self->GetThreadId()) 71 << "Attempt to change status of class while not holding its lock: " 72 << PrettyClass(this) << " " << old_status << " -> " << new_status; 73 } 74 } 75 if (UNLIKELY(new_status == kStatusError)) { 76 CHECK_NE(GetStatus(), kStatusError) 77 << "Attempt to set as erroneous an already erroneous class " << PrettyClass(this); 78 79 // Stash current exception. 80 SirtRef<mirror::Object> old_throw_this_object(self, NULL); 81 SirtRef<mirror::ArtMethod> old_throw_method(self, NULL); 82 SirtRef<mirror::Throwable> old_exception(self, NULL); 83 uint32_t old_throw_dex_pc; 84 { 85 ThrowLocation old_throw_location; 86 mirror::Throwable* old_exception_obj = self->GetException(&old_throw_location); 87 old_throw_this_object.reset(old_throw_location.GetThis()); 88 old_throw_method.reset(old_throw_location.GetMethod()); 89 old_exception.reset(old_exception_obj); 90 old_throw_dex_pc = old_throw_location.GetDexPc(); 91 self->ClearException(); 92 } 93 CHECK(old_exception.get() != NULL); 94 95 // clear exception to call FindSystemClass 96 self->ClearException(); 97 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 98 Class* eiie_class = class_linker->FindSystemClass(self, 99 "Ljava/lang/ExceptionInInitializerError;"); 100 CHECK(!self->IsExceptionPending()); 101 102 // Only verification errors, not initialization problems, should set a verify error. 103 // This is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case. 104 Class* exception_class = old_exception->GetClass(); 105 if (!eiie_class->IsAssignableFrom(exception_class)) { 106 SetVerifyErrorClass(exception_class); 107 } 108 109 // Restore exception. 110 ThrowLocation gc_safe_throw_location(old_throw_this_object.get(), old_throw_method.get(), 111 old_throw_dex_pc); 112 113 self->SetException(gc_safe_throw_location, old_exception.get()); 114 } 115 CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this); 116 if (Runtime::Current()->IsActiveTransaction()) { 117 SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false); 118 } else { 119 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false); 120 } 121 // Classes that are being resolved or initialized need to notify waiters that the class status 122 // changed. See ClassLinker::EnsureResolved and ClassLinker::WaitForInitializeClass. 123 if ((old_status >= kStatusResolved || new_status >= kStatusResolved) && 124 class_linker_initialized) { 125 NotifyAll(self); 126 } 127} 128 129void Class::SetDexCache(DexCache* new_dex_cache) { 130 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false); 131} 132 133void Class::SetClassSize(uint32_t new_class_size) { 134 if (kIsDebugBuild && (new_class_size < GetClassSize())) { 135 DumpClass(LOG(ERROR), kDumpClassFullDetail); 136 CHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this); 137 } 138 // Not called within a transaction. 139 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false); 140} 141 142// Return the class' name. The exact format is bizarre, but it's the specified behavior for 143// Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int" 144// but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than 145// slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness. 146String* Class::ComputeName() { 147 String* name = GetName(); 148 if (name != nullptr) { 149 return name; 150 } 151 Thread* self = Thread::Current(); 152 SirtRef<mirror::Class> sirt_c(self, this); 153 std::string descriptor(ClassHelper(this).GetDescriptor()); 154 if ((descriptor[0] != 'L') && (descriptor[0] != '[')) { 155 // The descriptor indicates that this is the class for 156 // a primitive type; special-case the return value. 157 const char* c_name = NULL; 158 switch (descriptor[0]) { 159 case 'Z': c_name = "boolean"; break; 160 case 'B': c_name = "byte"; break; 161 case 'C': c_name = "char"; break; 162 case 'S': c_name = "short"; break; 163 case 'I': c_name = "int"; break; 164 case 'J': c_name = "long"; break; 165 case 'F': c_name = "float"; break; 166 case 'D': c_name = "double"; break; 167 case 'V': c_name = "void"; break; 168 default: 169 LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]); 170 } 171 name = String::AllocFromModifiedUtf8(self, c_name); 172 } else { 173 // Convert the UTF-8 name to a java.lang.String. The name must use '.' to separate package 174 // components. 175 if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') { 176 descriptor.erase(0, 1); 177 descriptor.erase(descriptor.size() - 1); 178 } 179 std::replace(descriptor.begin(), descriptor.end(), '/', '.'); 180 name = String::AllocFromModifiedUtf8(self, descriptor.c_str()); 181 } 182 sirt_c->SetName(name); 183 return name; 184} 185 186void Class::DumpClass(std::ostream& os, int flags) { 187 if ((flags & kDumpClassFullDetail) == 0) { 188 os << PrettyClass(this); 189 if ((flags & kDumpClassClassLoader) != 0) { 190 os << ' ' << GetClassLoader(); 191 } 192 if ((flags & kDumpClassInitialized) != 0) { 193 os << ' ' << GetStatus(); 194 } 195 os << "\n"; 196 return; 197 } 198 199 Class* super = GetSuperClass(); 200 ClassHelper kh(this); 201 os << "----- " << (IsInterface() ? "interface" : "class") << " " 202 << "'" << kh.GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n", 203 os << " objectSize=" << SizeOf() << " " 204 << "(" << (super != NULL ? super->SizeOf() : -1) << " from super)\n", 205 os << StringPrintf(" access=0x%04x.%04x\n", 206 GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask); 207 if (super != NULL) { 208 os << " super='" << PrettyClass(super) << "' (cl=" << super->GetClassLoader() << ")\n"; 209 } 210 if (IsArrayClass()) { 211 os << " componentType=" << PrettyClass(GetComponentType()) << "\n"; 212 } 213 if (kh.NumDirectInterfaces() > 0) { 214 os << " interfaces (" << kh.NumDirectInterfaces() << "):\n"; 215 for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 216 Class* interface = kh.GetDirectInterface(i); 217 const ClassLoader* cl = interface->GetClassLoader(); 218 os << StringPrintf(" %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl); 219 } 220 } 221 os << " vtable (" << NumVirtualMethods() << " entries, " 222 << (super != NULL ? super->NumVirtualMethods() : 0) << " in super):\n"; 223 for (size_t i = 0; i < NumVirtualMethods(); ++i) { 224 os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetVirtualMethodDuringLinking(i)).c_str()); 225 } 226 os << " direct methods (" << NumDirectMethods() << " entries):\n"; 227 for (size_t i = 0; i < NumDirectMethods(); ++i) { 228 os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetDirectMethod(i)).c_str()); 229 } 230 if (NumStaticFields() > 0) { 231 os << " static fields (" << NumStaticFields() << " entries):\n"; 232 if (IsResolved() || IsErroneous()) { 233 for (size_t i = 0; i < NumStaticFields(); ++i) { 234 os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetStaticField(i)).c_str()); 235 } 236 } else { 237 os << " <not yet available>"; 238 } 239 } 240 if (NumInstanceFields() > 0) { 241 os << " instance fields (" << NumInstanceFields() << " entries):\n"; 242 if (IsResolved() || IsErroneous()) { 243 for (size_t i = 0; i < NumInstanceFields(); ++i) { 244 os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetInstanceField(i)).c_str()); 245 } 246 } else { 247 os << " <not yet available>"; 248 } 249 } 250} 251 252void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) { 253 if (new_reference_offsets != CLASS_WALK_SUPER) { 254 // Sanity check that the number of bits set in the reference offset bitmap 255 // agrees with the number of references 256 size_t count = 0; 257 for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 258 count += c->NumReferenceInstanceFieldsDuringLinking(); 259 } 260 CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), count); 261 } 262 // Not called within a transaction. 263 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_), 264 new_reference_offsets, false); 265} 266 267void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) { 268 if (new_reference_offsets != CLASS_WALK_SUPER) { 269 // Sanity check that the number of bits set in the reference offset bitmap 270 // agrees with the number of references 271 CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), 272 NumReferenceStaticFieldsDuringLinking()); 273 } 274 // Not called within a transaction. 275 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_), 276 new_reference_offsets, false); 277} 278 279bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) { 280 size_t i = 0; 281 while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) { 282 ++i; 283 } 284 if (descriptor1.find('/', i) != StringPiece::npos || 285 descriptor2.find('/', i) != StringPiece::npos) { 286 return false; 287 } else { 288 return true; 289 } 290} 291 292bool Class::IsInSamePackage(Class* that) { 293 Class* klass1 = this; 294 Class* klass2 = that; 295 if (klass1 == klass2) { 296 return true; 297 } 298 // Class loaders must match. 299 if (klass1->GetClassLoader() != klass2->GetClassLoader()) { 300 return false; 301 } 302 // Arrays are in the same package when their element classes are. 303 while (klass1->IsArrayClass()) { 304 klass1 = klass1->GetComponentType(); 305 } 306 while (klass2->IsArrayClass()) { 307 klass2 = klass2->GetComponentType(); 308 } 309 // trivial check again for array types 310 if (klass1 == klass2) { 311 return true; 312 } 313 // Compare the package part of the descriptor string. 314 return IsInSamePackage(ClassHelper(klass1).GetDescriptor(), 315 ClassHelper(klass2).GetDescriptor()); 316} 317 318bool Class::IsClassClass() { 319 Class* java_lang_Class = GetClass()->GetClass(); 320 return this == java_lang_Class; 321} 322 323bool Class::IsStringClass() const { 324 return this == String::GetJavaLangString(); 325} 326 327bool Class::IsThrowableClass() { 328 return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this); 329} 330 331void Class::SetClassLoader(ClassLoader* new_class_loader) { 332 if (Runtime::Current()->IsActiveTransaction()) { 333 SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false); 334 } else { 335 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false); 336 } 337} 338 339ArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const Signature& signature) { 340 // Check the current class before checking the interfaces. 341 ArtMethod* method = FindDeclaredVirtualMethod(name, signature); 342 if (method != NULL) { 343 return method; 344 } 345 346 int32_t iftable_count = GetIfTableCount(); 347 IfTable* iftable = GetIfTable(); 348 for (int32_t i = 0; i < iftable_count; i++) { 349 method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature); 350 if (method != NULL) { 351 return method; 352 } 353 } 354 return NULL; 355} 356 357ArtMethod* Class::FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) { 358 // Check the current class before checking the interfaces. 359 ArtMethod* method = FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 360 if (method != NULL) { 361 return method; 362 } 363 364 int32_t iftable_count = GetIfTableCount(); 365 IfTable* iftable = GetIfTable(); 366 for (int32_t i = 0; i < iftable_count; i++) { 367 method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 368 if (method != NULL) { 369 return method; 370 } 371 } 372 return NULL; 373} 374 375ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) { 376 MethodHelper mh; 377 for (size_t i = 0; i < NumDirectMethods(); ++i) { 378 ArtMethod* method = GetDirectMethod(i); 379 mh.ChangeMethod(method); 380 if (name == mh.GetName() && mh.GetSignature() == signature) { 381 return method; 382 } 383 } 384 return NULL; 385} 386 387ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const Signature& signature) { 388 MethodHelper mh; 389 for (size_t i = 0; i < NumDirectMethods(); ++i) { 390 ArtMethod* method = GetDirectMethod(i); 391 mh.ChangeMethod(method); 392 if (name == mh.GetName() && signature == mh.GetSignature()) { 393 return method; 394 } 395 } 396 return NULL; 397} 398 399ArtMethod* Class::FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) { 400 if (GetDexCache() == dex_cache) { 401 for (size_t i = 0; i < NumDirectMethods(); ++i) { 402 ArtMethod* method = GetDirectMethod(i); 403 if (method->GetDexMethodIndex() == dex_method_idx) { 404 return method; 405 } 406 } 407 } 408 return NULL; 409} 410 411ArtMethod* Class::FindDirectMethod(const StringPiece& name, const StringPiece& signature) { 412 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 413 ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature); 414 if (method != NULL) { 415 return method; 416 } 417 } 418 return NULL; 419} 420 421ArtMethod* Class::FindDirectMethod(const StringPiece& name, const Signature& signature) { 422 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 423 ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature); 424 if (method != NULL) { 425 return method; 426 } 427 } 428 return NULL; 429} 430 431ArtMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) { 432 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 433 ArtMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx); 434 if (method != NULL) { 435 return method; 436 } 437 } 438 return NULL; 439} 440 441ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) { 442 MethodHelper mh; 443 for (size_t i = 0; i < NumVirtualMethods(); ++i) { 444 ArtMethod* method = GetVirtualMethod(i); 445 mh.ChangeMethod(method); 446 if (name == mh.GetName() && mh.GetSignature() == signature) { 447 return method; 448 } 449 } 450 return NULL; 451} 452 453ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, 454 const Signature& signature) { 455 MethodHelper mh; 456 for (size_t i = 0; i < NumVirtualMethods(); ++i) { 457 ArtMethod* method = GetVirtualMethod(i); 458 mh.ChangeMethod(method); 459 if (name == mh.GetName() && signature == mh.GetSignature()) { 460 return method; 461 } 462 } 463 return NULL; 464} 465 466ArtMethod* Class::FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) { 467 if (GetDexCache() == dex_cache) { 468 for (size_t i = 0; i < NumVirtualMethods(); ++i) { 469 ArtMethod* method = GetVirtualMethod(i); 470 if (method->GetDexMethodIndex() == dex_method_idx) { 471 return method; 472 } 473 } 474 } 475 return NULL; 476} 477 478ArtMethod* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) { 479 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 480 ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature); 481 if (method != NULL) { 482 return method; 483 } 484 } 485 return NULL; 486} 487 488ArtMethod* Class::FindVirtualMethod(const StringPiece& name, const Signature& signature) { 489 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 490 ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature); 491 if (method != NULL) { 492 return method; 493 } 494 } 495 return NULL; 496} 497 498ArtMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) { 499 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 500 ArtMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 501 if (method != NULL) { 502 return method; 503 } 504 } 505 return NULL; 506} 507 508ArtMethod* Class::FindClassInitializer() { 509 for (size_t i = 0; i < NumDirectMethods(); ++i) { 510 ArtMethod* method = GetDirectMethod(i); 511 if (method->IsConstructor() && method->IsStatic()) { 512 if (kIsDebugBuild) { 513 MethodHelper mh(method); 514 CHECK(mh.IsClassInitializer()); 515 CHECK_STREQ(mh.GetName(), "<clinit>"); 516 CHECK_STREQ(mh.GetSignature().ToString().c_str(), "()V"); 517 } 518 return method; 519 } 520 } 521 return NULL; 522} 523 524ArtField* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) { 525 // Is the field in this class? 526 // Interfaces are not relevant because they can't contain instance fields. 527 FieldHelper fh; 528 for (size_t i = 0; i < NumInstanceFields(); ++i) { 529 ArtField* f = GetInstanceField(i); 530 fh.ChangeField(f); 531 if (name == fh.GetName() && type == fh.GetTypeDescriptor()) { 532 return f; 533 } 534 } 535 return NULL; 536} 537 538ArtField* Class::FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) { 539 if (GetDexCache() == dex_cache) { 540 for (size_t i = 0; i < NumInstanceFields(); ++i) { 541 ArtField* f = GetInstanceField(i); 542 if (f->GetDexFieldIndex() == dex_field_idx) { 543 return f; 544 } 545 } 546 } 547 return NULL; 548} 549 550ArtField* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) { 551 // Is the field in this class, or any of its superclasses? 552 // Interfaces are not relevant because they can't contain instance fields. 553 for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 554 ArtField* f = c->FindDeclaredInstanceField(name, type); 555 if (f != NULL) { 556 return f; 557 } 558 } 559 return NULL; 560} 561 562ArtField* Class::FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) { 563 // Is the field in this class, or any of its superclasses? 564 // Interfaces are not relevant because they can't contain instance fields. 565 for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 566 ArtField* f = c->FindDeclaredInstanceField(dex_cache, dex_field_idx); 567 if (f != NULL) { 568 return f; 569 } 570 } 571 return NULL; 572} 573 574ArtField* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) { 575 DCHECK(type != NULL); 576 FieldHelper fh; 577 for (size_t i = 0; i < NumStaticFields(); ++i) { 578 ArtField* f = GetStaticField(i); 579 fh.ChangeField(f); 580 if (name == fh.GetName() && type == fh.GetTypeDescriptor()) { 581 return f; 582 } 583 } 584 return NULL; 585} 586 587ArtField* Class::FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) { 588 if (dex_cache == GetDexCache()) { 589 for (size_t i = 0; i < NumStaticFields(); ++i) { 590 ArtField* f = GetStaticField(i); 591 if (f->GetDexFieldIndex() == dex_field_idx) { 592 return f; 593 } 594 } 595 } 596 return NULL; 597} 598 599ArtField* Class::FindStaticField(const StringPiece& name, const StringPiece& type) { 600 // Is the field in this class (or its interfaces), or any of its 601 // superclasses (or their interfaces)? 602 for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 603 // Is the field in this class? 604 ArtField* f = k->FindDeclaredStaticField(name, type); 605 if (f != NULL) { 606 return f; 607 } 608 // Is this field in any of this class' interfaces? 609 ClassHelper kh(k); 610 for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 611 Class* interface = kh.GetDirectInterface(i); 612 f = interface->FindStaticField(name, type); 613 if (f != NULL) { 614 return f; 615 } 616 } 617 } 618 return NULL; 619} 620 621ArtField* Class::FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) { 622 for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 623 // Is the field in this class? 624 ArtField* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx); 625 if (f != NULL) { 626 return f; 627 } 628 // Is this field in any of this class' interfaces? 629 ClassHelper kh(k); 630 for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 631 Class* interface = kh.GetDirectInterface(i); 632 f = interface->FindStaticField(dex_cache, dex_field_idx); 633 if (f != NULL) { 634 return f; 635 } 636 } 637 } 638 return NULL; 639} 640 641ArtField* Class::FindField(const StringPiece& name, const StringPiece& type) { 642 // Find a field using the JLS field resolution order 643 for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 644 // Is the field in this class? 645 ArtField* f = k->FindDeclaredInstanceField(name, type); 646 if (f != NULL) { 647 return f; 648 } 649 f = k->FindDeclaredStaticField(name, type); 650 if (f != NULL) { 651 return f; 652 } 653 // Is this field in any of this class' interfaces? 654 ClassHelper kh(k); 655 for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 656 Class* interface = kh.GetDirectInterface(i); 657 f = interface->FindStaticField(name, type); 658 if (f != NULL) { 659 return f; 660 } 661 } 662 } 663 return NULL; 664} 665 666static void SetPreverifiedFlagOnMethods(mirror::ObjectArray<mirror::ArtMethod>* methods) 667 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 668 if (methods != NULL) { 669 for (int32_t index = 0, end = methods->GetLength(); index < end; ++index) { 670 mirror::ArtMethod* method = methods->GetWithoutChecks(index); 671 DCHECK(method != NULL); 672 if (!method->IsNative() && !method->IsAbstract()) { 673 method->SetPreverified(); 674 } 675 } 676 } 677} 678 679void Class::SetPreverifiedFlagOnAllMethods() { 680 DCHECK(IsVerified()); 681 SetPreverifiedFlagOnMethods(GetDirectMethods()); 682 SetPreverifiedFlagOnMethods(GetVirtualMethods()); 683} 684 685} // namespace mirror 686} // namespace art 687