• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SetClassClass(Class * java_lang_Class)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 
ResetClass()48 void Class::ResetClass() {
49   CHECK(java_lang_Class_ != NULL);
50   java_lang_Class_ = NULL;
51 }
52 
SetStatus(Status new_status,Thread * self)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 
SetDexCache(DexCache * new_dex_cache)117 void Class::SetDexCache(DexCache* new_dex_cache) {
118   SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false);
119 }
120 
AllocObject(Thread * self)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 
SetClassSize(size_t new_class_size)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.
ComputeName()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 
DumpClass(std::ostream & os,int flags) const180 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 
SetReferenceInstanceOffsets(uint32_t new_reference_offsets)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 
SetReferenceStaticOffsets(uint32_t new_reference_offsets)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 
IsInSamePackage(const StringPiece & descriptor1,const StringPiece & descriptor2)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 
IsInSamePackage(const Class * that) const284 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 
IsClassClass() const310 bool Class::IsClassClass() const {
311   Class* java_lang_Class = GetClass()->GetClass();
312   return this == java_lang_Class;
313 }
314 
IsStringClass() const315 bool Class::IsStringClass() const {
316   return this == String::GetJavaLangString();
317 }
318 
IsThrowableClass() const319 bool Class::IsThrowableClass() const {
320   return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this);
321 }
322 
IsArtFieldClass() const323 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 
IsArtMethodClass() const329 bool Class::IsArtMethodClass() const {
330   return this == ArtMethod::GetJavaLangReflectArtMethod();
331 }
332 
SetClassLoader(ClassLoader * new_class_loader)333 void Class::SetClassLoader(ClassLoader* new_class_loader) {
334   SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false);
335 }
336 
FindInterfaceMethod(const StringPiece & name,const StringPiece & signature) const337 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 
FindInterfaceMethod(const DexCache * dex_cache,uint32_t dex_method_idx) const355 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 
FindDeclaredDirectMethod(const StringPiece & name,const StringPiece & signature) const374 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 
FindDeclaredDirectMethod(const DexCache * dex_cache,uint32_t dex_method_idx) const386 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 
FindDirectMethod(const StringPiece & name,const StringPiece & signature) const398 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 
FindDirectMethod(const DexCache * dex_cache,uint32_t dex_method_idx) const408 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 
FindDeclaredVirtualMethod(const StringPiece & name,const StringPiece & signature) const418 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 
FindDeclaredVirtualMethod(const DexCache * dex_cache,uint32_t dex_method_idx) const431 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 
FindVirtualMethod(const StringPiece & name,const StringPiece & signature) const443 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 
FindVirtualMethod(const DexCache * dex_cache,uint32_t dex_method_idx) const453 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 
FindDeclaredInstanceField(const StringPiece & name,const StringPiece & type)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 
FindDeclaredInstanceField(const DexCache * dex_cache,uint32_t dex_field_idx)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 
FindInstanceField(const StringPiece & name,const StringPiece & type)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 
FindInstanceField(const DexCache * dex_cache,uint32_t dex_field_idx)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 
FindDeclaredStaticField(const StringPiece & name,const StringPiece & type)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 
FindDeclaredStaticField(const DexCache * dex_cache,uint32_t dex_field_idx)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 
FindStaticField(const StringPiece & name,const StringPiece & type)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 
FindStaticField(const DexCache * dex_cache,uint32_t dex_field_idx)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 
FindField(const StringPiece & name,const StringPiece & type)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 
SetPreverifiedFlagOnMethods(mirror::ObjectArray<mirror::ArtMethod> * methods)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 
SetPreverifiedFlagOnAllMethods()619 void Class::SetPreverifiedFlagOnAllMethods() {
620   DCHECK(IsVerified());
621   SetPreverifiedFlagOnMethods(GetDirectMethods());
622   SetPreverifiedFlagOnMethods(GetVirtualMethods());
623 }
624 
625 }  // namespace mirror
626 }  // namespace art
627