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