summaryrefslogtreecommitdiffstats
path: root/runtime/entrypoints/quick
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-04-04 16:20:13 -0700
committerAndreas Gampe <agampe@google.com>2014-04-04 16:28:13 -0700
commitad61517890168ff6ed19063cc8032a9c033d135b (patch)
tree7bc9f0fa28eaedef854527c85cb15ff3d0afea8f /runtime/entrypoints/quick
parente8b4bbcef44f7fe76896850b2f5750cd46b1ade0 (diff)
downloadart-ad61517890168ff6ed19063cc8032a9c033d135b.zip
art-ad61517890168ff6ed19063cc8032a9c033d135b.tar.gz
art-ad61517890168ff6ed19063cc8032a9c033d135b.tar.bz2
Fix wrong handling of Generic JNI not finding native method.
Code did not properly call JNIMethodEnd, such that locks etc where not correctly handled. Add a test case to jni_compiler_test. Change-Id: If2d5c628517d65a56dd6bb5c4cabdff77c7664a1
Diffstat (limited to 'runtime/entrypoints/quick')
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc57
1 files changed, 35 insertions, 22 deletions
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 963c3d1..fcbcac2 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1496,6 +1496,22 @@ void BuildGenericJniFrameVisitor::FinalizeSirt(Thread* self) {
extern "C" void* artFindNativeMethod();
+uint64_t artQuickGenericJniEndJNIRef(Thread* self, uint32_t cookie, jobject l, jobject lock) {
+ if (lock != nullptr) {
+ return reinterpret_cast<uint64_t>(JniMethodEndWithReferenceSynchronized(l, cookie, lock, self));
+ } else {
+ return reinterpret_cast<uint64_t>(JniMethodEndWithReference(l, cookie, self));
+ }
+}
+
+void artQuickGenericJniEndJNINonRef(Thread* self, uint32_t cookie, jobject lock) {
+ if (lock != nullptr) {
+ JniMethodEndSynchronized(cookie, lock, self);
+ } else {
+ JniMethodEnd(cookie, self);
+ }
+}
+
/*
* Initializes an alloca region assumed to be directly below sp for a native call:
* Create a Sirt and call stack and fill a mini stack with values to be pushed to registers.
@@ -1555,6 +1571,15 @@ extern "C" ssize_t artQuickGenericJniTrampoline(Thread* self, mirror::ArtMethod*
if (nativeCode == nullptr) {
DCHECK(self->IsExceptionPending()); // There should be an exception pending now.
+
+ // End JNI, as the assembly will move to deliver the exception.
+ jobject lock = called->IsSynchronized() ? visitor.GetFirstSirtEntry() : nullptr;
+ if (mh.GetShorty()[0] == 'L') {
+ artQuickGenericJniEndJNIRef(self, cookie, nullptr, lock);
+ } else {
+ artQuickGenericJniEndJNINonRef(self, cookie, lock);
+ }
+
return -1;
}
// Note that the native code pointer will be automatically set by artFindNativeMethod().
@@ -1580,33 +1605,21 @@ extern "C" uint64_t artQuickGenericJniEndTrampoline(Thread* self, mirror::ArtMet
mirror::ArtMethod* called = *sp;
uint32_t cookie = *(sp32 - 1);
+ jobject lock = nullptr;
+ if (called->IsSynchronized()) {
+ StackIndirectReferenceTable* table =
+ reinterpret_cast<StackIndirectReferenceTable*>(
+ reinterpret_cast<uint8_t*>(sp) + kPointerSize);
+ lock = reinterpret_cast<jobject>(table->GetStackReference(0));
+ }
+
MethodHelper mh(called);
char return_shorty_char = mh.GetShorty()[0];
if (return_shorty_char == 'L') {
- // the only special ending call
- if (called->IsSynchronized()) {
- StackIndirectReferenceTable* table =
- reinterpret_cast<StackIndirectReferenceTable*>(
- reinterpret_cast<uint8_t*>(sp) + kPointerSize);
- jobject tmp = reinterpret_cast<jobject>(table->GetStackReference(0));
-
- return reinterpret_cast<uint64_t>(JniMethodEndWithReferenceSynchronized(result.l, cookie, tmp,
- self));
- } else {
- return reinterpret_cast<uint64_t>(JniMethodEndWithReference(result.l, cookie, self));
- }
+ return artQuickGenericJniEndJNIRef(self, cookie, result.l, lock);
} else {
- if (called->IsSynchronized()) {
- StackIndirectReferenceTable* table =
- reinterpret_cast<StackIndirectReferenceTable*>(
- reinterpret_cast<uint8_t*>(sp) + kPointerSize);
- jobject tmp = reinterpret_cast<jobject>(table->GetStackReference(0));
-
- JniMethodEndSynchronized(cookie, tmp, self);
- } else {
- JniMethodEnd(cookie, self);
- }
+ artQuickGenericJniEndJNINonRef(self, cookie, lock);
switch (return_shorty_char) {
case 'F': // Fall-through.