class.cc revision 0fbd6e6ec3241b7163b95f9f001bfe9b08f8b200
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                 new_status != kStatusRetired)) {
68      LOG(FATAL) << "Unexpected change back of class status for " << PrettyClass(this) << " "
69          << old_status << " -> " << new_status;
70    }
71    if (new_status >= kStatusResolved || old_status >= kStatusResolved) {
72      // When classes are being resolved the resolution code should hold the lock.
73      CHECK_EQ(GetLockOwnerThreadId(), self->GetThreadId())
74            << "Attempt to change status of class while not holding its lock: "
75            << PrettyClass(this) << " " << old_status << " -> " << new_status;
76    }
77  }
78  if (UNLIKELY(new_status == kStatusError)) {
79    CHECK_NE(GetStatus(), kStatusError)
80        << "Attempt to set as erroneous an already erroneous class " << PrettyClass(this);
81
82    // Stash current exception.
83    StackHandleScope<3> hs(self);
84    ThrowLocation old_throw_location;
85    Handle<mirror::Throwable> old_exception(hs.NewHandle(self->GetException(&old_throw_location)));
86    CHECK(old_exception.Get() != nullptr);
87    Handle<mirror::Object> old_throw_this_object(hs.NewHandle(old_throw_location.GetThis()));
88    Handle<mirror::ArtMethod> old_throw_method(hs.NewHandle(old_throw_location.GetMethod()));
89    uint32_t old_throw_dex_pc = old_throw_location.GetDexPc();
90    bool is_exception_reported = self->IsExceptionReportedToInstrumentation();
91    Class* eiie_class;
92    // Do't attempt to use FindClass if we have an OOM error since this can try to do more
93    // allocations and may cause infinite loops.
94    if (old_exception.Get() == nullptr ||
95        old_exception->GetClass()->GetDescriptor() != "Ljava/lang/OutOfMemoryError;") {
96      // Clear exception to call FindSystemClass.
97      self->ClearException();
98      eiie_class = Runtime::Current()->GetClassLinker()->FindSystemClass(
99          self, "Ljava/lang/ExceptionInInitializerError;");
100      CHECK(!self->IsExceptionPending());
101      // Only verification errors, not initialization problems, should set a verify error.
102      // This is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case.
103      Class* exception_class = old_exception->GetClass();
104      if (!eiie_class->IsAssignableFrom(exception_class)) {
105        SetVerifyErrorClass(exception_class);
106      }
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    self->SetException(gc_safe_throw_location, old_exception.Get());
113    self->SetExceptionReportedToInstrumentation(is_exception_reported);
114  }
115  COMPILE_ASSERT(sizeof(Status) == sizeof(uint32_t), size_of_status_not_uint32);
116  if (Runtime::Current()->IsActiveTransaction()) {
117    SetField32Volatile<true>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
118  } else {
119    SetField32Volatile<false>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
120  }
121
122  if (!class_linker_initialized) {
123    // When the class linker is being initialized its single threaded and by definition there can be
124    // no waiters. During initialization classes may appear temporary but won't be retired as their
125    // size was statically computed.
126  } else {
127    // Classes that are being resolved or initialized need to notify waiters that the class status
128    // changed. See ClassLinker::EnsureResolved and ClassLinker::WaitForInitializeClass.
129    if (IsTemp()) {
130      // Class is a temporary one, ensure that waiters for resolution get notified of retirement
131      // so that they can grab the new version of the class from the class linker's table.
132      CHECK_LT(new_status, kStatusResolved) << PrettyDescriptor(this);
133      if (new_status == kStatusRetired || new_status == kStatusError) {
134        NotifyAll(self);
135      }
136    } else {
137      CHECK_NE(new_status, kStatusRetired);
138      if (old_status >= kStatusResolved || new_status >= kStatusResolved) {
139        NotifyAll(self);
140      }
141    }
142  }
143}
144
145void Class::SetDexCache(DexCache* new_dex_cache) {
146  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache);
147}
148
149void Class::SetClassSize(uint32_t new_class_size) {
150  if (kIsDebugBuild && (new_class_size < GetClassSize())) {
151    DumpClass(LOG(ERROR), kDumpClassFullDetail);
152    CHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
153  }
154  // Not called within a transaction.
155  SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size);
156}
157
158// Return the class' name. The exact format is bizarre, but it's the specified behavior for
159// Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int"
160// but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than
161// slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness.
162String* Class::ComputeName(Handle<Class> h_this) {
163  String* name = h_this->GetName();
164  if (name != nullptr) {
165    return name;
166  }
167  std::string descriptor(h_this->GetDescriptor());
168  Thread* self = Thread::Current();
169  if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
170    // The descriptor indicates that this is the class for
171    // a primitive type; special-case the return value.
172    const char* c_name = nullptr;
173    switch (descriptor[0]) {
174    case 'Z': c_name = "boolean"; break;
175    case 'B': c_name = "byte";    break;
176    case 'C': c_name = "char";    break;
177    case 'S': c_name = "short";   break;
178    case 'I': c_name = "int";     break;
179    case 'J': c_name = "long";    break;
180    case 'F': c_name = "float";   break;
181    case 'D': c_name = "double";  break;
182    case 'V': c_name = "void";    break;
183    default:
184      LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
185    }
186    name = String::AllocFromModifiedUtf8(self, c_name);
187  } else {
188    // Convert the UTF-8 name to a java.lang.String. The name must use '.' to separate package
189    // components.
190    if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') {
191      descriptor.erase(0, 1);
192      descriptor.erase(descriptor.size() - 1);
193    }
194    std::replace(descriptor.begin(), descriptor.end(), '/', '.');
195    name = String::AllocFromModifiedUtf8(self, descriptor.c_str());
196  }
197  h_this->SetName(name);
198  return name;
199}
200
201void Class::DumpClass(std::ostream& os, int flags) {
202  if ((flags & kDumpClassFullDetail) == 0) {
203    os << PrettyClass(this);
204    if ((flags & kDumpClassClassLoader) != 0) {
205      os << ' ' << GetClassLoader();
206    }
207    if ((flags & kDumpClassInitialized) != 0) {
208      os << ' ' << GetStatus();
209    }
210    os << "\n";
211    return;
212  }
213
214  Thread* self = Thread::Current();
215  StackHandleScope<2> hs(self);
216  Handle<mirror::Class> h_this(hs.NewHandle(this));
217  Handle<mirror::Class> h_super(hs.NewHandle(GetSuperClass()));
218
219  os << "----- " << (IsInterface() ? "interface" : "class") << " "
220     << "'" << GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n",
221  os << "  objectSize=" << SizeOf() << " "
222     << "(" << (h_super.Get() != nullptr ? h_super->SizeOf() : -1) << " from super)\n",
223  os << StringPrintf("  access=0x%04x.%04x\n",
224      GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
225  if (h_super.Get() != nullptr) {
226    os << "  super='" << PrettyClass(h_super.Get()) << "' (cl=" << h_super->GetClassLoader()
227       << ")\n";
228  }
229  if (IsArrayClass()) {
230    os << "  componentType=" << PrettyClass(GetComponentType()) << "\n";
231  }
232  const size_t num_direct_interfaces = NumDirectInterfaces();
233  if (num_direct_interfaces > 0) {
234    os << "  interfaces (" << num_direct_interfaces << "):\n";
235    for (size_t i = 0; i < num_direct_interfaces; ++i) {
236      Class* interface = GetDirectInterface(self, h_this, i);
237      const ClassLoader* cl = interface->GetClassLoader();
238      os << StringPrintf("    %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl);
239    }
240  }
241  if (!IsLoaded()) {
242    os << "  class not yet loaded";
243  } else {
244    // After this point, this may have moved due to GetDirectInterface.
245    os << "  vtable (" << h_this->NumVirtualMethods() << " entries, "
246        << (h_super.Get() != nullptr ? h_super->NumVirtualMethods() : 0) << " in super):\n";
247    for (size_t i = 0; i < NumVirtualMethods(); ++i) {
248      os << StringPrintf("    %2zd: %s\n", i,
249                         PrettyMethod(h_this->GetVirtualMethodDuringLinking(i)).c_str());
250    }
251    os << "  direct methods (" << h_this->NumDirectMethods() << " entries):\n";
252    for (size_t i = 0; i < h_this->NumDirectMethods(); ++i) {
253      os << StringPrintf("    %2zd: %s\n", i, PrettyMethod(h_this->GetDirectMethod(i)).c_str());
254    }
255    if (h_this->NumStaticFields() > 0) {
256      os << "  static fields (" << h_this->NumStaticFields() << " entries):\n";
257      if (h_this->IsResolved() || h_this->IsErroneous()) {
258        for (size_t i = 0; i < h_this->NumStaticFields(); ++i) {
259          os << StringPrintf("    %2zd: %s\n", i, PrettyField(h_this->GetStaticField(i)).c_str());
260        }
261      } else {
262        os << "    <not yet available>";
263      }
264    }
265    if (h_this->NumInstanceFields() > 0) {
266      os << "  instance fields (" << h_this->NumInstanceFields() << " entries):\n";
267      if (h_this->IsResolved() || h_this->IsErroneous()) {
268        for (size_t i = 0; i < h_this->NumInstanceFields(); ++i) {
269          os << StringPrintf("    %2zd: %s\n", i, PrettyField(h_this->GetInstanceField(i)).c_str());
270        }
271      } else {
272        os << "    <not yet available>";
273      }
274    }
275  }
276}
277
278void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
279  if (new_reference_offsets != CLASS_WALK_SUPER) {
280    // Sanity check that the number of bits set in the reference offset bitmap
281    // agrees with the number of references
282    size_t count = 0;
283    for (Class* c = this; c != nullptr; c = c->GetSuperClass()) {
284      count += c->NumReferenceInstanceFieldsDuringLinking();
285    }
286    CHECK_EQ((size_t)POPCOUNT(new_reference_offsets), count);
287  }
288  // Not called within a transaction.
289  SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
290                    new_reference_offsets);
291}
292
293void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) {
294  if (new_reference_offsets != CLASS_WALK_SUPER) {
295    // Sanity check that the number of bits set in the reference offset bitmap
296    // agrees with the number of references
297    CHECK_EQ((size_t)POPCOUNT(new_reference_offsets),
298             NumReferenceStaticFieldsDuringLinking());
299  }
300  // Not called within a transaction.
301  SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_),
302                    new_reference_offsets);
303}
304
305bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
306  size_t i = 0;
307  while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
308    ++i;
309  }
310  if (descriptor1.find('/', i) != StringPiece::npos ||
311      descriptor2.find('/', i) != StringPiece::npos) {
312    return false;
313  } else {
314    return true;
315  }
316}
317
318bool Class::IsInSamePackage(Class* that) {
319  Class* klass1 = this;
320  Class* klass2 = that;
321  if (klass1 == klass2) {
322    return true;
323  }
324  // Class loaders must match.
325  if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
326    return false;
327  }
328  // Arrays are in the same package when their element classes are.
329  while (klass1->IsArrayClass()) {
330    klass1 = klass1->GetComponentType();
331  }
332  while (klass2->IsArrayClass()) {
333    klass2 = klass2->GetComponentType();
334  }
335  // trivial check again for array types
336  if (klass1 == klass2) {
337    return true;
338  }
339  // Compare the package part of the descriptor string.
340  return IsInSamePackage(klass1->GetDescriptor().c_str(), klass2->GetDescriptor().c_str());
341}
342
343bool Class::IsStringClass() const {
344  return this == String::GetJavaLangString();
345}
346
347bool Class::IsThrowableClass() {
348  return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this);
349}
350
351void Class::SetClassLoader(ClassLoader* new_class_loader) {
352  if (Runtime::Current()->IsActiveTransaction()) {
353    SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader);
354  } else {
355    SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader);
356  }
357}
358
359ArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) {
360  // Check the current class before checking the interfaces.
361  ArtMethod* method = FindDeclaredVirtualMethod(name, signature);
362  if (method != nullptr) {
363    return method;
364  }
365
366  int32_t iftable_count = GetIfTableCount();
367  IfTable* iftable = GetIfTable();
368  for (int32_t i = 0; i < iftable_count; ++i) {
369    method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature);
370    if (method != nullptr) {
371      return method;
372    }
373  }
374  return nullptr;
375}
376
377ArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const Signature& signature) {
378  // Check the current class before checking the interfaces.
379  ArtMethod* method = FindDeclaredVirtualMethod(name, signature);
380  if (method != nullptr) {
381    return method;
382  }
383
384  int32_t iftable_count = GetIfTableCount();
385  IfTable* iftable = GetIfTable();
386  for (int32_t i = 0; i < iftable_count; ++i) {
387    method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature);
388    if (method != nullptr) {
389      return method;
390    }
391  }
392  return nullptr;
393}
394
395ArtMethod* Class::FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
396  // Check the current class before checking the interfaces.
397  ArtMethod* method = FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
398  if (method != nullptr) {
399    return method;
400  }
401
402  int32_t iftable_count = GetIfTableCount();
403  IfTable* iftable = GetIfTable();
404  for (int32_t i = 0; i < iftable_count; ++i) {
405    method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
406    if (method != nullptr) {
407      return method;
408    }
409  }
410  return nullptr;
411}
412
413ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) {
414  for (size_t i = 0; i < NumDirectMethods(); ++i) {
415    ArtMethod* method = GetDirectMethod(i);
416    if (name == method->GetName() && method->GetSignature() == signature) {
417      return method;
418    }
419  }
420  return nullptr;
421}
422
423ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const Signature& signature) {
424  for (size_t i = 0; i < NumDirectMethods(); ++i) {
425    ArtMethod* method = GetDirectMethod(i);
426    if (name == method->GetName() && signature == method->GetSignature()) {
427      return method;
428    }
429  }
430  return nullptr;
431}
432
433ArtMethod* Class::FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
434  if (GetDexCache() == dex_cache) {
435    for (size_t i = 0; i < NumDirectMethods(); ++i) {
436      ArtMethod* method = GetDirectMethod(i);
437      if (method->GetDexMethodIndex() == dex_method_idx) {
438        return method;
439      }
440    }
441  }
442  return nullptr;
443}
444
445ArtMethod* Class::FindDirectMethod(const StringPiece& name, const StringPiece& signature) {
446  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
447    ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature);
448    if (method != nullptr) {
449      return method;
450    }
451  }
452  return nullptr;
453}
454
455ArtMethod* Class::FindDirectMethod(const StringPiece& name, const Signature& signature) {
456  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
457    ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature);
458    if (method != nullptr) {
459      return method;
460    }
461  }
462  return nullptr;
463}
464
465ArtMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
466  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
467    ArtMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx);
468    if (method != nullptr) {
469      return method;
470    }
471  }
472  return nullptr;
473}
474
475ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) {
476  for (size_t i = 0; i < NumVirtualMethods(); ++i) {
477    ArtMethod* method = GetVirtualMethod(i);
478    if (name == method->GetName() && method->GetSignature() == signature) {
479      return method;
480    }
481  }
482  return nullptr;
483}
484
485ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const Signature& signature) {
486  for (size_t i = 0; i < NumVirtualMethods(); ++i) {
487    ArtMethod* method = GetVirtualMethod(i);
488    if (name == method->GetName() && signature == method->GetSignature()) {
489      return method;
490    }
491  }
492  return nullptr;
493}
494
495ArtMethod* Class::FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
496  if (GetDexCache() == dex_cache) {
497    for (size_t i = 0; i < NumVirtualMethods(); ++i) {
498      ArtMethod* method = GetVirtualMethod(i);
499      if (method->GetDexMethodIndex() == dex_method_idx) {
500        return method;
501      }
502    }
503  }
504  return nullptr;
505}
506
507ArtMethod* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) {
508  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
509    ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature);
510    if (method != nullptr) {
511      return method;
512    }
513  }
514  return nullptr;
515}
516
517ArtMethod* Class::FindVirtualMethod(const StringPiece& name, const Signature& signature) {
518  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
519    ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature);
520    if (method != nullptr) {
521      return method;
522    }
523  }
524  return nullptr;
525}
526
527ArtMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) {
528  for (Class* klass = this; klass != nullptr; klass = klass->GetSuperClass()) {
529    ArtMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
530    if (method != nullptr) {
531      return method;
532    }
533  }
534  return nullptr;
535}
536
537ArtMethod* Class::FindClassInitializer() {
538  for (size_t i = 0; i < NumDirectMethods(); ++i) {
539    ArtMethod* method = GetDirectMethod(i);
540    if (method->IsClassInitializer()) {
541      DCHECK_STREQ(method->GetName(), "<clinit>");
542      DCHECK_STREQ(method->GetSignature().ToString().c_str(), "()V");
543      return method;
544    }
545  }
546  return nullptr;
547}
548
549ArtField* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) {
550  // Is the field in this class?
551  // Interfaces are not relevant because they can't contain instance fields.
552  for (size_t i = 0; i < NumInstanceFields(); ++i) {
553    ArtField* f = GetInstanceField(i);
554    if (name == f->GetName() && type == f->GetTypeDescriptor()) {
555      return f;
556    }
557  }
558  return nullptr;
559}
560
561ArtField* Class::FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) {
562  if (GetDexCache() == dex_cache) {
563    for (size_t i = 0; i < NumInstanceFields(); ++i) {
564      ArtField* f = GetInstanceField(i);
565      if (f->GetDexFieldIndex() == dex_field_idx) {
566        return f;
567      }
568    }
569  }
570  return nullptr;
571}
572
573ArtField* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) {
574  // Is the field in this class, or any of its superclasses?
575  // Interfaces are not relevant because they can't contain instance fields.
576  for (Class* c = this; c != nullptr; c = c->GetSuperClass()) {
577    ArtField* f = c->FindDeclaredInstanceField(name, type);
578    if (f != nullptr) {
579      return f;
580    }
581  }
582  return nullptr;
583}
584
585ArtField* Class::FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) {
586  // Is the field in this class, or any of its superclasses?
587  // Interfaces are not relevant because they can't contain instance fields.
588  for (Class* c = this; c != nullptr; c = c->GetSuperClass()) {
589    ArtField* f = c->FindDeclaredInstanceField(dex_cache, dex_field_idx);
590    if (f != nullptr) {
591      return f;
592    }
593  }
594  return nullptr;
595}
596
597ArtField* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) {
598  DCHECK(type != nullptr);
599  for (size_t i = 0; i < NumStaticFields(); ++i) {
600    ArtField* f = GetStaticField(i);
601    if (name == f->GetName() && type == f->GetTypeDescriptor()) {
602      return f;
603    }
604  }
605  return nullptr;
606}
607
608ArtField* Class::FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) {
609  if (dex_cache == GetDexCache()) {
610    for (size_t i = 0; i < NumStaticFields(); ++i) {
611      ArtField* f = GetStaticField(i);
612      if (f->GetDexFieldIndex() == dex_field_idx) {
613        return f;
614      }
615    }
616  }
617  return nullptr;
618}
619
620ArtField* Class::FindStaticField(Thread* self, Handle<Class> klass, const StringPiece& name,
621                                 const StringPiece& type) {
622  // Is the field in this class (or its interfaces), or any of its
623  // superclasses (or their interfaces)?
624  for (Class* k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
625    // Is the field in this class?
626    ArtField* f = k->FindDeclaredStaticField(name, type);
627    if (f != nullptr) {
628      return f;
629    }
630    // Wrap k incase it moves during GetDirectInterface.
631    StackHandleScope<1> hs(self);
632    HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
633    // Is this field in any of this class' interfaces?
634    for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
635      StackHandleScope<1> hs(self);
636      Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
637      f = FindStaticField(self, interface, name, type);
638      if (f != nullptr) {
639        return f;
640      }
641    }
642  }
643  return nullptr;
644}
645
646ArtField* Class::FindStaticField(Thread* self, Handle<Class> klass, const DexCache* dex_cache,
647                                 uint32_t dex_field_idx) {
648  for (Class* k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
649    // Is the field in this class?
650    ArtField* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx);
651    if (f != nullptr) {
652      return f;
653    }
654    // Wrap k incase it moves during GetDirectInterface.
655    StackHandleScope<1> hs(self);
656    HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
657    // Is this field in any of this class' interfaces?
658    for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
659      StackHandleScope<1> hs(self);
660      Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
661      f = FindStaticField(self, interface, dex_cache, dex_field_idx);
662      if (f != nullptr) {
663        return f;
664      }
665    }
666  }
667  return nullptr;
668}
669
670ArtField* Class::FindField(Thread* self, Handle<Class> klass, const StringPiece& name,
671                           const StringPiece& type) {
672  // Find a field using the JLS field resolution order
673  for (Class* k = klass.Get(); k != nullptr; k = k->GetSuperClass()) {
674    // Is the field in this class?
675    ArtField* f = k->FindDeclaredInstanceField(name, type);
676    if (f != nullptr) {
677      return f;
678    }
679    f = k->FindDeclaredStaticField(name, type);
680    if (f != nullptr) {
681      return f;
682    }
683    // Is this field in any of this class' interfaces?
684    StackHandleScope<1> hs(self);
685    HandleWrapper<mirror::Class> h_k(hs.NewHandleWrapper(&k));
686    for (uint32_t i = 0; i < h_k->NumDirectInterfaces(); ++i) {
687      StackHandleScope<1> hs(self);
688      Handle<mirror::Class> interface(hs.NewHandle(GetDirectInterface(self, h_k, i)));
689      f = interface->FindStaticField(self, interface, name, type);
690      if (f != nullptr) {
691        return f;
692      }
693    }
694  }
695  return nullptr;
696}
697
698static void SetPreverifiedFlagOnMethods(mirror::ObjectArray<mirror::ArtMethod>* methods)
699    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
700  if (methods != nullptr) {
701    for (int32_t index = 0, end = methods->GetLength(); index < end; ++index) {
702      mirror::ArtMethod* method = methods->GetWithoutChecks(index);
703      DCHECK(method != nullptr);
704      if (!method->IsNative() && !method->IsAbstract()) {
705        method->SetPreverified();
706      }
707    }
708  }
709}
710
711void Class::SetPreverifiedFlagOnAllMethods() {
712  DCHECK(IsVerified());
713  SetPreverifiedFlagOnMethods(GetDirectMethods());
714  SetPreverifiedFlagOnMethods(GetVirtualMethods());
715}
716
717std::string Class::GetDescriptor() {
718  if (UNLIKELY(IsArrayClass())) {
719    return GetArrayDescriptor();
720  } else if (UNLIKELY(IsPrimitive())) {
721    return Primitive::Descriptor(GetPrimitiveType());
722  } else if (UNLIKELY(IsProxyClass())) {
723    return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this);
724  } else {
725    const DexFile& dex_file = GetDexFile();
726    const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
727    return dex_file.GetTypeDescriptor(type_id);
728  }
729}
730
731std::string Class::GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
732  return "[" + GetComponentType()->GetDescriptor();
733}
734
735const DexFile::ClassDef* Class::GetClassDef() {
736  uint16_t class_def_idx = GetDexClassDefIndex();
737  if (class_def_idx == DexFile::kDexNoIndex16) {
738    return nullptr;
739  }
740  return &GetDexFile().GetClassDef(class_def_idx);
741}
742
743uint32_t Class::NumDirectInterfaces() {
744  if (IsPrimitive()) {
745    return 0;
746  } else if (IsArrayClass()) {
747    return 2;
748  } else if (IsProxyClass()) {
749    mirror::ObjectArray<mirror::Class>* interfaces = GetInterfaces();
750    return interfaces != nullptr ? interfaces->GetLength() : 0;
751  } else {
752    const DexFile::TypeList* interfaces = GetInterfaceTypeList();
753    if (interfaces == nullptr) {
754      return 0;
755    } else {
756      return interfaces->Size();
757    }
758  }
759}
760
761uint16_t Class::GetDirectInterfaceTypeIdx(uint32_t idx) {
762  DCHECK(!IsPrimitive());
763  DCHECK(!IsArrayClass());
764  return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
765}
766
767mirror::Class* Class::GetDirectInterface(Thread* self, Handle<mirror::Class> klass, uint32_t idx) {
768  DCHECK(klass.Get() != nullptr);
769  DCHECK(!klass->IsPrimitive());
770  if (klass->IsArrayClass()) {
771    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
772    if (idx == 0) {
773      return class_linker->FindSystemClass(self, "Ljava/lang/Cloneable;");
774    } else {
775      DCHECK_EQ(1U, idx);
776      return class_linker->FindSystemClass(self, "Ljava/io/Serializable;");
777    }
778  } else if (klass->IsProxyClass()) {
779    mirror::ObjectArray<mirror::Class>* interfaces = klass.Get()->GetInterfaces();
780    DCHECK(interfaces != nullptr);
781    return interfaces->Get(idx);
782  } else {
783    uint16_t type_idx = klass->GetDirectInterfaceTypeIdx(idx);
784    mirror::Class* interface = klass->GetDexCache()->GetResolvedType(type_idx);
785    if (interface == nullptr) {
786      interface = Runtime::Current()->GetClassLinker()->ResolveType(klass->GetDexFile(), type_idx,
787                                                                    klass.Get());
788      CHECK(interface != nullptr || self->IsExceptionPending());
789    }
790    return interface;
791  }
792}
793
794const char* Class::GetSourceFile() {
795  std::string descriptor(GetDescriptor());
796  const DexFile& dex_file = GetDexFile();
797  const DexFile::ClassDef* dex_class_def = GetClassDef();
798  if (dex_class_def == nullptr) {
799    // Generated classes have no class def.
800    return nullptr;
801  }
802  return dex_file.GetSourceFile(*dex_class_def);
803}
804
805std::string Class::GetLocation() {
806  mirror::DexCache* dex_cache = GetDexCache();
807  if (dex_cache != nullptr && !IsProxyClass()) {
808    return dex_cache->GetLocation()->ToModifiedUtf8();
809  }
810  // Arrays and proxies are generated and have no corresponding dex file location.
811  return "generated class";
812}
813
814const DexFile::TypeList* Class::GetInterfaceTypeList() {
815  const DexFile::ClassDef* class_def = GetClassDef();
816  if (class_def == nullptr) {
817    return nullptr;
818  }
819  return GetDexFile().GetInterfacesList(*class_def);
820}
821
822void Class::PopulateEmbeddedImtAndVTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
823  ObjectArray<ArtMethod>* table = GetImTable();
824  if (table != nullptr) {
825    for (uint32_t i = 0; i < kImtSize; i++) {
826      SetEmbeddedImTableEntry(i, table->Get(i));
827    }
828  }
829
830  table = GetVTableDuringLinking();
831  CHECK(table != nullptr);
832  for (int32_t i = 0; i < table->GetLength(); i++) {
833    SetEmbeddedVTableEntry(i, table->Get(i));
834  }
835}
836
837// The pre-fence visitor for Class::CopyOf().
838class CopyClassVisitor {
839 public:
840  explicit CopyClassVisitor(Thread* self, Handle<mirror::Class>* orig,
841                            size_t new_length, size_t copy_bytes)
842      : self_(self), orig_(orig), new_length_(new_length),
843        copy_bytes_(copy_bytes) {
844  }
845
846  void operator()(Object* obj, size_t usable_size) const
847      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
848    UNUSED(usable_size);
849    mirror::Class* new_class_obj = obj->AsClass();
850    mirror::Object::CopyObject(self_, new_class_obj, orig_->Get(), copy_bytes_);
851    new_class_obj->SetStatus(Class::kStatusResolving, self_);
852    new_class_obj->PopulateEmbeddedImtAndVTable();
853    new_class_obj->SetClassSize(new_length_);
854  }
855
856 private:
857  Thread* const self_;
858  Handle<mirror::Class>* const orig_;
859  const size_t new_length_;
860  const size_t copy_bytes_;
861  DISALLOW_COPY_AND_ASSIGN(CopyClassVisitor);
862};
863
864Class* Class::CopyOf(Thread* self, int32_t new_length) {
865  DCHECK_GE(new_length, static_cast<int32_t>(sizeof(Class)));
866  // We may get copied by a compacting GC.
867  StackHandleScope<1> hs(self);
868  Handle<mirror::Class> h_this(hs.NewHandle(this));
869  gc::Heap* heap = Runtime::Current()->GetHeap();
870  // The num_bytes (3rd param) is sizeof(Class) as opposed to SizeOf()
871  // to skip copying the tail part that we will overwrite here.
872  CopyClassVisitor visitor(self, &h_this, new_length, sizeof(Class));
873
874  mirror::Object* new_class =
875      kMovingClasses ? heap->AllocObject<true>(self, java_lang_Class_, new_length, visitor)
876                     : heap->AllocNonMovableObject<true>(self, java_lang_Class_, new_length, visitor);
877  if (UNLIKELY(new_class == nullptr)) {
878    CHECK(self->IsExceptionPending());  // Expect an OOME.
879    return NULL;
880  }
881
882  return new_class->AsClass();
883}
884
885}  // namespace mirror
886}  // namespace art
887