Fix JNI compiler for portable path.
Change-Id: Ic2cbfcf126137b1b72f3b51e7af5a9be87987737
diff --git a/src/runtime_support.h b/src/runtime_support.h
index bba9161..2ea7f99 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -235,6 +235,49 @@
return class_linker->ResolveString(string_idx, referrer);
}
+static inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_)
+ UNLOCK_FUNCTION(monitor_lock_) {
+ // Save any pending exception over monitor exit call.
+ Throwable* saved_exception = NULL;
+ if (UNLIKELY(self->IsExceptionPending())) {
+ saved_exception = self->GetException();
+ self->ClearException();
+ }
+ // Decode locked object and unlock, before popping local references.
+ self->DecodeJObject(locked)->MonitorExit(self);
+ if (UNLIKELY(self->IsExceptionPending())) {
+ LOG(FATAL) << "Synchronized JNI code returning with an exception:\n"
+ << saved_exception->Dump()
+ << "\nEncountered second exception during implicit MonitorExit:\n"
+ << self->GetException()->Dump();
+ }
+ // Restore pending exception.
+ if (saved_exception != NULL) {
+ self->SetException(saved_exception);
+ }
+}
+
+static inline void CheckReferenceResult(Object* o, Thread* self)
+ SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_) {
+ if (o == NULL) {
+ return;
+ }
+ if (o == kInvalidIndirectRefObject) {
+ JniAbortF(NULL, "invalid reference returned from %s",
+ PrettyMethod(self->GetCurrentMethod()).c_str());
+ }
+ // Make sure that the result is an instance of the type this method was expected to return.
+ Method* m = self->GetCurrentMethod();
+ MethodHelper mh(m);
+ Class* return_type = mh.GetReturnType();
+
+ if (!o->InstanceOf(return_type)) {
+ JniAbortF(NULL, "attempt to return an instance of %s from %s",
+ PrettyTypeOf(o).c_str(), PrettyMethod(m).c_str());
+ }
+}
+
} // namespace art
#endif // ART_SRC_RUNTIME_SUPPORT_H_