diff options
author | Andreas Gampe <agampe@google.com> | 2015-04-10 19:57:29 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-04-10 20:42:14 -0700 |
commit | 48ee356484225ef0d7cfa197b1699524b866c802 (patch) | |
tree | ea33754d124d5e15b02e1a7c09c81d27fd625ba3 /runtime/entrypoints/quick | |
parent | 58565098b2298041ccc97371a3cc486df88d51b3 (diff) | |
download | android_art-48ee356484225ef0d7cfa197b1699524b866c802.tar.gz android_art-48ee356484225ef0d7cfa197b1699524b866c802.tar.bz2 android_art-48ee356484225ef0d7cfa197b1699524b866c802.zip |
ART: Ignore result for exception-case JNIEndWithReference
The value may not contain a valid jobject, so ignore and use null
directly.
Refactor a bit to have one common function for both synchronized
and non-synchronized case.
Add a test to the JNI compiler tests.
Bug: 18135031
Change-Id: If2f004a112f36f4ff68172a946dec67ce561ae4d
Diffstat (limited to 'runtime/entrypoints/quick')
-rw-r--r-- | runtime/entrypoints/quick/quick_jni_entrypoints.cc | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/runtime/entrypoints/quick/quick_jni_entrypoints.cc b/runtime/entrypoints/quick/quick_jni_entrypoints.cc index c1276b5bf2..e478d2a840 100644 --- a/runtime/entrypoints/quick/quick_jni_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_jni_entrypoints.cc @@ -68,7 +68,6 @@ extern void JniMethodEnd(uint32_t saved_local_ref_cookie, Thread* self) { PopLocalReferences(saved_local_ref_cookie, self); } - extern void JniMethodEndSynchronized(uint32_t saved_local_ref_cookie, jobject locked, Thread* self) { GoToRunnable(self); @@ -76,38 +75,34 @@ extern void JniMethodEndSynchronized(uint32_t saved_local_ref_cookie, jobject lo PopLocalReferences(saved_local_ref_cookie, self); } -extern mirror::Object* JniMethodEndWithReference(jobject result, uint32_t saved_local_ref_cookie, - Thread* self) { - GoToRunnable(self); - mirror::Object* o = self->DecodeJObject(result); // Must decode before pop. +// Common result handling for EndWithReference. +static mirror::Object* JniMethodEndWithReferenceHandleResult(jobject result, + uint32_t saved_local_ref_cookie, + Thread* self) + NO_THREAD_SAFETY_ANALYSIS { + // Must decode before pop. The 'result' may not be valid in case of an exception, though. + mirror::Object* o = self->IsExceptionPending() ? nullptr : self->DecodeJObject(result); PopLocalReferences(saved_local_ref_cookie, self); // Process result. if (UNLIKELY(self->GetJniEnv()->check_jni)) { - if (self->IsExceptionPending()) { - return NULL; - } CheckReferenceResult(o, self); } VerifyObject(o); return o; } +extern mirror::Object* JniMethodEndWithReference(jobject result, uint32_t saved_local_ref_cookie, + Thread* self) { + GoToRunnable(self); + return JniMethodEndWithReferenceHandleResult(result, saved_local_ref_cookie, self); +} + extern mirror::Object* JniMethodEndWithReferenceSynchronized(jobject result, uint32_t saved_local_ref_cookie, jobject locked, Thread* self) { GoToRunnable(self); - UnlockJniSynchronizedMethod(locked, self); // Must decode before pop. - mirror::Object* o = self->DecodeJObject(result); - PopLocalReferences(saved_local_ref_cookie, self); - // Process result. - if (UNLIKELY(self->GetJniEnv()->check_jni)) { - if (self->IsExceptionPending()) { - return NULL; - } - CheckReferenceResult(o, self); - } - VerifyObject(o); - return o; + UnlockJniSynchronizedMethod(locked, self); + return JniMethodEndWithReferenceHandleResult(result, saved_local_ref_cookie, self); } } // namespace art |