Setup AbstractMethodError and dlsym stub when loading from oat
Change-Id: Ie97fa6eb3cfb7d0c6224aa6914f28a7b137ae056
diff --git a/build/Android.oattest.mk b/build/Android.oattest.mk
index 6dfbf99..8e23112 100644
--- a/build/Android.oattest.mk
+++ b/build/Android.oattest.mk
@@ -77,10 +77,10 @@
$(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 3f30b9e..f6cf291 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -982,6 +982,23 @@
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 @@
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 @@
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 @@
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 @@
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 277284a..21b5918 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -576,6 +576,7 @@
}
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 6ebe36e..65b89a3 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -39,6 +39,8 @@
// 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 b2feee3..25b2270 100644
--- a/src/stack_walk.cc
+++ b/src/stack_walk.cc
@@ -100,7 +100,7 @@
}
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 7d8c177..b4ea2d7 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