diff options
author | 2011-10-10 15:50:01 -0700 | |
---|---|---|
committer | 2011-10-10 15:50:01 -0700 | |
commit | 92827a5fc2598589b3717269cc09c33b8c53f30b (patch) | |
tree | e1bf729c78f160c54b9afdb87e999f4f97d5fdcd | |
parent | 6f495f2898a418f87e2a919e04fe23521bb0b9e9 (diff) |
Setup AbstractMethodError and dlsym stub when loading from oat
Change-Id: Ie97fa6eb3cfb7d0c6224aa6914f28a7b137ae056
-rw-r--r-- | build/Android.oattest.mk | 6 | ||||
-rw-r--r-- | src/class_linker.cc | 50 | ||||
-rw-r--r-- | src/jni_internal.cc | 1 | ||||
-rw-r--r-- | src/runtime_support.cc | 2 | ||||
-rw-r--r-- | src/stack_walk.cc | 2 | ||||
-rw-r--r-- | test/StackWalk2/StackWalk2.java | 2 |
6 files changed, 39 insertions, 24 deletions
diff --git a/build/Android.oattest.mk b/build/Android.oattest.mk index 6dfbf99bae..8e23112f40 100644 --- a/build/Android.oattest.mk +++ b/build/Android.oattest.mk @@ -77,10 +77,10 @@ $(eval $(call declare-test-test-target,IntMath,)) $(eval $(call declare-test-test-target,Invoke,)) $(eval $(call declare-test-test-target,ExceptionTest,)) $(eval $(call declare-test-test-target,SystemMethods,)) -# TODO: Re-enable the test when System.LoadLibrary is working. +$(eval $(call declare-test-test-target,MemUsage,)) + +# TODO: Enable when the StackWalk tests are passing # $(eval $(call declare-test-test-target,StackWalk,)) # $(eval $(call declare-test-test-target,StackWalk2,)) - $(eval $(call declare-test-test-target,MemUsage,)) - ######################################################################## diff --git a/src/class_linker.cc b/src/class_linker.cc index 3f30b9ef2d..f6cf291fcd 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -982,6 +982,23 @@ size_t ClassLinker::SizeOfClass(const DexFile& dex_file, return size; } +void LinkCode(Method* method, const OatFile::OatClass* oat_class, uint32_t method_index) { + // Every kind of method should at least get an invoke stub from the oat_method. + // non-abstract methods also get their code pointers. + const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index); + oat_method.LinkMethod(method); + + if (method->IsAbstract()) { + method->SetCode(Runtime::Current()->GetAbstractMethodErrorStubArray()->GetData()); + return; + } + if (method->IsNative()) { + // unregistering restores the dlsym lookup stub + method->UnregisterNative(); + return; + } +} + void ClassLinker::LoadClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, Class* klass, @@ -1060,6 +1077,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file, bool found = dex_file.FindClassDefIndex(descriptor, class_def_index); CHECK(found) << descriptor; oat_class.reset(oat_dex_file->GetOatClass(class_def_index)); + CHECK(oat_class.get() != NULL) << descriptor; } } } @@ -1073,12 +1091,11 @@ void ClassLinker::LoadClass(const DexFile& dex_file, for (size_t i = 0; i < num_direct_methods; ++i, ++method_index) { DexFile::Method dex_method; dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); - Method* meth = AllocMethod(); - klass->SetDirectMethod(i, meth); - LoadMethod(dex_file, dex_method, klass, meth); + Method* method = AllocMethod(); + klass->SetDirectMethod(i, method); + LoadMethod(dex_file, dex_method, klass, method); if (oat_class.get() != NULL) { - const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index); - oat_method.LinkMethod(meth); + LinkCode(method, oat_class.get(), method_index); } } } @@ -1091,12 +1108,11 @@ void ClassLinker::LoadClass(const DexFile& dex_file, for (size_t i = 0; i < num_virtual_methods; ++i, ++method_index) { DexFile::Method dex_method; dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); - Method* meth = AllocMethod(); - klass->SetVirtualMethod(i, meth); - LoadMethod(dex_file, dex_method, klass, meth); + Method* method = AllocMethod(); + klass->SetVirtualMethod(i, method); + LoadMethod(dex_file, dex_method, klass, method); if (oat_class.get() != NULL) { - const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index); - oat_method.LinkMethod(meth); + LinkCode(method, oat_class.get(), method_index); } } } @@ -2116,14 +2132,12 @@ bool ClassLinker::LinkInterfaceMethods(Class* klass) { int new_vtable_count = old_vtable_count + miranda_list.size(); vtable = vtable->CopyOf(new_vtable_count); for (size_t i = 0; i < miranda_list.size(); ++i) { - Method* meth = miranda_list[i]; //AllocMethod(); - // TODO: this shouldn't be a memcpy - //memcpy(meth, miranda_list[i], sizeof(Method)); - meth->SetDeclaringClass(klass); - meth->SetAccessFlags(meth->GetAccessFlags() | kAccMiranda); - meth->SetMethodIndex(0xFFFF & (old_vtable_count + i)); - klass->SetVirtualMethod(old_method_count + i, meth); - vtable->Set(old_vtable_count + i, meth); + Method* method = miranda_list[i]; + method->SetDeclaringClass(klass); + method->SetAccessFlags(method->GetAccessFlags() | kAccMiranda); + method->SetMethodIndex(0xFFFF & (old_vtable_count + i)); + klass->SetVirtualMethod(old_method_count + i, method); + vtable->Set(old_vtable_count + i, method); } // TODO: do not assign to the vtable field until it is fully constructed. klass->SetVTable(vtable); diff --git a/src/jni_internal.cc b/src/jni_internal.cc index 277284a929..21b5918c11 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -576,6 +576,7 @@ class Libraries { } detail += "No implementation found for "; detail += PrettyMethod(m); + detail += " (tried " + jni_short_name + " and " + jni_long_name + ")"; LOG(ERROR) << detail; return NULL; } diff --git a/src/runtime_support.cc b/src/runtime_support.cc index 6ebe36e1c2..65b89a31ad 100644 --- a/src/runtime_support.cc +++ b/src/runtime_support.cc @@ -39,6 +39,8 @@ extern void DebugMe(Method* method, uint32_t info) { // Return value helper for jobject return types extern Object* DecodeJObjectInThread(Thread* thread, jobject obj) { if (thread->IsExceptionPending()) { + // clear any result if an exception is pending to avoid making a + // local reference out of garbage. return NULL; } return thread->DecodeJObject(obj); diff --git a/src/stack_walk.cc b/src/stack_walk.cc index b2feee3cd6..25b2270645 100644 --- a/src/stack_walk.cc +++ b/src/stack_walk.cc @@ -100,7 +100,7 @@ JNIEXPORT jint JNICALL Java_StackWalk_refmap(JNIEnv* env, jobject thisObj, jint } extern "C" -JNIEXPORT jint JNICALL Java_StackWalk_refmap2(JNIEnv* env, jobject thisObj, jint count) { +JNIEXPORT jint JNICALL Java_StackWalk2_refmap2(JNIEnv* env, jobject thisObj, jint count) { gJava_StackWalk_refmap_calls++; // Visitor diff --git a/test/StackWalk2/StackWalk2.java b/test/StackWalk2/StackWalk2.java index 7d8c17723e..b4ea2d79e7 100644 --- a/test/StackWalk2/StackWalk2.java +++ b/test/StackWalk2/StackWalk2.java @@ -1,7 +1,5 @@ // Copyright 2011 Google Inc. All Rights Reserved. -package com.example.StackWalk2; - public class StackWalk2 { // use v1 for this |