class.cc revision b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cf
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);
118  } else {
119    SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
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);
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);
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);
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);
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);
334  } else {
335    SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader);
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