class.cc revision 8b2c0b9abc3f520495f4387ea040132ba85cae69
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 537dfb28c066159e6cde8181720f0c451a700ef966Ian Rogersvoid Class::SetStatus(Status new_status, Thread* self) { 547dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers Status old_status = GetStatus(); 557dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers bool class_linker_initialized = Runtime::Current()->GetClassLinker() != nullptr; 567dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers if (LIKELY(class_linker_initialized)) { 577dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers if (UNLIKELY(new_status <= old_status && new_status != kStatusError)) { 588f3c9ae38df2460940a26dff889a84430b6c38d3Ian Rogers LOG(FATAL) << "Unexpected change back of class status for " << PrettyClass(this) << " " 597dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers << old_status << " -> " << new_status; 607dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers } 617dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers if (new_status >= kStatusResolved || old_status >= kStatusResolved) { 627dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers // When classes are being resolved the resolution code should hold the lock. 637dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers CHECK_EQ(GetThinLockId(), self->GetThinLockId()) 647dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers << "Attempt to change status of class while not holding its lock: " 657dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers << PrettyClass(this) << " " << old_status << " -> " << new_status; 668f3c9ae38df2460940a26dff889a84430b6c38d3Ian Rogers } 672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (new_status == kStatusError) { 698f3c9ae38df2460940a26dff889a84430b6c38d3Ian Rogers CHECK_NE(GetStatus(), kStatusError) 708f3c9ae38df2460940a26dff889a84430b6c38d3Ian Rogers << "Attempt to set as erroneous an already erroneous class " << PrettyClass(this); 712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Stash current exception. 7362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SirtRef<mirror::Object> old_throw_this_object(self, NULL); 74ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom SirtRef<mirror::ArtMethod> old_throw_method(self, NULL); 7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SirtRef<mirror::Throwable> old_exception(self, NULL); 7662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t old_throw_dex_pc; 7762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers { 7862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation old_throw_location; 7962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Throwable* old_exception_obj = self->GetException(&old_throw_location); 8062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_this_object.reset(old_throw_location.GetThis()); 8162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_method.reset(old_throw_location.GetMethod()); 8262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_exception.reset(old_exception_obj); 8362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_dex_pc = old_throw_location.GetDexPc(); 8462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->ClearException(); 8562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 8662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers CHECK(old_exception.get() != NULL); 872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // clear exception to call FindSystemClass 892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers self->ClearException(); 902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* eiie_class = class_linker->FindSystemClass("Ljava/lang/ExceptionInInitializerError;"); 922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK(!self->IsExceptionPending()); 932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 9462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Only verification errors, not initialization problems, should set a verify error. 9562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // This is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case. 9662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Class* exception_class = old_exception->GetClass(); 972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (!eiie_class->IsAssignableFrom(exception_class)) { 982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetVerifyErrorClass(exception_class); 992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 10162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Restore exception. 10262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation gc_safe_throw_location(old_throw_this_object.get(), old_throw_method.get(), 10362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_dex_pc); 10462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 10562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->SetException(gc_safe_throw_location, old_exception.get()); 1062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1078f3c9ae38df2460940a26dff889a84430b6c38d3Ian Rogers CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this); 1087dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false); 1097dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers // Classes that are being resolved or initialized need to notify waiters that the class status 1107dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers // changed. See ClassLinker::EnsureResolved and ClassLinker::WaitForInitializeClass. 1117dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers if ((old_status >= kStatusResolved || new_status >= kStatusResolved) && 1127dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers class_linker_initialized) { 1137dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers NotifyAll(self); 1147dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers } 1152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetDexCache(DexCache* new_dex_cache) { 1182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false); 1192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetClassSize(size_t new_class_size) { 1228b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers if (kIsDebugBuild && (new_class_size < GetClassSize())) { 1238b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers DumpClass(LOG(ERROR), kDumpClassFullDetail); 1248b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers CHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this); 1258b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers } 1262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false); 1272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// Return the class' name. The exact format is bizarre, but it's the specified behavior for 1302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int" 1312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than 1322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers// slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness. 1332dd0e2cea360bc9206eb88ecc40d259e796c239dIan RogersString* Class::ComputeName() { 1342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers String* name = GetName(); 1352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name != NULL) { 1362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return name; 1372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers std::string descriptor(ClassHelper(this).GetDescriptor()); 1392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if ((descriptor[0] != 'L') && (descriptor[0] != '[')) { 1402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // The descriptor indicates that this is the class for 1412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // a primitive type; special-case the return value. 1422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const char* c_name = NULL; 1432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers switch (descriptor[0]) { 1442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'Z': c_name = "boolean"; break; 1452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'B': c_name = "byte"; break; 1462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'C': c_name = "char"; break; 1472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'S': c_name = "short"; break; 1482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'I': c_name = "int"; break; 1492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'J': c_name = "long"; break; 1502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'F': c_name = "float"; break; 1512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'D': c_name = "double"; break; 1522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case 'V': c_name = "void"; break; 1532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers default: 1542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]); 1552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers name = String::AllocFromModifiedUtf8(Thread::Current(), c_name); 1572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 1582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Convert the UTF-8 name to a java.lang.String. The name must use '.' to separate package 1592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // components. 1602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') { 1612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers descriptor.erase(0, 1); 1622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers descriptor.erase(descriptor.size() - 1); 1632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers std::replace(descriptor.begin(), descriptor.end(), '/', '.'); 1652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers name = String::AllocFromModifiedUtf8(Thread::Current(), descriptor.c_str()); 1662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetName(name); 1682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return name; 1692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::DumpClass(std::ostream& os, int flags) const { 1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if ((flags & kDumpClassFullDetail) == 0) { 1732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << PrettyClass(this); 1742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if ((flags & kDumpClassClassLoader) != 0) { 1752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << ' ' << GetClassLoader(); 1762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if ((flags & kDumpClassInitialized) != 0) { 1782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << ' ' << GetStatus(); 1792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << "\n"; 1812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return; 1822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* super = GetSuperClass(); 1852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassHelper kh(this); 1862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << "----- " << (IsInterface() ? "interface" : "class") << " " 1872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << "'" << kh.GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n", 1882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " objectSize=" << SizeOf() << " " 1892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << "(" << (super != NULL ? super->SizeOf() : -1) << " from super)\n", 1902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" access=0x%04x.%04x\n", 1912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask); 1922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (super != NULL) { 1932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " super='" << PrettyClass(super) << "' (cl=" << super->GetClassLoader() << ")\n"; 1942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (IsArrayClass()) { 1962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " componentType=" << PrettyClass(GetComponentType()) << "\n"; 1972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (kh.NumDirectInterfaces() > 0) { 1992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " interfaces (" << kh.NumDirectInterfaces() << "):\n"; 2002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 2012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* interface = kh.GetDirectInterface(i); 2022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const ClassLoader* cl = interface->GetClassLoader(); 2032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl); 2042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " vtable (" << NumVirtualMethods() << " entries, " 2072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << (super != NULL ? super->NumVirtualMethods() : 0) << " in super):\n"; 2082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumVirtualMethods(); ++i) { 2092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetVirtualMethodDuringLinking(i)).c_str()); 2102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " direct methods (" << NumDirectMethods() << " entries):\n"; 2122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumDirectMethods(); ++i) { 2132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetDirectMethod(i)).c_str()); 2142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (NumStaticFields() > 0) { 2162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " static fields (" << NumStaticFields() << " entries):\n"; 2172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (IsResolved() || IsErroneous()) { 2182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumStaticFields(); ++i) { 2192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetStaticField(i)).c_str()); 2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 2222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " <not yet available>"; 2232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (NumInstanceFields() > 0) { 2262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " instance fields (" << NumInstanceFields() << " entries):\n"; 2272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (IsResolved() || IsErroneous()) { 2282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumInstanceFields(); ++i) { 2292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetInstanceField(i)).c_str()); 2302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 2322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers os << " <not yet available>"; 2332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) { 2382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (new_reference_offsets != CLASS_WALK_SUPER) { 2392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Sanity check that the number of bits set in the reference offset bitmap 2402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // agrees with the number of references 2412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t count = 0; 2422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 2432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers count += c->NumReferenceInstanceFieldsDuringLinking(); 2442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), count); 2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_), 2482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers new_reference_offsets, false); 2492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) { 2522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (new_reference_offsets != CLASS_WALK_SUPER) { 2532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Sanity check that the number of bits set in the reference offset bitmap 2542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // agrees with the number of references 2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), 2562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers NumReferenceStaticFieldsDuringLinking()); 2572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_), 2592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers new_reference_offsets, false); 2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) { 2632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t i = 0; 2642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) { 2652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ++i; 2662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (descriptor1.find('/', i) != StringPiece::npos || 2682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers descriptor2.find('/', i) != StringPiece::npos) { 2692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return false; 2702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 2712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return true; 2722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsInSamePackage(const Class* that) const { 2762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const Class* klass1 = this; 2772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const Class* klass2 = that; 2782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (klass1 == klass2) { 2792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return true; 2802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Class loaders must match. 2822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (klass1->GetClassLoader() != klass2->GetClassLoader()) { 2832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return false; 2842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Arrays are in the same package when their element classes are. 2862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers while (klass1->IsArrayClass()) { 2872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers klass1 = klass1->GetComponentType(); 2882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers while (klass2->IsArrayClass()) { 2902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers klass2 = klass2->GetComponentType(); 2912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2929fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum // trivial check again for array types 2939fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum if (klass1 == klass2) { 2949fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum return true; 2959fa3f20c5fa101a4f55f123d817590b7cfbdbfc0Anwar Ghuloum } 2962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Compare the package part of the descriptor string. 2978b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers return IsInSamePackage(ClassHelper(klass1).GetDescriptor(), 2988b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers ClassHelper(klass2).GetDescriptor()); 2992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsClassClass() const { 3022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* java_lang_Class = GetClass()->GetClass(); 3032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return this == java_lang_Class; 3042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsStringClass() const { 3072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return this == String::GetJavaLangString(); 3082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersbool Class::IsThrowableClass() const { 3112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this); 3122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 314ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrombool Class::IsArtFieldClass() const { 3152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* java_lang_Class = GetClass(); 316ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom Class* java_lang_reflect_ArtField = java_lang_Class->GetInstanceField(0)->GetClass(); 317ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return this == java_lang_reflect_ArtField; 3182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 320ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrombool Class::IsArtMethodClass() const { 321ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return this == ArtMethod::GetJavaLangReflectArtMethod(); 3222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid Class::SetClassLoader(ClassLoader* new_class_loader) { 3252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false); 3262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 328ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) const { 3292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Check the current class before checking the interfaces. 330ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = FindDeclaredVirtualMethod(name, signature); 3312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int32_t iftable_count = GetIfTableCount(); 3362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers IfTable* iftable = GetIfTable(); 3372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (int32_t i = 0; i < iftable_count; i++) { 3382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature); 3392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 346ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 3472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Check the current class before checking the interfaces. 348ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 3492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int32_t iftable_count = GetIfTableCount(); 3542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers IfTable* iftable = GetIfTable(); 3552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (int32_t i = 0; i < iftable_count; i++) { 3562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 3572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 365ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const { 3662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers MethodHelper mh; 3672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumDirectMethods(); ++i) { 368ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = GetDirectMethod(i); 3692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mh.ChangeMethod(method); 3702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name == mh.GetName() && signature == mh.GetSignature()) { 3712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 377ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 3782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (GetDexCache() == dex_cache) { 3792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumDirectMethods(); ++i) { 380ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = GetDirectMethod(i); 3812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method->GetDexMethodIndex() == dex_method_idx) { 3822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 389ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDirectMethod(const StringPiece& name, const StringPiece& signature) const { 3902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 391ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature); 3922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 3932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 3942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 3972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 399ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 4002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 401ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx); 4022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 4032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 409ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, 4102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const StringPiece& signature) const { 4112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers MethodHelper mh; 4122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumVirtualMethods(); ++i) { 413ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = GetVirtualMethod(i); 4142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mh.ChangeMethod(method); 4152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name == mh.GetName() && signature == mh.GetSignature()) { 4162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 422ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 4232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (GetDexCache() == dex_cache) { 4242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumVirtualMethods(); ++i) { 425ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = GetVirtualMethod(i); 4262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method->GetDexMethodIndex() == dex_method_idx) { 4272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 434ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const { 4352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 436ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature); 4372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 4382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 444ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const { 4452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) { 446ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx); 4472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method != NULL) { 4482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 454ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) { 4552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class? 4562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Interfaces are not relevant because they can't contain instance fields. 4572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers FieldHelper fh; 4582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumInstanceFields(); ++i) { 459ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = GetInstanceField(i); 4602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers fh.ChangeField(f); 4612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name == fh.GetName() && type == fh.GetTypeDescriptor()) { 4622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 4632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 468ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) { 4692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (GetDexCache() == dex_cache) { 4702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumInstanceFields(); ++i) { 471ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = GetInstanceField(i); 4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f->GetDexFieldIndex() == dex_field_idx) { 4732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 4742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 480ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) { 4812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class, or any of its superclasses? 4822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Interfaces are not relevant because they can't contain instance fields. 4832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 484ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = c->FindDeclaredInstanceField(name, type); 4852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 4862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 4872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 4902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 492ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) { 4932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class, or any of its superclasses? 4942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Interfaces are not relevant because they can't contain instance fields. 4952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* c = this; c != NULL; c = c->GetSuperClass()) { 496ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = c->FindDeclaredInstanceField(dex_cache, dex_field_idx); 4972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 4982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 4992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 504ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) { 5052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(type != NULL); 5062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers FieldHelper fh; 5072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumStaticFields(); ++i) { 508ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = GetStaticField(i); 5092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers fh.ChangeField(f); 5102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (name == fh.GetName() && type == fh.GetTypeDescriptor()) { 5112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 517ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) { 5182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (dex_cache == GetDexCache()) { 5192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (size_t i = 0; i < NumStaticFields(); ++i) { 520ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = GetStaticField(i); 5212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f->GetDexFieldIndex() == dex_field_idx) { 5222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 529ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindStaticField(const StringPiece& name, const StringPiece& type) { 5302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class (or its interfaces), or any of its 5312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // superclasses (or their interfaces)? 5322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassHelper kh; 5332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 5342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class? 535ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = k->FindDeclaredStaticField(name, type); 5362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is this field in any of this class' interfaces? 5402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers kh.ChangeClass(k); 5412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 5422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* interface = kh.GetDirectInterface(i); 5432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers f = interface->FindStaticField(name, type); 5442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 552ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) { 5532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassHelper kh; 5542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 5552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class? 556ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx); 5572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is this field in any of this class' interfaces? 5612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers kh.ChangeClass(k); 5622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 5632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* interface = kh.GetDirectInterface(i); 5642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers f = interface->FindStaticField(dex_cache, dex_field_idx); 5652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 573ea46f950e7a51585db293cd7f047de190a482414Brian CarlstromArtField* Class::FindField(const StringPiece& name, const StringPiece& type) { 5742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Find a field using the JLS field resolution order 5752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ClassHelper kh; 5762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (Class* k = this; k != NULL; k = k->GetSuperClass()) { 5772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is the field in this class? 578ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = k->FindDeclaredInstanceField(name, type); 5792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers f = k->FindDeclaredStaticField(name, type); 5832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Is this field in any of this class' interfaces? 5872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers kh.ChangeClass(k); 5882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) { 5892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Class* interface = kh.GetDirectInterface(i); 5902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers f = interface->FindStaticField(name, type); 5912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (f != NULL) { 5922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return f; 5932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return NULL; 5972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 599ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic void SetPreverifiedFlagOnMethods(mirror::ObjectArray<mirror::ArtMethod>* methods) 600233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 601233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz if (methods != NULL) { 602233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz for (int32_t index = 0, end = methods->GetLength(); index < end; ++index) { 603ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method = methods->GetWithoutChecks(index); 604233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz DCHECK(method != NULL); 605233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz method->SetPreverified(); 606233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 607233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 608233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 609233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 610233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertzvoid Class::SetPreverifiedFlagOnAllMethods() { 611233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz DCHECK(IsVerified()); 612233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SetPreverifiedFlagOnMethods(GetDirectMethods()); 613233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SetPreverifiedFlagOnMethods(GetVirtualMethods()); 614233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 615233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 6162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 6172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 618