diff options
author | Andreas Gampe <agampe@google.com> | 2014-04-04 16:20:13 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-04-04 16:28:13 -0700 |
commit | ad61517890168ff6ed19063cc8032a9c033d135b (patch) | |
tree | 7bc9f0fa28eaedef854527c85cb15ff3d0afea8f /runtime/entrypoints/quick | |
parent | e8b4bbcef44f7fe76896850b2f5750cd46b1ade0 (diff) | |
download | art-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.cc | 57 |
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. |