class.cc revision ee39a10e45a6a0880e8b829525c40d6055818560
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "class.h"
18
19#include "art_field-inl.h"
20#include "art_method-inl.h"
21#include "class-inl.h"
22#include "class_linker.h"
23#include "class_loader.h"
24#include "dex_cache.h"
25#include "dex_file-inl.h"
26#include "gc/accounting/card_table-inl.h"
27#include "object-inl.h"
28#include "object_array-inl.h"
29#include "object_utils.h"
30#include "runtime.h"
31#include "sirt_ref.h"
32#include "thread.h"
33#include "throwable.h"
34#include "utils.h"
35#include "well_known_classes.h"
36
37namespace art {
38namespace mirror {
39
40Class* Class::java_lang_Class_ = NULL;
41
42void Class::SetClassClass(Class* java_lang_Class) {
43  CHECK(java_lang_Class_ == NULL) << java_lang_Class_ << " " << java_lang_Class;
44  CHECK(java_lang_Class != NULL);
45  java_lang_Class_ = java_lang_Class;
46}
47
48void Class::ResetClass() {
49  CHECK(java_lang_Class_ != NULL);
50  java_lang_Class_ = NULL;
51}
52
53void Class::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
117void Class::SetDexCache(DexCache* new_dex_cache) {
118  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false);
119}
120
121Object* 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
130void 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.
142String* 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
180void 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
246void 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
260void 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
271bool 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
284bool 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
310bool Class::IsClassClass() const {
311  Class* java_lang_Class = GetClass()->GetClass();
312  return this == java_lang_Class;
313}
314
315bool Class::IsStringClass() const {
316  return this == String::GetJavaLangString();
317}
318
319bool Class::IsThrowableClass() const {
320  return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this);
321}
322
323bool 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
329bool Class::IsArtMethodClass() const {
330  return this == ArtMethod::GetJavaLangReflectArtMethod();
331}
332
333void Class::SetClassLoader(ClassLoader* new_class_loader) {
334  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false);
335}
336
337ArtMethod* 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
355ArtMethod* 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
374ArtMethod* 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
386ArtMethod* 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
398ArtMethod* 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
408ArtMethod* 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
418ArtMethod* 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
431ArtMethod* 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
443ArtMethod* 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
453ArtMethod* 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
463ArtField* 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
477ArtField* 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
489ArtField* 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
501ArtField* 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
513ArtField* 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
526ArtField* 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
538ArtField* 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
561ArtField* 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
582ArtField* 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
608static 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
619void Class::SetPreverifiedFlagOnAllMethods() {
620  DCHECK(IsVerified());
621  SetPreverifiedFlagOnMethods(GetDirectMethods());
622  SetPreverifiedFlagOnMethods(GetVirtualMethods());
623}
624
625}  // namespace mirror
626}  // namespace art
627