summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc356
1 files changed, 175 insertions, 181 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 184e5d4be9..cfe3bf4c0f 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -170,20 +170,6 @@ const char* ClassLinker::class_roots_descriptors_[] = {
"[Ljava/lang/StackTraceElement;",
};
-ClassLinker* ClassLinker::CreateFromCompiler(const std::vector<const DexFile*>& boot_class_path,
- InternTable* intern_table) {
- CHECK_NE(boot_class_path.size(), 0U);
- UniquePtr<ClassLinker> class_linker(new ClassLinker(intern_table));
- class_linker->InitFromCompiler(boot_class_path);
- return class_linker.release();
-}
-
-ClassLinker* ClassLinker::CreateFromImage(InternTable* intern_table) {
- UniquePtr<ClassLinker> class_linker(new ClassLinker(intern_table));
- class_linker->InitFromImage();
- return class_linker.release();
-}
-
ClassLinker::ClassLinker(InternTable* intern_table)
// dex_lock_ is recursive as it may be used in stack dumping.
: dex_lock_("ClassLinker dex lock", kDefaultMutexLevel),
@@ -211,14 +197,16 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class
// java_lang_Class comes first, it's needed for AllocClass
Thread* self = Thread::Current();
gc::Heap* heap = Runtime::Current()->GetHeap();
- SirtRef<mirror::Class>
- java_lang_Class(self,
- down_cast<mirror::Class*>(heap->AllocObject(self, NULL,
- sizeof(mirror::ClassClass))));
+ // The GC can't handle an object with a null class since we can't get the size of this object.
+ heap->IncrementDisableGC(self);
+ SirtRef<mirror::Class> java_lang_Class(
+ self, down_cast<mirror::Class*>(
+ heap->AllocNonMovableObject(self, NULL, sizeof(mirror::ClassClass))));
CHECK(java_lang_Class.get() != NULL);
mirror::Class::SetClassClass(java_lang_Class.get());
java_lang_Class->SetClass(java_lang_Class.get());
java_lang_Class->SetClassSize(sizeof(mirror::ClassClass));
+ heap->DecrementDisableGC(self);
// AllocClass(mirror::Class*) can now be used
// Class[] is used for reflection support.
@@ -401,7 +389,7 @@ void ClassLinker::InitFromCompiler(const std::vector<const DexFile*>& boot_class
array_iftable_->SetInterface(1, java_io_Serializable);
// Sanity check Class[] and Object[]'s interfaces.
- ClassHelper kh(class_array_class.get(), this);
+ ClassHelper kh(class_array_class.get());
CHECK_EQ(java_lang_Cloneable, kh.GetDirectInterface(0));
CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
kh.ChangeClass(object_array_class.get());
@@ -487,7 +475,7 @@ void ClassLinker::FinishInit() {
FindSystemClass("Ljava/lang/ref/FinalizerReference;");
mirror::ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
- FieldHelper fh(pendingNext, this);
+ FieldHelper fh(pendingNext);
CHECK_STREQ(fh.GetName(), "pendingNext");
CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
@@ -1043,6 +1031,7 @@ void ClassLinker::InitFromImage() {
VLOG(startup) << "ClassLinker::InitFromImage entering";
CHECK(!init_done_);
+ Thread* self = Thread::Current();
gc::Heap* heap = Runtime::Current()->GetHeap();
gc::space::ImageSpace* space = heap->GetImageSpace();
dex_cache_image_class_lookup_required_ = true;
@@ -1059,9 +1048,10 @@ void ClassLinker::InitFromImage() {
mirror::ObjectArray<mirror::DexCache>* dex_caches =
dex_caches_object->AsObjectArray<mirror::DexCache>();
- mirror::ObjectArray<mirror::Class>* class_roots =
- space->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<mirror::Class>();
- class_roots_ = class_roots;
+ SirtRef<mirror::ObjectArray<mirror::Class> > class_roots(
+ self,
+ space->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<mirror::Class>());
+ class_roots_ = class_roots.get();
// Special case of setting up the String class early so that we can test arbitrary objects
// as being Strings or not
@@ -1069,7 +1059,6 @@ void ClassLinker::InitFromImage() {
CHECK_EQ(oat_file.GetOatHeader().GetDexFileCount(),
static_cast<uint32_t>(dex_caches->GetLength()));
- Thread* self = Thread::Current();
for (int32_t i = 0; i < dex_caches->GetLength(); i++) {
SirtRef<mirror::DexCache> dex_cache(self, dex_caches->Get(i));
const std::string& dex_file_location(dex_cache->GetLocation()->ToModifiedUtf8());
@@ -1096,13 +1085,12 @@ void ClassLinker::InitFromImage() {
// Set entry point to interpreter if in InterpretOnly mode.
if (Runtime::Current()->GetInstrumentation()->InterpretOnly()) {
ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
- heap->FlushAllocStack();
- heap->GetLiveBitmap()->Walk(InitFromImageInterpretOnlyCallback, this);
+ heap->VisitObjects(InitFromImageInterpretOnlyCallback, this);
}
// reinit class_roots_
mirror::Class::SetClassClass(class_roots->Get(kJavaLangClass));
- class_roots_ = class_roots;
+ class_roots_ = class_roots.get();
// reinit array_iftable_ from any array class instance, they should be ==
array_iftable_ = GetClassRoot(kObjectArrayClass)->GetIfTable();
@@ -1192,7 +1180,6 @@ void ClassLinker::VisitClassesWithoutClassesLock(ClassVisitor* visitor, void* ar
}
}
-
ClassLinker::~ClassLinker() {
mirror::Class::ResetClass();
mirror::String::ResetClass();
@@ -1214,10 +1201,10 @@ ClassLinker::~ClassLinker() {
mirror::DexCache* ClassLinker::AllocDexCache(Thread* self, const DexFile& dex_file) {
gc::Heap* heap = Runtime::Current()->GetHeap();
- mirror::Class* dex_cache_class = GetClassRoot(kJavaLangDexCache);
- SirtRef<mirror::DexCache> dex_cache(self,
- down_cast<mirror::DexCache*>(heap->AllocObject(self, dex_cache_class,
- dex_cache_class->GetObjectSize())));
+ SirtRef<mirror::Class> dex_cache_class(self, GetClassRoot(kJavaLangDexCache));
+ SirtRef<mirror::DexCache> dex_cache(
+ self, down_cast<mirror::DexCache*>(
+ heap->AllocObject(self, dex_cache_class.get(), dex_cache_class->GetObjectSize())));
if (dex_cache.get() == NULL) {
return NULL;
}
@@ -1253,13 +1240,8 @@ mirror::DexCache* ClassLinker::AllocDexCache(Thread* self, const DexFile& dex_fi
return NULL;
}
- dex_cache->Init(&dex_file,
- location.get(),
- strings.get(),
- types.get(),
- methods.get(),
- fields.get(),
- initialized_static_storage.get());
+ dex_cache->Init(&dex_file, location.get(), strings.get(), types.get(), methods.get(),
+ fields.get(), initialized_static_storage.get());
return dex_cache.get();
}
@@ -1267,7 +1249,7 @@ mirror::Class* ClassLinker::AllocClass(Thread* self, mirror::Class* java_lang_Cl
size_t class_size) {
DCHECK_GE(class_size, sizeof(mirror::Class));
gc::Heap* heap = Runtime::Current()->GetHeap();
- mirror::Object* k = heap->AllocObject(self, java_lang_Class, class_size);
+ mirror::Object* k = heap->AllocNonMovableObject(self, java_lang_Class, class_size);
if (UNLIKELY(k == NULL)) {
CHECK(self->IsExceptionPending()); // OOME.
return NULL;
@@ -1285,18 +1267,19 @@ mirror::Class* ClassLinker::AllocClass(Thread* self, size_t class_size) {
}
mirror::ArtField* ClassLinker::AllocArtField(Thread* self) {
- return down_cast<mirror::ArtField*>(GetClassRoot(kJavaLangReflectArtField)->AllocObject(self));
+ return down_cast<mirror::ArtField*>(
+ GetClassRoot(kJavaLangReflectArtField)->Alloc<false, true>(self));
}
mirror::ArtMethod* ClassLinker::AllocArtMethod(Thread* self) {
- return down_cast<mirror::ArtMethod*>(GetClassRoot(kJavaLangReflectArtMethod)->AllocObject(self));
+ return down_cast<mirror::ArtMethod*>(
+ GetClassRoot(kJavaLangReflectArtMethod)->Alloc<false, true>(self));
}
-mirror::ObjectArray<mirror::StackTraceElement>* ClassLinker::AllocStackTraceElementArray(Thread* self,
- size_t length) {
- return mirror::ObjectArray<mirror::StackTraceElement>::Alloc(self,
- GetClassRoot(kJavaLangStackTraceElementArrayClass),
- length);
+mirror::ObjectArray<mirror::StackTraceElement>* ClassLinker::AllocStackTraceElementArray(
+ Thread* self, size_t length) {
+ return mirror::ObjectArray<mirror::StackTraceElement>::Alloc(
+ self, GetClassRoot(kJavaLangStackTraceElementArrayClass), length);
}
static mirror::Class* EnsureResolved(Thread* self, mirror::Class* klass)
@@ -1332,10 +1315,12 @@ bool ClassLinker::IsInBootClassPath(const char* descriptor) {
}
mirror::Class* ClassLinker::FindSystemClass(const char* descriptor) {
- return FindClass(descriptor, NULL);
+ SirtRef<mirror::ClassLoader> class_loader(Thread::Current(), nullptr);
+ return FindClass(descriptor, class_loader);
}
-mirror::Class* ClassLinker::FindClass(const char* descriptor, mirror::ClassLoader* class_loader) {
+mirror::Class* ClassLinker::FindClass(const char* descriptor,
+ SirtRef<mirror::ClassLoader>& class_loader) {
DCHECK_NE(*descriptor, '\0') << "descriptor is empty string";
Thread* self = Thread::Current();
DCHECK(self != NULL);
@@ -1346,20 +1331,19 @@ mirror::Class* ClassLinker::FindClass(const char* descriptor, mirror::ClassLoade
return FindPrimitiveClass(descriptor[0]);
}
// Find the class in the loaded classes table.
- mirror::Class* klass = LookupClass(descriptor, class_loader);
+ mirror::Class* klass = LookupClass(descriptor, class_loader.get());
if (klass != NULL) {
return EnsureResolved(self, klass);
}
// Class is not yet loaded.
if (descriptor[0] == '[') {
return CreateArrayClass(descriptor, class_loader);
-
- } else if (class_loader == NULL) {
+ } else if (class_loader.get() == nullptr) {
DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, boot_class_path_);
if (pair.second != NULL) {
- return DefineClass(descriptor, NULL, *pair.first, *pair.second);
+ SirtRef<mirror::ClassLoader> class_loader(self, nullptr);
+ return DefineClass(descriptor, class_loader, *pair.first, *pair.second);
}
-
} else if (Runtime::Current()->UseCompileTimeClassPath()) {
// First try the boot class path, we check the descriptor first to avoid an unnecessary
// throw of a NoClassDefFoundError.
@@ -1372,7 +1356,8 @@ mirror::Class* ClassLinker::FindClass(const char* descriptor, mirror::ClassLoade
const std::vector<const DexFile*>* class_path;
{
ScopedObjectAccessUnchecked soa(self);
- ScopedLocalRef<jobject> jclass_loader(soa.Env(), soa.AddLocalReference<jobject>(class_loader));
+ ScopedLocalRef<jobject> jclass_loader(soa.Env(),
+ soa.AddLocalReference<jobject>(class_loader.get()));
class_path = &Runtime::Current()->GetCompileTimeClassPath(jclass_loader.get());
}
@@ -1384,7 +1369,7 @@ mirror::Class* ClassLinker::FindClass(const char* descriptor, mirror::ClassLoade
} else {
ScopedObjectAccessUnchecked soa(self->GetJniEnv());
ScopedLocalRef<jobject> class_loader_object(soa.Env(),
- soa.AddLocalReference<jobject>(class_loader));
+ soa.AddLocalReference<jobject>(class_loader.get()));
std::string class_name_string(DescriptorToDot(descriptor));
ScopedLocalRef<jobject> result(soa.Env(), NULL);
{
@@ -1418,7 +1403,7 @@ mirror::Class* ClassLinker::FindClass(const char* descriptor, mirror::ClassLoade
}
mirror::Class* ClassLinker::DefineClass(const char* descriptor,
- mirror::ClassLoader* class_loader,
+ SirtRef<mirror::ClassLoader>& class_loader,
const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def) {
Thread* self = Thread::Current();
@@ -1449,7 +1434,7 @@ mirror::Class* ClassLinker::DefineClass(const char* descriptor,
return NULL;
}
klass->SetDexCache(FindDexCache(dex_file));
- LoadClass(dex_file, dex_class_def, klass, class_loader);
+ LoadClass(dex_file, dex_class_def, klass, class_loader.get());
// Check for a pending exception during load
if (self->IsExceptionPending()) {
klass->SetStatus(mirror::Class::kStatusError, self);
@@ -1457,14 +1442,12 @@ mirror::Class* ClassLinker::DefineClass(const char* descriptor,
}
ObjectLock lock(self, klass.get());
klass->SetClinitThreadId(self->GetTid());
- {
- // Add the newly loaded class to the loaded classes table.
- mirror::Class* existing = InsertClass(descriptor, klass.get(), Hash(descriptor));
- if (existing != NULL) {
- // We failed to insert because we raced with another thread. Calling EnsureResolved may cause
- // this thread to block.
- return EnsureResolved(self, existing);
- }
+ // Add the newly loaded class to the loaded classes table.
+ mirror::Class* existing = InsertClass(descriptor, klass.get(), Hash(descriptor));
+ if (existing != NULL) {
+ // We failed to insert because we raced with another thread. Calling EnsureResolved may cause
+ // this thread to block.
+ return EnsureResolved(self, existing);
}
// Finish loading (if necessary) by finding parents
CHECK(!klass->IsLoaded());
@@ -1476,7 +1459,9 @@ mirror::Class* ClassLinker::DefineClass(const char* descriptor,
CHECK(klass->IsLoaded());
// Link the class (if necessary)
CHECK(!klass->IsResolved());
- if (!LinkClass(klass, NULL, self)) {
+ // TODO: Use fast jobjects?
+ SirtRef<mirror::ObjectArray<mirror::Class> > interfaces(self, nullptr);
+ if (!LinkClass(self, klass, interfaces)) {
// Linking failed.
klass->SetStatus(mirror::Class::kStatusError, self);
return NULL;
@@ -2083,7 +2068,7 @@ mirror::Class* ClassLinker::InitializePrimitiveClass(mirror::Class* primitive_cl
//
// Returns NULL with an exception raised on failure.
mirror::Class* ClassLinker::CreateArrayClass(const char* descriptor,
- mirror::ClassLoader* class_loader) {
+ SirtRef<mirror::ClassLoader>& class_loader) {
// Identify the underlying component type
CHECK_EQ('[', descriptor[0]);
mirror::Class* component_type = FindClass(descriptor + 1, class_loader);
@@ -2109,7 +2094,7 @@ mirror::Class* ClassLinker::CreateArrayClass(const char* descriptor,
// because we effectively do this lookup again when we add the new
// class to the hash table --- necessary because of possible races with
// other threads.)
- if (class_loader != component_type->GetClassLoader()) {
+ if (class_loader.get() != component_type->GetClassLoader()) {
mirror::Class* new_class = LookupClass(descriptor, component_type->GetClassLoader());
if (new_class != NULL) {
return new_class;
@@ -2266,11 +2251,10 @@ mirror::Class* ClassLinker::InsertClass(const char* descriptor, mirror::Class* k
bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* class_loader) {
size_t hash = Hash(descriptor);
WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
- ClassHelper kh;
for (auto it = class_table_.lower_bound(hash), end = class_table_.end(); it != end && it->first == hash;
++it) {
mirror::Class* klass = it->second;
- kh.ChangeClass(klass);
+ ClassHelper kh(klass);
if ((klass->GetClassLoader() == class_loader) &&
(strcmp(descriptor, kh.GetDescriptor()) == 0)) {
class_table_.erase(it);
@@ -2313,18 +2297,17 @@ mirror::Class* ClassLinker::LookupClass(const char* descriptor,
mirror::Class* ClassLinker::LookupClassFromTableLocked(const char* descriptor,
const mirror::ClassLoader* class_loader,
size_t hash) {
- ClassHelper kh(NULL, this);
auto end = class_table_.end();
for (auto it = class_table_.lower_bound(hash); it != end && it->first == hash; ++it) {
mirror::Class* klass = it->second;
- kh.ChangeClass(klass);
+ ClassHelper kh(klass);
if ((klass->GetClassLoader() == class_loader) &&
(strcmp(descriptor, kh.GetDescriptor()) == 0)) {
if (kIsDebugBuild) {
// Check for duplicates in the table.
for (++it; it != end && it->first == hash; ++it) {
mirror::Class* klass2 = it->second;
- kh.ChangeClass(klass2);
+ ClassHelper kh(klass2);
CHECK(!((klass2->GetClassLoader() == class_loader) &&
(strcmp(descriptor, kh.GetDescriptor()) == 0)))
<< PrettyClass(klass) << " " << klass << " " << klass->GetClassLoader() << " "
@@ -2354,14 +2337,13 @@ void ClassLinker::MoveImageClassesToClassTable() {
const char* old_no_suspend_cause =
self->StartAssertNoThreadSuspension("Moving image classes to class table");
mirror::ObjectArray<mirror::DexCache>* dex_caches = GetImageDexCaches();
- ClassHelper kh(NULL, this);
for (int32_t i = 0; i < dex_caches->GetLength(); i++) {
mirror::DexCache* dex_cache = dex_caches->Get(i);
mirror::ObjectArray<mirror::Class>* types = dex_cache->GetResolvedTypes();
for (int32_t j = 0; j < types->GetLength(); j++) {
mirror::Class* klass = types->Get(j);
if (klass != NULL) {
- kh.ChangeClass(klass);
+ ClassHelper kh(klass);
DCHECK(klass->GetClassLoader() == NULL);
const char* descriptor = kh.GetDescriptor();
size_t hash = Hash(descriptor);
@@ -2429,11 +2411,10 @@ void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Clas
}
size_t hash = Hash(descriptor);
ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
- ClassHelper kh(NULL, this);
for (auto it = class_table_.lower_bound(hash), end = class_table_.end();
it != end && it->first == hash; ++it) {
mirror::Class* klass = it->second;
- kh.ChangeClass(klass);
+ ClassHelper kh(klass);
if (strcmp(descriptor, kh.GetDescriptor()) == 0) {
result.push_back(klass);
}
@@ -2687,12 +2668,10 @@ static void CheckProxyConstructor(mirror::ArtMethod* constructor);
static void CheckProxyMethod(mirror::ArtMethod* method,
SirtRef<mirror::ArtMethod>& prototype);
-mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
- mirror::ObjectArray<mirror::Class>* interfaces,
- mirror::ClassLoader* loader,
- mirror::ObjectArray<mirror::ArtMethod>* methods,
- mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >* throws) {
- Thread* self = Thread::Current();
+mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccess& soa, jstring name,
+ jobjectArray interfaces, jobject loader,
+ jobjectArray methods, jobjectArray throws) {
+ Thread* self = soa.Self();
SirtRef<mirror::Class> klass(self, AllocClass(self, GetClassRoot(kJavaLangClass),
sizeof(mirror::SynthesizedProxyClass)));
if (klass.get() == NULL) {
@@ -2702,9 +2681,9 @@ mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
DCHECK(klass->GetClass() != NULL);
klass->SetObjectSize(sizeof(mirror::Proxy));
klass->SetAccessFlags(kAccClassIsProxy | kAccPublic | kAccFinal);
- klass->SetClassLoader(loader);
+ klass->SetClassLoader(soa.Decode<mirror::ClassLoader*>(loader));
DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
- klass->SetName(name);
+ klass->SetName(soa.Decode<mirror::String*>(name));
mirror::Class* proxy_class = GetClassRoot(kJavaLangReflectProxy);
klass->SetDexCache(proxy_class->GetDexCache());
klass->SetStatus(mirror::Class::kStatusIdx, self);
@@ -2742,8 +2721,7 @@ mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
// Proxies have 1 direct method, the constructor
{
- mirror::ObjectArray<mirror::ArtMethod>* directs =
- AllocArtMethodArray(self, 1);
+ mirror::ObjectArray<mirror::ArtMethod>* directs = AllocArtMethodArray(self, 1);
if (UNLIKELY(directs == NULL)) {
CHECK(self->IsExceptionPending()); // OOME.
return NULL;
@@ -2757,11 +2735,11 @@ mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
klass->SetDirectMethod(0, constructor);
}
- // Create virtual method using specified prototypes
- size_t num_virtual_methods = methods->GetLength();
+ // Create virtual method using specified prototypes.
+ size_t num_virtual_methods =
+ soa.Decode<mirror::ObjectArray<mirror::ArtMethod>*>(methods)->GetLength();
{
- mirror::ObjectArray<mirror::ArtMethod>* virtuals =
- AllocArtMethodArray(self, num_virtual_methods);
+ mirror::ObjectArray<mirror::ArtMethod>* virtuals = AllocArtMethodArray(self, num_virtual_methods);
if (UNLIKELY(virtuals == NULL)) {
CHECK(self->IsExceptionPending()); // OOME.
return NULL;
@@ -2769,7 +2747,9 @@ mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
klass->SetVirtualMethods(virtuals);
}
for (size_t i = 0; i < num_virtual_methods; ++i) {
- SirtRef<mirror::ArtMethod> prototype(self, methods->Get(i));
+ mirror::ObjectArray<mirror::ArtMethod>* decoded_methods =
+ soa.Decode<mirror::ObjectArray<mirror::ArtMethod>*>(methods);
+ SirtRef<mirror::ArtMethod> prototype(self, decoded_methods->Get(i));
mirror::ArtMethod* clone = CreateProxyMethod(self, klass, prototype);
if (UNLIKELY(clone == NULL)) {
CHECK(self->IsExceptionPending()); // OOME.
@@ -2785,13 +2765,15 @@ mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
{
ObjectLock lock(self, klass.get()); // Must hold lock on object when resolved.
// Link the fields and virtual methods, creating vtable and iftables
- if (!LinkClass(klass, interfaces, self)) {
+ SirtRef<mirror::ObjectArray<mirror::Class> > sirt_interfaces(
+ self, soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces));
+ if (!LinkClass(self, klass, sirt_interfaces)) {
klass->SetStatus(mirror::Class::kStatusError, self);
return NULL;
}
- interfaces_sfield->SetObject(klass.get(), interfaces);
- throws_sfield->SetObject(klass.get(), throws);
+ interfaces_sfield->SetObject(klass.get(), soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces));
+ throws_sfield->SetObject(klass.get(), soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >*>(throws));
klass->SetStatus(mirror::Class::kStatusInitialized, self);
}
@@ -2800,22 +2782,25 @@ mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
CHECK(klass->GetIFields() == NULL);
CheckProxyConstructor(klass->GetDirectMethod(0));
for (size_t i = 0; i < num_virtual_methods; ++i) {
- SirtRef<mirror::ArtMethod> prototype(self, methods->Get(i));
+ mirror::ObjectArray<mirror::ArtMethod>* decoded_methods =
+ soa.Decode<mirror::ObjectArray<mirror::ArtMethod>*>(methods);
+ SirtRef<mirror::ArtMethod> prototype(self, decoded_methods->Get(i));
CheckProxyMethod(klass->GetVirtualMethod(i), prototype);
}
+ mirror::String* decoded_name = soa.Decode<mirror::String*>(name);
std::string interfaces_field_name(StringPrintf("java.lang.Class[] %s.interfaces",
- name->ToModifiedUtf8().c_str()));
+ decoded_name->ToModifiedUtf8().c_str()));
CHECK_EQ(PrettyField(klass->GetStaticField(0)), interfaces_field_name);
std::string throws_field_name(StringPrintf("java.lang.Class[][] %s.throws",
- name->ToModifiedUtf8().c_str()));
+ decoded_name->ToModifiedUtf8().c_str()));
CHECK_EQ(PrettyField(klass->GetStaticField(1)), throws_field_name);
mirror::SynthesizedProxyClass* synth_proxy_class =
down_cast<mirror::SynthesizedProxyClass*>(klass.get());
- CHECK_EQ(synth_proxy_class->GetInterfaces(), interfaces);
- CHECK_EQ(synth_proxy_class->GetThrows(), throws);
+ CHECK_EQ(synth_proxy_class->GetInterfaces(), soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces));
+ CHECK_EQ(synth_proxy_class->GetThrows(), soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >*>(throws));
}
std::string descriptor(GetDescriptorForProxy(klass.get()));
mirror::Class* existing = InsertClass(descriptor.c_str(), klass.get(), Hash(descriptor.c_str()));
@@ -2977,6 +2962,10 @@ static bool CanWeInitializeClass(mirror::Class* klass, bool can_init_statics,
return true;
}
+bool ClassLinker::IsInitialized() const {
+ return init_done_;
+}
+
bool ClassLinker::InitializeClass(mirror::Class* klass, bool can_init_statics,
bool can_init_parents) {
// see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol
@@ -3084,7 +3073,9 @@ bool ClassLinker::InitializeClass(mirror::Class* klass, bool can_init_statics,
const DexFile::ClassDef* dex_class_def = kh.GetClassDef();
CHECK(dex_class_def != NULL);
const DexFile& dex_file = kh.GetDexFile();
- EncodedStaticFieldValueIterator it(dex_file, kh.GetDexCache(), klass->GetClassLoader(),
+ SirtRef<mirror::ClassLoader> class_loader(self, klass->GetClassLoader());
+ SirtRef<mirror::DexCache> dex_cache(self, kh.GetDexCache());
+ EncodedStaticFieldValueIterator it(dex_file, &dex_cache, &class_loader,
this, *dex_class_def);
if (it.HasNext()) {
CHECK(can_init_statics);
@@ -3196,12 +3187,11 @@ bool ClassLinker::ValidateSuperClassDescriptors(const mirror::Class* klass) {
}
}
}
- mirror::IfTable* iftable = klass->GetIfTable();
for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
- mirror::Class* interface = iftable->GetInterface(i);
+ mirror::Class* interface = klass->GetIfTable()->GetInterface(i);
if (klass->GetClassLoader() != interface->GetClassLoader()) {
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
- const mirror::ArtMethod* method = iftable->GetMethodArray(i)->Get(j);
+ const mirror::ArtMethod* method = klass->GetIfTable()->GetMethodArray(i)->Get(j);
if (!IsSameMethodSignatureInDifferentClassContexts(method, interface,
method->GetDeclaringClass())) {
ThrowLinkageError(klass, "Class %s method %s resolves differently in interface %s",
@@ -3259,11 +3249,14 @@ bool ClassLinker::IsSameDescriptorInDifferentClassContexts(const char* descripto
if (klass1 == klass2) {
return true;
}
- mirror::Class* found1 = FindClass(descriptor, klass1->GetClassLoader());
+ Thread* self = Thread::Current();
+ SirtRef<mirror::ClassLoader> class_loader1(self, klass1->GetClassLoader());
+ mirror::Class* found1 = FindClass(descriptor, class_loader1);
if (found1 == NULL) {
Thread::Current()->ClearException();
}
- mirror::Class* found2 = FindClass(descriptor, klass2->GetClassLoader());
+ SirtRef<mirror::ClassLoader> class_loader2(self, klass2->GetClassLoader());
+ mirror::Class* found2 = FindClass(descriptor, class_loader2);
if (found2 == NULL) {
Thread::Current()->ClearException();
}
@@ -3285,17 +3278,20 @@ bool ClassLinker::EnsureInitialized(mirror::Class* c, bool can_init_fields, bool
}
void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
- mirror::Class* c, SafeMap<uint32_t, mirror::ArtField*>& field_map) {
- mirror::ClassLoader* cl = c->GetClassLoader();
+ mirror::Class* c,
+ SafeMap<uint32_t, mirror::ArtField*>& field_map) {
const byte* class_data = dex_file.GetClassData(dex_class_def);
ClassDataItemIterator it(dex_file, class_data);
+ Thread* self = Thread::Current();
+ SirtRef<mirror::DexCache> dex_cache(self, c->GetDexCache());
+ SirtRef<mirror::ClassLoader> class_loader(self, c->GetClassLoader());
for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
- field_map.Put(i, ResolveField(dex_file, it.GetMemberIndex(), c->GetDexCache(), cl, true));
+ field_map.Put(i, ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, true));
}
}
-bool ClassLinker::LinkClass(SirtRef<mirror::Class>& klass,
- mirror::ObjectArray<mirror::Class>* interfaces, Thread* self) {
+bool ClassLinker::LinkClass(Thread* self, SirtRef<mirror::Class>& klass,
+ SirtRef<mirror::ObjectArray<mirror::Class> >& interfaces) {
CHECK_EQ(mirror::Class::kStatusLoaded, klass->GetStatus());
if (!LinkSuperClass(klass)) {
return false;
@@ -3419,7 +3415,7 @@ bool ClassLinker::LinkSuperClass(SirtRef<mirror::Class>& klass) {
// Populate the class vtable and itable. Compute return type indices.
bool ClassLinker::LinkMethods(SirtRef<mirror::Class>& klass,
- mirror::ObjectArray<mirror::Class>* interfaces) {
+ SirtRef<mirror::ObjectArray<mirror::Class> >& interfaces) {
if (klass->IsInterface()) {
// No vtable.
size_t count = klass->NumVirtualMethods();
@@ -3453,15 +3449,13 @@ bool ClassLinker::LinkVirtualMethods(SirtRef<mirror::Class>& klass) {
return false;
}
// See if any of our virtual methods override the superclass.
- MethodHelper local_mh(NULL, this);
- MethodHelper super_mh(NULL, this);
for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
mirror::ArtMethod* local_method = klass->GetVirtualMethodDuringLinking(i);
- local_mh.ChangeMethod(local_method);
+ MethodHelper local_mh(local_method);
size_t j = 0;
for (; j < actual_count; ++j) {
mirror::ArtMethod* super_method = vtable->Get(j);
- super_mh.ChangeMethod(super_method);
+ MethodHelper super_mh(super_method);
if (local_mh.HasSameNameAndSignature(&super_mh)) {
if (klass->CanAccessMember(super_method->GetDeclaringClass(), super_method->GetAccessFlags())) {
if (super_method->IsFinal()) {
@@ -3525,7 +3519,7 @@ bool ClassLinker::LinkVirtualMethods(SirtRef<mirror::Class>& klass) {
}
bool ClassLinker::LinkInterfaceMethods(SirtRef<mirror::Class>& klass,
- mirror::ObjectArray<mirror::Class>* interfaces) {
+ SirtRef<mirror::ObjectArray<mirror::Class> >& interfaces) {
// Set the imt table to be all conflicts by default.
klass->SetImTable(Runtime::Current()->GetDefaultImt());
size_t super_ifcount;
@@ -3535,11 +3529,13 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<mirror::Class>& klass,
super_ifcount = 0;
}
size_t ifcount = super_ifcount;
- ClassHelper kh(klass.get(), this);
- uint32_t num_interfaces = interfaces == NULL ? kh.NumDirectInterfaces() : interfaces->GetLength();
+ ClassHelper kh(klass.get());
+ uint32_t num_interfaces =
+ interfaces.get() == nullptr ? kh.NumDirectInterfaces() : interfaces->GetLength();
ifcount += num_interfaces;
for (size_t i = 0; i < num_interfaces; i++) {
- mirror::Class* interface = interfaces == NULL ? kh.GetDirectInterface(i) : interfaces->Get(i);
+ mirror::Class* interface =
+ interfaces.get() == nullptr ? kh.GetDirectInterface(i) : interfaces->Get(i);
ifcount += interface->GetIfTableCount();
}
if (ifcount == 0) {
@@ -3580,7 +3576,8 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<mirror::Class>& klass,
// Flatten the interface inheritance hierarchy.
size_t idx = super_ifcount;
for (size_t i = 0; i < num_interfaces; i++) {
- mirror::Class* interface = interfaces == NULL ? kh.GetDirectInterface(i) : interfaces->Get(i);
+ mirror::Class* interface =
+ interfaces.get() == nullptr ? kh.GetDirectInterface(i) : interfaces->Get(i);
DCHECK(interface != NULL);
if (!interface->IsInterface()) {
ClassHelper ih(interface);
@@ -3643,20 +3640,21 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<mirror::Class>& klass,
return false;
}
std::vector<mirror::ArtMethod*> miranda_list;
- MethodHelper vtable_mh(NULL, this);
- MethodHelper interface_mh(NULL, this);
+ MethodHelper vtable_mh(NULL);
+ MethodHelper interface_mh(NULL);
for (size_t i = 0; i < ifcount; ++i) {
mirror::Class* interface = iftable->GetInterface(i);
size_t num_methods = interface->NumVirtualMethods();
if (num_methods > 0) {
- mirror::ObjectArray<mirror::ArtMethod>* method_array =
- AllocArtMethodArray(self, num_methods);
- if (UNLIKELY(method_array == NULL)) {
+ SirtRef<mirror::ObjectArray<mirror::ArtMethod> >
+ method_array(self, AllocArtMethodArray(self, num_methods));
+ if (UNLIKELY(method_array.get() == nullptr)) {
CHECK(self->IsExceptionPending()); // OOME.
return false;
}
- iftable->SetMethodArray(i, method_array);
- mirror::ObjectArray<mirror::ArtMethod>* vtable = klass->GetVTableDuringLinking();
+ iftable->SetMethodArray(i, method_array.get());
+ SirtRef<mirror::ObjectArray<mirror::ArtMethod> > vtable(self,
+ klass->GetVTableDuringLinking());
for (size_t j = 0; j < num_methods; ++j) {
mirror::ArtMethod* interface_method = interface->GetVirtualMethod(j);
interface_mh.ChangeMethod(interface_method);
@@ -3709,10 +3707,7 @@ bool ClassLinker::LinkInterfaceMethods(SirtRef<mirror::Class>& klass,
CHECK(self->IsExceptionPending()); // OOME.
return false;
}
-#ifdef MOVING_GARBAGE_COLLECTOR
// TODO: If a methods move then the miranda_list may hold stale references.
- UNIMPLEMENTED(FATAL);
-#endif
miranda_list.push_back(miranda_method.get());
}
method_array->Set(j, miranda_method.get());
@@ -3791,17 +3786,16 @@ bool ClassLinker::LinkStaticFields(SirtRef<mirror::Class>& klass) {
}
struct LinkFieldsComparator {
- explicit LinkFieldsComparator(FieldHelper* fh)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : fh_(fh) {}
+ explicit LinkFieldsComparator() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ }
// No thread safety analysis as will be called from STL. Checked lock held in constructor.
bool operator()(const mirror::ArtField* field1, const mirror::ArtField* field2)
NO_THREAD_SAFETY_ANALYSIS {
// First come reference fields, then 64-bit, and finally 32-bit
- fh_->ChangeField(field1);
- Primitive::Type type1 = fh_->GetTypeAsPrimitiveType();
- fh_->ChangeField(field2);
- Primitive::Type type2 = fh_->GetTypeAsPrimitiveType();
+ FieldHelper fh1(field1);
+ Primitive::Type type1 = fh1.GetTypeAsPrimitiveType();
+ FieldHelper fh2(field2);
+ Primitive::Type type2 = fh2.GetTypeAsPrimitiveType();
bool isPrimitive1 = type1 != Primitive::kPrimNot;
bool isPrimitive2 = type2 != Primitive::kPrimNot;
bool is64bit1 = isPrimitive1 && (type1 == Primitive::kPrimLong || type1 == Primitive::kPrimDouble);
@@ -3813,14 +3807,10 @@ struct LinkFieldsComparator {
}
// same basic group? then sort by string.
- fh_->ChangeField(field1);
- const char* name1 = fh_->GetName();
- fh_->ChangeField(field2);
- const char* name2 = fh_->GetName();
+ const char* name1 = fh1.GetName();
+ const char* name2 = fh2.GetName();
return strcmp(name1, name2) < 0;
}
-
- FieldHelper* fh_;
};
bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) {
@@ -3855,17 +3845,15 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) {
CHECK(f != NULL);
grouped_and_sorted_fields.push_back(f);
}
- FieldHelper fh(NULL, this);
- std::sort(grouped_and_sorted_fields.begin(),
- grouped_and_sorted_fields.end(),
- LinkFieldsComparator(&fh));
+ std::sort(grouped_and_sorted_fields.begin(), grouped_and_sorted_fields.end(),
+ LinkFieldsComparator());
// References should be at the front.
size_t current_field = 0;
size_t num_reference_fields = 0;
for (; current_field < num_fields; current_field++) {
mirror::ArtField* field = grouped_and_sorted_fields.front();
- fh.ChangeField(field);
+ FieldHelper fh(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
bool isPrimitive = type != Primitive::kPrimNot;
if (isPrimitive) {
@@ -3884,7 +3872,7 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) {
if (current_field != num_fields && !IsAligned<8>(field_offset.Uint32Value())) {
for (size_t i = 0; i < grouped_and_sorted_fields.size(); i++) {
mirror::ArtField* field = grouped_and_sorted_fields[i];
- fh.ChangeField(field);
+ FieldHelper fh(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
CHECK(type != Primitive::kPrimNot); // should only be working on primitive types
if (type == Primitive::kPrimLong || type == Primitive::kPrimDouble) {
@@ -3906,7 +3894,7 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) {
while (!grouped_and_sorted_fields.empty()) {
mirror::ArtField* field = grouped_and_sorted_fields.front();
grouped_and_sorted_fields.pop_front();
- fh.ChangeField(field);
+ FieldHelper fh(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
CHECK(type != Primitive::kPrimNot); // should only be working on primitive types
fields->Set(current_field, field);
@@ -3920,11 +3908,11 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) {
// We lie to the GC about the java.lang.ref.Reference.referent field, so it doesn't scan it.
if (!is_static &&
- (strcmp("Ljava/lang/ref/Reference;", ClassHelper(klass.get(), this).GetDescriptor()) == 0)) {
+ (strcmp("Ljava/lang/ref/Reference;", ClassHelper(klass.get()).GetDescriptor()) == 0)) {
// We know there are no non-reference fields in the Reference classes, and we know
// that 'referent' is alphabetically last, so this is easy...
CHECK_EQ(num_reference_fields, num_fields);
- fh.ChangeField(fields->Get(num_fields - 1));
+ FieldHelper fh(fields->Get(num_fields - 1));
CHECK_STREQ(fh.GetName(), "referent");
--num_reference_fields;
}
@@ -3942,10 +3930,10 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) {
<< " offset=" << field->GetField32(MemberOffset(mirror::ArtField::OffsetOffset()),
false);
}
- fh.ChangeField(field);
+ FieldHelper fh(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
bool is_primitive = type != Primitive::kPrimNot;
- if ((strcmp("Ljava/lang/ref/Reference;", ClassHelper(klass.get(), this).GetDescriptor()) == 0)
+ if ((strcmp("Ljava/lang/ref/Reference;", ClassHelper(klass.get()).GetDescriptor()) == 0)
&& (strcmp("referent", fh.GetName()) == 0)) {
is_primitive = true; // We lied above, so we have to expect a lie here.
}
@@ -3970,7 +3958,7 @@ bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) {
} else {
klass->SetNumReferenceInstanceFields(num_reference_fields);
if (!klass->IsVariableSize()) {
- DCHECK_GE(size, sizeof(mirror::Object)) << ClassHelper(klass.get(), this).GetDescriptor();
+ DCHECK_GE(size, sizeof(mirror::Object)) << ClassHelper(klass.get()).GetDescriptor();
size_t previous_size = klass->GetObjectSize();
if (previous_size != 0) {
// Make sure that we didn't originally have an incorrect size.
@@ -4034,9 +4022,9 @@ void ClassLinker::CreateReferenceOffsets(SirtRef<mirror::Class>& klass, bool is_
}
}
-mirror::String* ClassLinker::ResolveString(const DexFile& dex_file,
- uint32_t string_idx, mirror::DexCache* dex_cache) {
- DCHECK(dex_cache != NULL);
+mirror::String* ClassLinker::ResolveString(const DexFile& dex_file, uint32_t string_idx,
+ SirtRef<mirror::DexCache>& dex_cache) {
+ DCHECK(dex_cache.get() != nullptr);
mirror::String* resolved = dex_cache->GetResolvedString(string_idx);
if (resolved != NULL) {
return resolved;
@@ -4048,11 +4036,18 @@ mirror::String* ClassLinker::ResolveString(const DexFile& dex_file,
return string;
}
-mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file,
- uint16_t type_idx,
- mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader) {
- DCHECK(dex_cache != NULL);
+mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_idx,
+ const mirror::Class* referrer) {
+ Thread* self = Thread::Current();
+ SirtRef<mirror::DexCache> dex_cache(self, referrer->GetDexCache());
+ SirtRef<mirror::ClassLoader> class_loader(self, referrer->GetClassLoader());
+ return ResolveType(dex_file, type_idx, dex_cache, class_loader);
+}
+
+mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_idx,
+ SirtRef<mirror::DexCache>& dex_cache,
+ SirtRef<mirror::ClassLoader>& class_loader) {
+ DCHECK(dex_cache.get() != NULL);
mirror::Class* resolved = dex_cache->GetResolvedType(type_idx);
if (resolved == NULL) {
const char* descriptor = dex_file.StringByTypeIdx(type_idx);
@@ -4082,11 +4077,11 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file,
mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
uint32_t method_idx,
- mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader,
+ SirtRef<mirror::DexCache>& dex_cache,
+ SirtRef<mirror::ClassLoader>& class_loader,
const mirror::ArtMethod* referrer,
InvokeType type) {
- DCHECK(dex_cache != NULL);
+ DCHECK(dex_cache.get() != NULL);
// Check for hit in the dex cache.
mirror::ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx);
if (resolved != NULL && !resolved->IsRuntimeMethod()) {
@@ -4104,15 +4099,15 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
switch (type) {
case kDirect: // Fall-through.
case kStatic:
- resolved = klass->FindDirectMethod(dex_cache, method_idx);
+ resolved = klass->FindDirectMethod(dex_cache.get(), method_idx);
break;
case kInterface:
- resolved = klass->FindInterfaceMethod(dex_cache, method_idx);
+ resolved = klass->FindInterfaceMethod(dex_cache.get(), method_idx);
DCHECK(resolved == NULL || resolved->GetDeclaringClass()->IsInterface());
break;
case kSuper: // Fall-through.
case kVirtual:
- resolved = klass->FindVirtualMethod(dex_cache, method_idx);
+ resolved = klass->FindVirtualMethod(dex_cache.get(), method_idx);
break;
default:
LOG(FATAL) << "Unreachable - invocation type: " << type;
@@ -4227,12 +4222,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
}
}
-mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file,
- uint32_t field_idx,
- mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader,
+mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t field_idx,
+ SirtRef<mirror::DexCache>& dex_cache,
+ SirtRef<mirror::ClassLoader>& class_loader,
bool is_static) {
- DCHECK(dex_cache != NULL);
+ DCHECK(dex_cache.get() != nullptr);
mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx);
if (resolved != NULL) {
return resolved;
@@ -4245,9 +4239,9 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file,
}
if (is_static) {
- resolved = klass->FindStaticField(dex_cache, field_idx);
+ resolved = klass->FindStaticField(dex_cache.get(), field_idx);
} else {
- resolved = klass->FindInstanceField(dex_cache, field_idx);
+ resolved = klass->FindInstanceField(dex_cache.get(), field_idx);
}
if (resolved == NULL) {
@@ -4269,9 +4263,9 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file,
mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file,
uint32_t field_idx,
- mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader) {
- DCHECK(dex_cache != NULL);
+ SirtRef<mirror::DexCache>& dex_cache,
+ SirtRef<mirror::ClassLoader>& class_loader) {
+ DCHECK(dex_cache.get() != nullptr);
mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx);
if (resolved != NULL) {
return resolved;