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