class.cc revision 4f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5
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 "handle_scope-inl.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_ = nullptr;
41
42void Class::SetClassClass(Class* java_lang_Class) {
43  CHECK(java_lang_Class_ == nullptr)
44      << ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>(&java_lang_Class_)
45      << " " << java_lang_Class;
46  CHECK(java_lang_Class != nullptr);
47  java_lang_Class_ = java_lang_Class;
48}
49
50void Class::ResetClass() {
51  CHECK(java_lang_Class_ != nullptr);
52  java_lang_Class_ = nullptr;
53}
54
55void Class::VisitRoots(RootCallback* callback, void* arg) {
56  if (java_lang_Class_ != nullptr) {
57    callback(reinterpret_cast<mirror::Object**>(&java_lang_Class_), arg, 0, kRootStickyClass);
58  }
59}
60
61void Class::SetStatus(Status new_status, Thread* self) {
62  Status old_status = GetStatus();
63  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
64  bool class_linker_initialized = class_linker != nullptr && class_linker->IsInitialized();
65  if (LIKELY(class_linker_initialized)) {
66    if (UNLIKELY(new_status <= old_status && new_status != kStatusError)) {
67      LOG(FATAL) << "Unexpected change back of class status for " << PrettyClass(this) << " "
68          << old_status << " -> " << new_status;
69    }
70    if (new_status >= kStatusResolved || old_status >= kStatusResolved) {
71      // When classes are being resolved the resolution code should hold the lock.
72      CHECK_EQ(GetLockOwnerThreadId(), self->GetThreadId())
73            << "Attempt to change status of class while not holding its lock: "
74            << PrettyClass(this) << " " << old_status << " -> " << new_status;
75    }
76  }
77  if (UNLIKELY(new_status == kStatusError)) {
78    CHECK_NE(GetStatus(), kStatusError)
79        << "Attempt to set as erroneous an already erroneous class " << PrettyClass(this);
80
81    // Stash current exception.
82    StackHandleScope<3> hs(self);
83    ThrowLocation old_throw_location;
84    Handle<mirror::Throwable> old_exception(hs.NewHandle(self->GetException(&old_throw_location)));
85    CHECK(old_exception.Get() != nullptr);
86    Handle<mirror::Object> old_throw_this_object(hs.NewHandle(old_throw_location.GetThis()));
87    Handle<mirror::ArtMethod> old_throw_method(hs.NewHandle(old_throw_location.GetMethod()));
88    uint32_t old_throw_dex_pc = old_throw_location.GetDexPc();
89    bool is_exception_reported = self->IsExceptionReportedToInstrumentation();
90    // clear exception to call FindSystemClass
91    self->ClearException();
92    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
93    Class* eiie_class = class_linker->FindSystemClass(self,
94                                                      "Ljava/lang/ExceptionInInitializerError;");
95    CHECK(!self->IsExceptionPending());
96
97    // Only verification errors, not initialization problems, should set a verify error.
98    // This is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case.
99    Class* exception_class = old_exception->GetClass();
100    if (!eiie_class->IsAssignableFrom(exception_class)) {
101      SetVerifyErrorClass(exception_class);
102    }
103
104    // Restore exception.
105    ThrowLocation gc_safe_throw_location(old_throw_this_object.Get(), old_throw_method.Get(),
106                                         old_throw_dex_pc);
107    self->SetException(gc_safe_throw_location, old_exception.Get());
108    self->SetExceptionReportedToInstrumentation(is_exception_reported);
109  }
110  COMPILE_ASSERT(sizeof(Status) == sizeof(uint32_t), size_of_status_not_uint32);
111  if (Runtime::Current()->IsActiveTransaction()) {
112    SetField32Volatile<true>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
113  } else {
114    SetField32Volatile<false>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
115  }
116  // Classes that are being resolved or initialized need to notify waiters that the class status
117  // changed. See ClassLinker::EnsureResolved and ClassLinker::WaitForInitializeClass.
118  if ((old_status >= kStatusResolved || new_status >= kStatusResolved) &&
119      class_linker_initialized) {
120    NotifyAll(self);
121  }
122}
123
124void Class::SetDexCache(DexCache* new_dex_cache) {
125  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache);
126}
127
128void Class::SetClassSize(uint32_t new_class_size) {
129  if (kIsDebugBuild && (new_class_size < GetClassSize())) {
130    DumpClass(LOG(ERROR), kDumpClassFullDetail);
131    CHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
132  }
133  // Not called within a transaction.
134  SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size);
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(Handle<Class> h_this) {
142  String* name = h_this->GetName();
143  if (name != nullptr) {
144    return name;
145  }
146  std::string descriptor(h_this->GetDescriptor());
147  Thread* self = Thread::Current();
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 = nullptr;
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(self, 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(self, descriptor.c_str());
175  }
176  h_this->SetName(name);
177  return name;
178}
179
180void Class::DumpClass(std::ostream& os, int flags) {
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  Thread* self = Thread::Current();
194  StackHandleScope<2> hs(self);
195  Handle<mirror::Class> h_this(hs.NewHandle(this));
196  Handle<mirror::Class> h_super(hs.NewHandle(GetSuperClass()));
197
198  os << "----- " << (IsInterface() ? "interface" : "class") << " "
199     << "'" << GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n",
200  os << "  objectSize=" << SizeOf() << " "
201     << "(" << (h_super.Get() != nullptr ? h_super->SizeOf() : -1) << " from super)\n",
202  os << StringPrintf("  access=0x%04x.%04x\n",
203      GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
204  if (h_super.Get() != nullptr) {
205    os << "  super='" << PrettyClass(h_super.Get()) << "' (cl=" << h_super->GetClassLoader()
206       << ")\n";
207  }
208  if (IsArrayClass()) {
209    os << "  componentType=" << PrettyClass(GetComponentType()) << "\n";
210  }
211  const size_t num_direct_interfaces = NumDirectInterfaces();
212  if (num_direct_interfaces > 0) {
213    os << "  interfaces (" << num_direct_interfaces << "):\n";
214    for (size_t i = 0; i < num_direct_interfaces; ++i) {
215      Class* interface = GetDirectInterface(self, h_this, i);
216      const ClassLoader* cl = interface->GetClassLoader();
217      os << StringPrintf("    %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl);
218    }
219  }
220  // After this point, this may have moved due to GetDirectInterface.
221  os << "  vtable (" << h_this->NumVirtualMethods() << " entries, "
222     << (h_super.Get() != nullptr ? h_super->NumVirtualMethods() : 0) << " in super):\n";
223  for (size_t i = 0; i < NumVirtualMethods(); ++i) {
224    os << StringPrintf("    %2zd: %s\n", i,
225                       PrettyMethod(h_this->GetVirtualMethodDuringLinking(i)).c_str());
226  }
227  os << "  direct methods (" << h_this->NumDirectMethods() << " entries):\n";
228  for (size_t i = 0; i < h_this->NumDirectMethods(); ++i) {
229    os << StringPrintf("    %2zd: %s\n", i, PrettyMethod(h_this->GetDirectMethod(i)).c_str());
230  }
231  if (h_this->NumStaticFields() > 0) {
232    os << "  static fields (" << h_this->NumStaticFields() << " entries):\n";
233    if (h_this->IsResolved() || h_this->IsErroneous()) {
234      for (size_t i = 0; i < h_this->NumStaticFields(); ++i) {
235        os << StringPrintf("    %2zd: %s\n", i, PrettyField(h_this->GetStaticField(i)).c_str());
236      }
237    } else {
238      os << "    <not yet available>";
239    }
240  }
241  if (h_this->NumInstanceFields() > 0) {
242    os << "  instance fields (" << h_this->NumInstanceFields() << " entries):\n";
243    if (h_this->IsResolved() || h_this->IsErroneous()) {
244      for (size_t i = 0; i < h_this->NumInstanceFields(); ++i) {
245        os << StringPrintf("    %2zd: %s\n", i, PrettyField(h_this->GetInstanceField(i)).c_str());
246      }
247    } else {
248      os << "    <not yet available>";
249    }
250  }
251}
252
253void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
254  if (new_reference_offsets != CLASS_WALK_SUPER) {
255    // Sanity check that the number of bits set in the reference offset bitmap
256    // agrees with the number of references
257    size_t count = 0;
258    for (Class* c = this; c != nullptr; c = c->GetSuperClass()) {
259      count += c->NumReferenceInstanceFieldsDuringLinking();
260    }
261    CHECK_EQ((size_t)POPCOUNT(new_reference_offsets), count);
262  }
263  // Not called within a transaction.
264  SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
265                    new_reference_offsets);
266}
267
268void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) {
269  if (new_reference_offsets != CLASS_WALK_SUPER) {
270    // Sanity check that the number of bits set in the reference offset bitmap
271    // agrees with the number of references
272    CHECK_EQ((size_t)POPCOUNT(new_reference_offsets),
273             NumReferenceStaticFieldsDuringLinking());
274  }
275  // Not called within a transaction.
276  SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_),
277                    new_reference_offsets);
278}
279
280bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
281  size_t i = 0;
282  while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
283    ++i;
284  }
285  if (descriptor1.find('/', i) != StringPiece::npos ||
286      descriptor2.find('/', i) != StringPiece::npos) {
287    return false;
288  } else {
289    return true;
290  }
291}
292
293bool Class::IsInSamePackage(Class* that) {
294  Class* klass1 = this;
295  Class* klass2 = that;
296  if (klass1 == klass2) {
297    return true;
298  }
299  // Class loaders must match.
300  if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
301    return false;
302  }
303  // Arrays are in the same package when their element classes are.
304  while (klass1->IsArrayClass()) {
305    klass1 = klass1->GetComponentType();
306  }
307  while (klass2->IsArrayClass()) {
308    klass2 = klass2->GetComponentType();
309  }
310  // trivial check again for array types
311  if (klass1 == klass2) {
312    return true;
313  }
314  // Compare the package part of the descriptor string.
315  return IsInSamePackage(klass1->GetDescriptor().c_str(), klass2->GetDescriptor().c_str());
316}
317
318bool Class::IsStringClass() const {
319  return this == String::GetJavaLangString();
320}
321
322bool Class::IsThrowableClass() {
323  return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this);
324}
325
326void Class::SetClassLoader(ClassLoader* new_class_loader) {
327  if (Runtime::Current()->IsActiveTransaction()) {
328    SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader);
329  } else {
330    SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader);
331  }
332}
333
334ArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) {
335  // Check the current class before checking the interfaces.
336  ArtMethod* method = FindDeclaredVirtualMethod(name, signature);
337  if (method != nullptr) {
338    return method;
339  }
340
341  int32_t iftable_count = GetIfTableCount();
342  IfTable* iftable = GetIfTable();
343  for (int32_t i = 0; i < iftable_count; ++i) {
344    method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature);
345    if (method != nullptr) {
346      return method;
347    }
348  }
349  return nullptr;
350}
351
352ArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const Signature& signature) {
353  // Check the current class before checking the interfaces.
354  ArtMethod* method = FindDeclaredVirtualMethod(name, signature);
355  if (method != nullptr) {
356    return method;
357  }
358
359  int32_t iftable_count = GetIfTableCount();
360  IfTable* iftable = GetIfTable();
361  for (int32_t i = 0; i < iftable_count; ++i) {
362    method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature);
363    if (method != nullptr) {
364      return method;
365    }
366  }
367  return nullptr;
368}
369
370ArtMethod* Class::FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
371  // Check the current class before checking the interfaces.
372  ArtMethod* method = FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
373  if (method != nullptr) {
374    return method;
375  }
376
377  int32_t iftable_count = GetIfTableCount();
378  IfTable* iftable = GetIfTable();
379  for (int32_t i = 0; i < iftable_count; ++i) {
380    method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
381    if (method != nullptr) {
382      return method;
383    }
384  }
385  return nullptr;
386}
387
388ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) {
389  for (size_t i = 0; i < NumDirectMethods(); ++i) {
390    ArtMethod* method = GetDirectMethod(i);
391    if (name == method->GetName() && method->GetSignature() == signature) {
392      return method;
393    }
394  }
395  return nullptr;
396}
397
398ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const Signature& signature) {
399  for (size_t i = 0; i < NumDirectMethods(); ++i) {
400    ArtMethod* method = GetDirectMethod(i);
401    if (name == method->GetName() && signature == method->GetSignature()) {
402      return method;
403    }
404  }
405  return nullptr;
406}
407
408ArtMethod* Class::FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
409  if (GetDexCache() == dex_cache) {
410    for (size_t i = 0; i < NumDirectMethods(); ++i) {
411      ArtMethod* method = GetDirectMethod(i);
412      if (method->GetDexMethodIndex() == dex_method_idx) {
413        return method;
414      }
415    }
416  }
417  return nullptr;
418}
419
420ArtMethod* Class::FindDirectMethod(const StringPiece& name, const StringPiece& signature) {
421  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
422    ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature);
423    if (method != nullptr) {
424      return method;
425    }
426  }
427  return nullptr;
428}
429
430ArtMethod* Class::FindDirectMethod(const StringPiece& name, const Signature& signature) {
431  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
432    ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature);
433    if (method != nullptr) {
434      return method;
435    }
436  }
437  return nullptr;
438}
439
440ArtMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
441  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
442    ArtMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx);
443    if (method != nullptr) {
444      return method;
445    }
446  }
447  return nullptr;
448}
449
450ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) {
451  for (size_t i = 0; i < NumVirtualMethods(); ++i) {
452    ArtMethod* method = GetVirtualMethod(i);
453    if (name == method->GetName() && method->GetSignature() == signature) {
454      return method;
455    }
456  }
457  return nullptr;
458}
459
460ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const Signature& signature) {
461  for (size_t i = 0; i < NumVirtualMethods(); ++i) {
462    ArtMethod* method = GetVirtualMethod(i);
463    if (name == method->GetName() && signature == method->GetSignature()) {
464      return method;
465    }
466  }
467  return nullptr;
468}
469
470ArtMethod* Class::FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
471  if (GetDexCache() == dex_cache) {
472    for (size_t i = 0; i < NumVirtualMethods(); ++i) {
473      ArtMethod* method = GetVirtualMethod(i);
474      if (method->GetDexMethodIndex() == dex_method_idx) {
475        return method;
476      }
477    }
478  }
479  return nullptr;
480}
481
482ArtMethod* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) {
483  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
484    ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature);
485    if (method != nullptr) {
486      return method;
487    }
488  }
489  return nullptr;
490}
491
492ArtMethod* Class::FindVirtualMethod(const StringPiece& name, const Signature& signature) {
493  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
494    ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature);
495    if (method != nullptr) {
496      return method;
497    }
498  }
499  return nullptr;
500}
501
502ArtMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
503  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
504    ArtMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
505    if (method != nullptr) {
506      return method;
507    }
508  }
509  return nullptr;
510}
511
512ArtMethod* Class::FindClassInitializer() {
513  for (size_t i = 0; i < NumDirectMethods(); ++i) {
514    ArtMethod* method = GetDirectMethod(i);
515    if (method->IsClassInitializer()) {
516      DCHECK_STREQ(method->GetName(), "<clinit>");
517      DCHECK_STREQ(method->GetSignature().ToString().c_str(), "()V");
518      return method;
519    }
520  }
521  return nullptr;
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  for (size_t i = 0; i < NumInstanceFields(); ++i) {
528    ArtField* f = GetInstanceField(i);
529    if (name == f->GetName() && type == f->GetTypeDescriptor()) {
530      return f;
531    }
532  }
533  return nullptr;
534}
535
536ArtField* Class::FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) {
537  if (GetDexCache() == dex_cache) {
538    for (size_t i = 0; i < NumInstanceFields(); ++i) {
539      ArtField* f = GetInstanceField(i);
540      if (f->GetDexFieldIndex() == dex_field_idx) {
541        return f;
542      }
543    }
544  }
545  return nullptr;
546}
547
548ArtField* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) {
549  // Is the field in this class, or any of its superclasses?
550  // Interfaces are not relevant because they can't contain instance fields.
551  for (Class* c = this; c != nullptr; c = c->GetSuperClass()) {
552    ArtField* f = c->FindDeclaredInstanceField(name, type);
553    if (f != nullptr) {
554      return f;
555    }
556  }
557  return nullptr;
558}
559
560ArtField* Class::FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) {
561  // Is the field in this class, or any of its superclasses?
562  // Interfaces are not relevant because they can't contain instance fields.
563  for (Class* c = this; c != nullptr; c = c->GetSuperClass()) {
564    ArtField* f = c->FindDeclaredInstanceField(dex_cache, dex_field_idx);
565    if (f != nullptr) {
566      return f;
567    }
568  }
569  return nullptr;
570}
571
572ArtField* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) {
573  DCHECK(type != nullptr);
574  for (size_t i = 0; i < NumStaticFields(); ++i) {
575    ArtField* f = GetStaticField(i);
576    if (name == f->GetName() && type == f->GetTypeDescriptor()) {
577      return f;
578    }
579  }
580  return nullptr;
581}
582
583ArtField* Class::FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) {
584  if (dex_cache == GetDexCache()) {
585    for (size_t i = 0; i < NumStaticFields(); ++i) {
586      ArtField* f = GetStaticField(i);
587      if (f->GetDexFieldIndex() == dex_field_idx) {
588        return f;
589      }
590    }
591  }
592  return nullptr;
593}
594
595ArtField* Class::FindStaticField(Thread* self, Handle<Class> klass, const StringPiece& name,
596                                 const StringPiece& type) {
597  // Is the field in this class (or its interfaces), or any of its
598  // superclasses (or their interfaces)?
599  for (Class* k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
600    // Is the field in this class?
601    ArtField* f = k->FindDeclaredStaticField(name, type);
602    if (f != nullptr) {
603      return f;
604    }
605    // Wrap k incase it moves during GetDirectInterface.
606    StackHandleScope<1> hs(self);
607    HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
608    // Is this field in any of this class' interfaces?
609    for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
610      StackHandleScope<1> hs(self);
611      Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
612      f = FindStaticField(self, interface, name, type);
613      if (f != nullptr) {
614        return f;
615      }
616    }
617  }
618  return nullptr;
619}
620
621ArtField* Class::FindStaticField(Thread* self, Handle<Class> klass, const DexCache* dex_cache,
622                                 uint32_t dex_field_idx) {
623  for (Class* k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
624    // Is the field in this class?
625    ArtField* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx);
626    if (f != nullptr) {
627      return f;
628    }
629    // Wrap k incase it moves during GetDirectInterface.
630    StackHandleScope<1> hs(self);
631    HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
632    // Is this field in any of this class' interfaces?
633    for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
634      StackHandleScope<1> hs(self);
635      Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
636      f = FindStaticField(self, interface, dex_cache, dex_field_idx);
637      if (f != nullptr) {
638        return f;
639      }
640    }
641  }
642  return nullptr;
643}
644
645ArtField* Class::FindField(Thread* self, Handle<Class> klass, const StringPiece& name,
646                           const StringPiece& type) {
647  // Find a field using the JLS field resolution order
648  for (Class* k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
649    // Is the field in this class?
650    ArtField* f = k->FindDeclaredInstanceField(name, type);
651    if (f != nullptr) {
652      return f;
653    }
654    f = k->FindDeclaredStaticField(name, type);
655    if (f != nullptr) {
656      return f;
657    }
658    // Is this field in any of this class' interfaces?
659    StackHandleScope<1> hs(self);
660    HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
661    for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
662      StackHandleScope<1> hs(self);
663      Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
664      f = interface->FindStaticField(self, interface, name, type);
665      if (f != nullptr) {
666        return f;
667      }
668    }
669  }
670  return nullptr;
671}
672
673static void SetPreverifiedFlagOnMethods(mirror::ObjectArray<mirror::ArtMethod>* methods)
674    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
675  if (methods != nullptr) {
676    for (int32_t index = 0, end = methods->GetLength(); index < end; ++index) {
677      mirror::ArtMethod* method = methods->GetWithoutChecks(index);
678      DCHECK(method != nullptr);
679      if (!method->IsNative() && !method->IsAbstract()) {
680        method->SetPreverified();
681      }
682    }
683  }
684}
685
686void Class::SetPreverifiedFlagOnAllMethods() {
687  DCHECK(IsVerified());
688  SetPreverifiedFlagOnMethods(GetDirectMethods());
689  SetPreverifiedFlagOnMethods(GetVirtualMethods());
690}
691
692std::string Class::GetDescriptor() {
693  if (UNLIKELY(IsArrayClass())) {
694    return GetArrayDescriptor();
695  } else if (UNLIKELY(IsPrimitive())) {
696    return Primitive::Descriptor(GetPrimitiveType());
697  } else if (UNLIKELY(IsProxyClass())) {
698    return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this);
699  } else {
700    const DexFile& dex_file = GetDexFile();
701    const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
702    return dex_file.GetTypeDescriptor(type_id);
703  }
704}
705
706std::string Class::GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
707  return "[" + GetComponentType()->GetDescriptor();
708}
709
710const DexFile::ClassDef* Class::GetClassDef() {
711  uint16_t class_def_idx = GetDexClassDefIndex();
712  if (class_def_idx == DexFile::kDexNoIndex16) {
713    return nullptr;
714  }
715  return &GetDexFile().GetClassDef(class_def_idx);
716}
717
718uint32_t Class::NumDirectInterfaces() {
719  if (IsPrimitive()) {
720    return 0;
721  } else if (IsArrayClass()) {
722    return 2;
723  } else if (IsProxyClass()) {
724    mirror::SynthesizedProxyClass* proxy_class=
725        reinterpret_cast<mirror::SynthesizedProxyClass*>(this);
726    mirror::ObjectArray<mirror::Class>* interfaces = proxy_class->GetInterfaces();
727    return interfaces != nullptr ? interfaces->GetLength() : 0;
728  } else {
729    const DexFile::TypeList* interfaces = GetInterfaceTypeList();
730    if (interfaces == nullptr) {
731      return 0;
732    } else {
733      return interfaces->Size();
734    }
735  }
736}
737
738uint16_t Class::GetDirectInterfaceTypeIdx(uint32_t idx) {
739  DCHECK(!IsPrimitive());
740  DCHECK(!IsArrayClass());
741  return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
742}
743
744mirror::Class* Class::GetDirectInterface(Thread* self, Handle<mirror::Class> klass, uint32_t idx) {
745  DCHECK(klass.Get() != nullptr);
746  DCHECK(!klass->IsPrimitive());
747  if (klass->IsArrayClass()) {
748    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
749    if (idx == 0) {
750      return class_linker->FindSystemClass(self, "Ljava/lang/Cloneable;");
751    } else {
752      DCHECK_EQ(1U, idx);
753      return class_linker->FindSystemClass(self, "Ljava/io/Serializable;");
754    }
755  } else if (klass->IsProxyClass()) {
756    mirror::SynthesizedProxyClass* proxy_class =
757        reinterpret_cast<mirror::SynthesizedProxyClass*>(klass.Get());
758    mirror::ObjectArray<mirror::Class>* interfaces = proxy_class->GetInterfaces();
759    DCHECK(interfaces != nullptr);
760    return interfaces->Get(idx);
761  } else {
762    uint16_t type_idx = klass->GetDirectInterfaceTypeIdx(idx);
763    mirror::Class* interface = klass->GetDexCache()->GetResolvedType(type_idx);
764    if (interface == nullptr) {
765      interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(), type_idx,
766                                                                    klass.Get());
767      CHECK(interface != nullptr || self->IsExceptionPending());
768    }
769    return interface;
770  }
771}
772
773const char* Class::GetSourceFile() {
774  std::string descriptor(GetDescriptor());
775  const DexFile& dex_file = GetDexFile();
776  const DexFile::ClassDef* dex_class_def = GetClassDef();
777  if (dex_class_def == nullptr) {
778    // Generated classes have no class def.
779    return nullptr;
780  }
781  return dex_file.GetSourceFile(*dex_class_def);
782}
783
784std::string Class::GetLocation() {
785  mirror::DexCache* dex_cache = GetDexCache();
786  if (dex_cache != nullptr && !IsProxyClass()) {
787    return dex_cache->GetLocation()->ToModifiedUtf8();
788  }
789  // Arrays and proxies are generated and have no corresponding dex file location.
790  return "generated class";
791}
792
793const DexFile::TypeList* Class::GetInterfaceTypeList() {
794  const DexFile::ClassDef* class_def = GetClassDef();
795  if (class_def == nullptr) {
796    return nullptr;
797  }
798  return GetDexFile().GetInterfacesList(*class_def);
799}
800
801}  // namespace mirror
802}  // namespace art
803