class.cc revision ea46f950e7a51585db293cd7f047de190a482414
12dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers/* 22dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Copyright (C) 2011 The Android Open Source Project 32dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 42dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 52dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * you may not use this file except in compliance with the License. 62dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * You may obtain a copy of the License at 72dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 82dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 92dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Unless required by applicable law or agreed to in writing, software 112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * See the License for the specific language governing permissions and 142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * limitations under the License. 152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers */ 162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class.h" 182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 19ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "art_field-inl.h" 20ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "art_method-inl.h" 212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class-inl.h" 222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class_linker.h" 232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class_loader.h" 242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "dex_cache.h" 254f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 261d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/card_table-inl.h" 272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "object-inl.h" 282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "object_array-inl.h" 292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "object_utils.h" 302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h" 312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "sirt_ref.h" 322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "thread.h" 332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "throwable.h" 342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "utils.h" 352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "well_known_classes.h" 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan RogersClass* Class::java_lang_Class_ = NULL; 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetClassClass(Class* java_lang_Class) { 432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK(java_lang_Class_ == NULL) << java_lang_Class_ << " " << java_lang_Class; 442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK(java_lang_Class != NULL); 452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers java_lang_Class_ = java_lang_Class; 462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::ResetClass() { 492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK(java_lang_Class_ != NULL); 502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers java_lang_Class_ = NULL; 512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetStatus(Status new_status) { 542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK(new_status > GetStatus() || new_status == kStatusError || !Runtime::Current()->IsStarted()) 552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << PrettyClass(this) << " " << GetStatus() << " -> " << new_status; 562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this); 572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (new_status > kStatusResolved) { 582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK_EQ(GetThinLockId(), Thread::Current()->GetThinLockId()) << PrettyClass(this); 592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (new_status == kStatusError) { 612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK_NE(GetStatus(), kStatusError) << PrettyClass(this); 622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 6362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Stash current exception. 642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Thread* self = Thread::Current(); 6562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SirtRef<mirror::Object> old_throw_this_object(self, NULL); 66ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom SirtRef<mirror::ArtMethod> old_throw_method(self, NULL); 6762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SirtRef<mirror::Throwable> old_exception(self, NULL); 6862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t old_throw_dex_pc; 6962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers { 7062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation old_throw_location; 7162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Throwable* old_exception_obj = self->GetException(&old_throw_location); 7262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_this_object.reset(old_throw_location.GetThis()); 7362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_method.reset(old_throw_location.GetMethod()); 7462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_exception.reset(old_exception_obj); 7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_dex_pc = old_throw_location.GetDexPc(); 7662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->ClearException(); 7762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 7862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers CHECK(old_exception.get() != NULL); 792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // clear exception to call FindSystemClass 812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers self->ClearException(); 822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* eiie_class = class_linker->FindSystemClass("Ljava/lang/ExceptionInInitializerError;"); 842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK(!self->IsExceptionPending()); 852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 8662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Only verification errors, not initialization problems, should set a verify error. 8762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // This is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case. 8862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Class* exception_class = old_exception->GetClass(); 892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (!eiie_class->IsAssignableFrom(exception_class)) { 902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetVerifyErrorClass(exception_class); 912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 9362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Restore exception. 9462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation gc_safe_throw_location(old_throw_this_object.get(), old_throw_method.get(), 9562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_dex_pc); 9662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 9762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->SetException(gc_safe_throw_location, old_exception.get()); 982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false); 1002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetDexCache(DexCache* new_dex_cache) { 1032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false); 1042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1062dd0e2cea360bc9206eb88ecc40d259e796c239dIan RogersObject* Class::AllocObject(Thread* self) { 1072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(!IsArrayClass()) << PrettyClass(this); 1082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsInstantiable()) << PrettyClass(this); 1092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // TODO: decide whether we want this check. It currently fails during bootstrap. 1102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this); 1112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK_GE(this->object_size_, sizeof(Object)); 1122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return Runtime::Current()->GetHeap()->AllocObject(self, this, this->object_size_); 1132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetClassSize(size_t new_class_size) { 1162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this); 1172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false); 1182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// Return the class' name. The exact format is bizarre, but it's the specified behavior for 1212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int" 1222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than 1232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness. 1242dd0e2cea360bc9206eb88ecc40d259e796c239dIan RogersString* Class::ComputeName() { 1252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers String* name = GetName(); 1262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name != NULL) { 1272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return name; 1282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers std::string descriptor(ClassHelper(this).GetDescriptor()); 1302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if ((descriptor[0] != 'L') && (descriptor[0] != '[')) { 1312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // The descriptor indicates that this is the class for 1322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // a primitive type; special-case the return value. 1332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const char* c_name = NULL; 1342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers switch (descriptor[0]) { 1352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'Z': c_name = "boolean"; break; 1362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'B': c_name = "byte"; break; 1372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'C': c_name = "char"; break; 1382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'S': c_name = "short"; break; 1392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'I': c_name = "int"; break; 1402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'J': c_name = "long"; break; 1412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'F': c_name = "float"; break; 1422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'D': c_name = "double"; break; 1432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'V': c_name = "void"; break; 1442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers default: 1452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]); 1462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers name = String::AllocFromModifiedUtf8(Thread::Current(), c_name); 1482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 1492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Convert the UTF-8 name to a java.lang.String. The name must use '.' to separate package 1502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // components. 1512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') { 1522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers descriptor.erase(0, 1); 1532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers descriptor.erase(descriptor.size() - 1); 1542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers std::replace(descriptor.begin(), descriptor.end(), '/', '.'); 1562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers name = String::AllocFromModifiedUtf8(Thread::Current(), descriptor.c_str()); 1572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetName(name); 1592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return name; 1602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::DumpClass(std::ostream& os, int flags) const { 1632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if ((flags & kDumpClassFullDetail) == 0) { 1642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << PrettyClass(this); 1652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if ((flags & kDumpClassClassLoader) != 0) { 1662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << ' ' << GetClassLoader(); 1672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if ((flags & kDumpClassInitialized) != 0) { 1692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << ' ' << GetStatus(); 1702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << "\n"; 1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return; 1732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* super = GetSuperClass(); 1762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassHelper kh(this); 1772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << "----- " << (IsInterface() ? "interface" : "class") << " " 1782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << "'" << kh.GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n", 1792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " objectSize=" << SizeOf() << " " 1802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << "(" << (super != NULL ? super->SizeOf() : -1) << " from super)\n", 1812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" access=0x%04x.%04x\n", 1822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask); 1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (super != NULL) { 1842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " super='" << PrettyClass(super) << "' (cl=" << super->GetClassLoader() << ")\n"; 1852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (IsArrayClass()) { 1872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " componentType=" << PrettyClass(GetComponentType()) << "\n"; 1882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (kh.NumDirectInterfaces() > 0) { 1902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " interfaces (" << kh.NumDirectInterfaces() << "):\n"; 1912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 1922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* interface = kh.GetDirectInterface(i); 1932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const ClassLoader* cl = interface->GetClassLoader(); 1942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl); 1952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " vtable (" << NumVirtualMethods() << " entries, " 1982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << (super != NULL ? super->NumVirtualMethods() : 0) << " in super):\n"; 1992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumVirtualMethods(); ++i) { 2002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetVirtualMethodDuringLinking(i)).c_str()); 2012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " direct methods (" << NumDirectMethods() << " entries):\n"; 2032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumDirectMethods(); ++i) { 2042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetDirectMethod(i)).c_str()); 2052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (NumStaticFields() > 0) { 2072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " static fields (" << NumStaticFields() << " entries):\n"; 2082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (IsResolved() || IsErroneous()) { 2092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumStaticFields(); ++i) { 2102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetStaticField(i)).c_str()); 2112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 2132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " <not yet available>"; 2142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (NumInstanceFields() > 0) { 2172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " instance fields (" << NumInstanceFields() << " entries):\n"; 2182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (IsResolved() || IsErroneous()) { 2192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumInstanceFields(); ++i) { 2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetInstanceField(i)).c_str()); 2212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 2232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " <not yet available>"; 2242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) { 2292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (new_reference_offsets != CLASS_WALK_SUPER) { 2302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Sanity check that the number of bits set in the reference offset bitmap 2312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // agrees with the number of references 2322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t count = 0; 2332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 2342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers count += c->NumReferenceInstanceFieldsDuringLinking(); 2352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), count); 2372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_), 2392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers new_reference_offsets, false); 2402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) { 2432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (new_reference_offsets != CLASS_WALK_SUPER) { 2442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Sanity check that the number of bits set in the reference offset bitmap 2452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // agrees with the number of references 2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), 2472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers NumReferenceStaticFieldsDuringLinking()); 2482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_), 2502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers new_reference_offsets, false); 2512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) { 2542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t i = 0; 2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) { 2562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ++i; 2572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (descriptor1.find('/', i) != StringPiece::npos || 2592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers descriptor2.find('/', i) != StringPiece::npos) { 2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return false; 2612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 2622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return true; 2632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsInSamePackage(const Class* that) const { 2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const Class* klass1 = this; 2682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const Class* klass2 = that; 2692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (klass1 == klass2) { 2702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return true; 2712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Class loaders must match. 2732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (klass1->GetClassLoader() != klass2->GetClassLoader()) { 2742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return false; 2752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Arrays are in the same package when their element classes are. 2772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers while (klass1->IsArrayClass()) { 2782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers klass1 = klass1->GetComponentType(); 2792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers while (klass2->IsArrayClass()) { 2812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers klass2 = klass2->GetComponentType(); 2822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2839fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum // trivial check again for array types 2849fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum if (klass1 == klass2) { 2859fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum return true; 2869fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum } 2872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Compare the package part of the descriptor string. 2889fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum if (LIKELY(!klass1->IsProxyClass() && !klass2->IsProxyClass())) { 2899fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum ClassHelper kh(klass1); 290857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom const DexFile* dex_file1 = &kh.GetDexFile(); 291857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom const DexFile::TypeId* type_id1 = &dex_file1->GetTypeId(klass1->GetDexTypeIndex()); 292857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom const char* descriptor1 = dex_file1->GetTypeDescriptor(*type_id1); 2939fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum kh.ChangeClass(klass2); 294857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom const DexFile* dex_file2 = &kh.GetDexFile(); 295857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom const DexFile::TypeId* type_id2 = &dex_file2->GetTypeId(klass2->GetDexTypeIndex()); 296857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom const char* descriptor2 = dex_file2->GetTypeDescriptor(*type_id2); 2979fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum return IsInSamePackage(descriptor1, descriptor2); 2989fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum } 299857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom ClassHelper kh(klass1); 300857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom std::string descriptor1(kh.GetDescriptor()); 301857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom kh.ChangeClass(klass2); 302857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom std::string descriptor2(kh.GetDescriptor()); 303857fe960a02834c0d6b8792dcc0af8143995cb1fBrian Carlstrom return IsInSamePackage(descriptor1, descriptor2); 3042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsClassClass() const { 3072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* java_lang_Class = GetClass()->GetClass(); 3082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return this == java_lang_Class; 3092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsStringClass() const { 3122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return this == String::GetJavaLangString(); 3132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsThrowableClass() const { 3162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this); 3172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 319ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrombool Class::IsArtFieldClass() const { 3202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* java_lang_Class = GetClass(); 321ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom Class* java_lang_reflect_ArtField = java_lang_Class->GetInstanceField(0)->GetClass(); 322ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return this == java_lang_reflect_ArtField; 3232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 325ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrombool Class::IsArtMethodClass() const { 326ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return this == ArtMethod::GetJavaLangReflectArtMethod(); 3272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetClassLoader(ClassLoader* new_class_loader) { 3302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false); 3312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 333ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) const { 3342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Check the current class before checking the interfaces. 335ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = FindDeclaredVirtualMethod(name, signature); 3362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int32_t iftable_count = GetIfTableCount(); 3412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers IfTable* iftable = GetIfTable(); 3422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (int32_t i = 0; i < iftable_count; i++) { 3432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature); 3442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 351ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 3522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Check the current class before checking the interfaces. 353ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 3542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int32_t iftable_count = GetIfTableCount(); 3592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers IfTable* iftable = GetIfTable(); 3602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (int32_t i = 0; i < iftable_count; i++) { 3612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 3622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 370ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const { 3712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers MethodHelper mh; 3722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumDirectMethods(); ++i) { 373ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = GetDirectMethod(i); 3742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mh.ChangeMethod(method); 3752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name == mh.GetName() && signature == mh.GetSignature()) { 3762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 382ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 3832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (GetDexCache() == dex_cache) { 3842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumDirectMethods(); ++i) { 385ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = GetDirectMethod(i); 3862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method->GetDexMethodIndex() == dex_method_idx) { 3872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 394ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDirectMethod(const StringPiece& name, const StringPiece& signature) const { 3952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 396ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature); 3972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 404ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 4052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 406ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx); 4072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 4082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 414ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, 4152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const StringPiece& signature) const { 4162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers MethodHelper mh; 4172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumVirtualMethods(); ++i) { 418ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = GetVirtualMethod(i); 4192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mh.ChangeMethod(method); 4202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name == mh.GetName() && signature == mh.GetSignature()) { 4212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 427ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 4282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (GetDexCache() == dex_cache) { 4292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumVirtualMethods(); ++i) { 430ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = GetVirtualMethod(i); 4312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method->GetDexMethodIndex() == dex_method_idx) { 4322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 439ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const { 4402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 441ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature); 4422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 4432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 449ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 4502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 451ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 4522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 4532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 459ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) { 4602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class? 4612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Interfaces are not relevant because they can't contain instance fields. 4622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers FieldHelper fh; 4632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumInstanceFields(); ++i) { 464ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = GetInstanceField(i); 4652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers fh.ChangeField(f); 4662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name == fh.GetName() && type == fh.GetTypeDescriptor()) { 4672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 4682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 473ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) { 4742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (GetDexCache() == dex_cache) { 4752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumInstanceFields(); ++i) { 476ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = GetInstanceField(i); 4772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f->GetDexFieldIndex() == dex_field_idx) { 4782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 4792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 485ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) { 4862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class, or any of its superclasses? 4872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Interfaces are not relevant because they can't contain instance fields. 4882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 489ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = c->FindDeclaredInstanceField(name, type); 4902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 4912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 4922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 497ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) { 4982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class, or any of its superclasses? 4992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Interfaces are not relevant because they can't contain instance fields. 5002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 501ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = c->FindDeclaredInstanceField(dex_cache, dex_field_idx); 5022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 509ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) { 5102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(type != NULL); 5112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers FieldHelper fh; 5122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumStaticFields(); ++i) { 513ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = GetStaticField(i); 5142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers fh.ChangeField(f); 5152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name == fh.GetName() && type == fh.GetTypeDescriptor()) { 5162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 522ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) { 5232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (dex_cache == GetDexCache()) { 5242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumStaticFields(); ++i) { 525ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = GetStaticField(i); 5262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f->GetDexFieldIndex() == dex_field_idx) { 5272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 534ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindStaticField(const StringPiece& name, const StringPiece& type) { 5352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class (or its interfaces), or any of its 5362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // superclasses (or their interfaces)? 5372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassHelper kh; 5382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 5392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class? 540ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = k->FindDeclaredStaticField(name, type); 5412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is this field in any of this class' interfaces? 5452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers kh.ChangeClass(k); 5462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 5472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* interface = kh.GetDirectInterface(i); 5482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers f = interface->FindStaticField(name, type); 5492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 557ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) { 5582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassHelper kh; 5592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 5602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class? 561ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx); 5622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is this field in any of this class' interfaces? 5662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers kh.ChangeClass(k); 5672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 5682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* interface = kh.GetDirectInterface(i); 5692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers f = interface->FindStaticField(dex_cache, dex_field_idx); 5702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 578ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindField(const StringPiece& name, const StringPiece& type) { 5792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Find a field using the JLS field resolution order 5802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassHelper kh; 5812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 5822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class? 583ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = k->FindDeclaredInstanceField(name, type); 5842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers f = k->FindDeclaredStaticField(name, type); 5882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is this field in any of this class' interfaces? 5922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers kh.ChangeClass(k); 5932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 5942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* interface = kh.GetDirectInterface(i); 5952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers f = interface->FindStaticField(name, type); 5962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 6002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 6012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 6022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 604ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic void SetPreverifiedFlagOnMethods(mirror::ObjectArray<mirror::ArtMethod>* methods) 605233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 606233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz if (methods != NULL) { 607233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz for (int32_t index = 0, end = methods->GetLength(); index < end; ++index) { 608ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method = methods->GetWithoutChecks(index); 609233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz DCHECK(method != NULL); 610233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz method->SetPreverified(); 611233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 612233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 613233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 614233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 615233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertzvoid Class::SetPreverifiedFlagOnAllMethods() { 616233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz DCHECK(IsVerified()); 617233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SetPreverifiedFlagOnMethods(GetDirectMethods()); 618233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SetPreverifiedFlagOnMethods(GetVirtualMethods()); 619233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 620233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 6212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 6222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 623