--- a/hotspot/src/share/vm/prims/jniCheck.cpp Wed Jun 11 09:58:23 2014 -0400
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp Wed Jun 11 18:34:09 2014 +0200
@@ -53,6 +53,8 @@
# include "jniTypes_ppc.hpp"
#endif
+// Complain every extra number of unplanned local refs
+#define CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD 32
// Heap objects are allowed to be directly referenced only in VM code,
// not in native code.
@@ -168,12 +170,42 @@
* SUPPORT FUNCTIONS
*/
+/**
+ * Check whether or not a programmer has actually checked for exceptions. According
+ * to the JNI Specification ("jni/spec/design.html#java_exceptions"):
+ *
+ * There are two cases where the programmer needs to check for exceptions without
+ * being able to first check an error code:
+ *
+ * - The JNI functions that invoke a Java method return the result of the Java method.
+ * The programmer must call ExceptionOccurred() to check for possible exceptions
+ * that occurred during the execution of the Java method.
+ *
+ * - Some of the JNI array access functions do not return an error code, but may
+ * throw an ArrayIndexOutOfBoundsException or ArrayStoreException.
+ *
+ * In all other cases, a non-error return value guarantees that no exceptions have been thrown.
+ */
+static inline void
+check_pending_exception(JavaThread* thr) {
+ if (thr->has_pending_exception()) {
+ NativeReportJNIWarning(thr, "JNI call made with exception pending");
+ }
+ if (thr->is_pending_jni_exception_check()) {
+ IN_VM(
+ tty->print_cr("WARNING in native method: JNI call made without checking exceptions when required to from %s",
+ thr->get_pending_jni_exception_check());
+ thr->print_stack();
+ )
+ thr->clear_pending_jni_exception_check(); // Just complain once
+ }
+}
+
+
static inline void
functionEnterCritical(JavaThread* thr)
{
- if (thr->has_pending_exception()) {
- NativeReportJNIWarning(thr, "JNI call made with exception pending");
- }
+ check_pending_exception(thr);
}
static inline void
@@ -187,9 +219,7 @@
if (thr->in_critical()) {
tty->print_cr("%s", warn_other_function_in_critical);
}
- if (thr->has_pending_exception()) {
- NativeReportJNIWarning(thr, "JNI call made with exception pending");
- }
+ check_pending_exception(thr);
}
static inline void
@@ -201,9 +231,20 @@
}
static inline void
-functionExit(JNIEnv *env)
+functionExit(JavaThread* thr)
{
- /* nothing to do at this time */
+ JNIHandleBlock* handles = thr->active_handles();
+ size_t planned_capacity = handles->get_planned_capacity();
+ size_t live_handles = handles->get_number_of_live_handles();
+ if (live_handles > planned_capacity) {
+ IN_VM(
+ tty->print_cr("WARNING: JNI local refs: %zu, exceeds capacity: %zu",
+ live_handles, planned_capacity);
+ thr->print_stack();
+ )
+ // Complain just the once, reset to current + warn threshold
+ handles->set_planned_capacity(live_handles + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ }
}
static inline void
@@ -508,7 +549,7 @@
jniCheck::validate_object(thr, loader);
)
jclass result = UNCHECKED()->DefineClass(env, name, loader, buf, len);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -520,7 +561,7 @@
jniCheck::validate_class_descriptor(thr, name);
)
jclass result = UNCHECKED()->FindClass(env, name);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -532,7 +573,7 @@
jniCheck::validate_object(thr, method);
)
jmethodID result = UNCHECKED()->FromReflectedMethod(env, method);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -544,7 +585,7 @@
jniCheck::validate_object(thr, field);
)
jfieldID result = UNCHECKED()->FromReflectedField(env, field);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -560,7 +601,7 @@
)
jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID,
isStatic);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -572,7 +613,7 @@
jniCheck::validate_class(thr, sub, true);
)
jclass result = UNCHECKED()->GetSuperclass(env, sub);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -586,7 +627,7 @@
jniCheck::validate_class(thr, sup, true);
)
jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -601,7 +642,7 @@
)
jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID,
isStatic);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -619,7 +660,7 @@
}
)
jint result = UNCHECKED()->Throw(env, obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -634,15 +675,16 @@
jniCheck::validate_throwable_klass(thr, k);
)
jint result = UNCHECKED()->ThrowNew(env, clazz, msg);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
JNI_ENTRY_CHECKED(jthrowable,
checked_jni_ExceptionOccurred(JNIEnv *env))
+ thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr);
jthrowable result = UNCHECKED()->ExceptionOccurred(env);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -650,22 +692,24 @@
checked_jni_ExceptionDescribe(JNIEnv *env))
functionEnterExceptionAllowed(thr);
UNCHECKED()->ExceptionDescribe(env);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
checked_jni_ExceptionClear(JNIEnv *env))
+ thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr);
UNCHECKED()->ExceptionClear(env);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
checked_jni_FatalError(JNIEnv *env,
const char *msg))
+ thr->clear_pending_jni_exception_check();
functionEnter(thr);
UNCHECKED()->FatalError(env, msg);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jint,
@@ -675,7 +719,10 @@
if (capacity < 0)
NativeReportJNIFatalError(thr, "negative capacity");
jint result = UNCHECKED()->PushLocalFrame(env, capacity);
- functionExit(env);
+ if (result == JNI_OK) {
+ thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ }
+ functionExit(thr);
return result;
JNI_END
@@ -684,7 +731,7 @@
jobject result))
functionEnterExceptionAllowed(thr);
jobject res = UNCHECKED()->PopLocalFrame(env, result);
- functionExit(env);
+ functionExit(thr);
return res;
JNI_END
@@ -698,7 +745,7 @@
}
)
jobject result = UNCHECKED()->NewGlobalRef(env,lobj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -714,7 +761,7 @@
}
)
UNCHECKED()->DeleteGlobalRef(env,gref);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -729,7 +776,7 @@
"Invalid local JNI handle passed to DeleteLocalRef");
)
UNCHECKED()->DeleteLocalRef(env, obj);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jboolean,
@@ -750,7 +797,7 @@
}
)
jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -764,7 +811,7 @@
}
)
jobject result = UNCHECKED()->NewLocalRef(env, ref);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -776,7 +823,10 @@
NativeReportJNIFatalError(thr, "negative capacity");
}
jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity);
- functionExit(env);
+ if (result == JNI_OK) {
+ thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ }
+ functionExit(thr);
return result;
JNI_END
@@ -788,7 +838,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jobject result = UNCHECKED()->AllocObject(env,clazz);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -806,7 +856,7 @@
va_start(args, methodID);
jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
va_end(args);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -821,7 +871,7 @@
jniCheck::validate_jmethod_id(thr, methodID);
)
jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -836,7 +886,7 @@
jniCheck::validate_jmethod_id(thr, methodID);
)
jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -848,7 +898,7 @@
jniCheck::validate_object(thr, obj);
)
jclass result = UNCHECKED()->GetObjectClass(env,obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -862,7 +912,7 @@
jniCheck::validate_class(thr, clazz, true);
)
jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -876,7 +926,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jmethodID result = UNCHECKED()->GetMethodID(env,clazz,name,sig);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -895,7 +945,8 @@
ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \
args); \
va_end(args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Call"#Result"Method"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -910,7 +961,8 @@
) \
ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Call"#Result"MethodV"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -925,7 +977,8 @@
) \
ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Call"#Result"MethodA"); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -952,7 +1005,8 @@
va_start(args,methodID);
UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
va_end(args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallVoidMethod");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -965,7 +1019,8 @@
jniCheck::validate_call_object(thr, obj, methodID);
)
UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallVoidMethodV");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -978,7 +1033,8 @@
jniCheck::validate_call_object(thr, obj, methodID);
)
UNCHECKED()->CallVoidMethodA(env,obj,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallVoidMethodA");
+ functionExit(thr);
JNI_END
#define WRAPPER_CallNonvirtualMethod(ResultType, Result) \
@@ -1001,7 +1057,8 @@
methodID,\
args); \
va_end(args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"Method"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -1021,7 +1078,8 @@
clazz, \
methodID,\
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodV"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -1041,7 +1099,8 @@
clazz, \
methodID,\
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodA"); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1070,7 +1129,8 @@
va_start(args,methodID);
UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
va_end(args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallNonvirtualVoidMethod");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1085,7 +1145,8 @@
jniCheck::validate_call_class(thr, clazz, methodID);
)
UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1100,7 +1161,8 @@
jniCheck::validate_call_class(thr, clazz, methodID);
)
UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jfieldID,
@@ -1113,7 +1175,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jfieldID result = UNCHECKED()->GetFieldID(env,clazz,name,sig);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1127,7 +1189,7 @@
checkInstanceFieldID(thr, fieldID, obj, FieldType); \
) \
ReturnType result = UNCHECKED()->Get##Result##Field(env,obj,fieldID); \
- functionExit(env); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1152,7 +1214,7 @@
checkInstanceFieldID(thr, fieldID, obj, FieldType); \
) \
UNCHECKED()->Set##Result##Field(env,obj,fieldID,val); \
- functionExit(env); \
+ functionExit(thr); \
JNI_END
WRAPPER_SetField(jobject, Object, T_OBJECT)
@@ -1176,7 +1238,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jmethodID result = UNCHECKED()->GetStaticMethodID(env,clazz,name,sig);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1198,7 +1260,8 @@
methodID, \
args); \
va_end(args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallStatic"#Result"Method"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -1216,7 +1279,8 @@
clazz, \
methodID, \
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallStatic"#Result"MethodV"); \
+ functionExit(thr); \
return result; \
JNI_END \
\
@@ -1234,7 +1298,8 @@
clazz, \
methodID, \
args); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("CallStatic"#Result"MethodA"); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1262,7 +1327,8 @@
va_start(args,methodID);
UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
va_end(args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallStaticVoidMethod");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1276,7 +1342,8 @@
jniCheck::validate_class(thr, cls, false);
)
UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallStaticVoidMethodV");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1290,7 +1357,8 @@
jniCheck::validate_class(thr, cls, false);
)
UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args);
- functionExit(env);
+ thr->set_pending_jni_exception_check("CallStaticVoidMethodA");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jfieldID,
@@ -1303,7 +1371,7 @@
jniCheck::validate_class(thr, clazz, false);
)
jfieldID result = UNCHECKED()->GetStaticFieldID(env,clazz,name,sig);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1320,7 +1388,7 @@
ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \
clazz, \
fieldID); \
- functionExit(env); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1346,7 +1414,7 @@
checkStaticFieldID(thr, fieldID, clazz, FieldType); \
) \
UNCHECKED()->SetStatic##Result##Field(env,clazz,fieldID,value); \
- functionExit(env); \
+ functionExit(thr); \
JNI_END
WRAPPER_SetStaticField(jobject, Object, T_OBJECT)
@@ -1366,7 +1434,7 @@
jsize len))
functionEnter(thr);
jstring result = UNCHECKED()->NewString(env,unicode,len);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1378,7 +1446,7 @@
checkString(thr, str);
)
jsize result = UNCHECKED()->GetStringLength(env,str);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1407,7 +1475,7 @@
// Note that the dtrace arguments for the allocated memory will not match up with this solution.
FreeHeap((char*)result);
}
- functionExit(env);
+ functionExit(thr);
return new_result;
JNI_END
@@ -1442,7 +1510,7 @@
UNCHECKED()->ReleaseStringChars(env, str,
(const jchar*) guarded.release_for_freeing());
}
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jstring,
@@ -1450,7 +1518,7 @@
const char *utf))
functionEnter(thr);
jstring result = UNCHECKED()->NewStringUTF(env,utf);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1462,7 +1530,7 @@
checkString(thr, str);
)
jsize result = UNCHECKED()->GetStringUTFLength(env,str);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1490,7 +1558,7 @@
// Note that the dtrace arguments for the allocated memory will not match up with this solution.
FreeHeap((char*)result, mtInternal);
}
- functionExit(env);
+ functionExit(thr);
return new_result;
JNI_END
@@ -1525,7 +1593,7 @@
UNCHECKED()->ReleaseStringUTFChars(env, str,
(const char*) guarded.release_for_freeing());
}
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jsize,
@@ -1536,7 +1604,7 @@
check_is_array(thr, array);
)
jsize result = UNCHECKED()->GetArrayLength(env,array);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1547,7 +1615,7 @@
jobject init))
functionEnter(thr);
jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1560,7 +1628,8 @@
check_is_obj_array(thr, array);
)
jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
- functionExit(env);
+ thr->set_pending_jni_exception_check("GetObjectArrayElement");
+ functionExit(thr);
return result;
JNI_END
@@ -1574,7 +1643,8 @@
check_is_obj_array(thr, array);
)
UNCHECKED()->SetObjectArrayElement(env,array,index,val);
- functionExit(env);
+ thr->set_pending_jni_exception_check("SetObjectArrayElement");
+ functionExit(thr);
JNI_END
#define WRAPPER_NewScalarArray(Return, Result) \
@@ -1583,7 +1653,7 @@
jsize len)) \
functionEnter(thr); \
Return result = UNCHECKED()->New##Result##Array(env,len); \
- functionExit(env); \
+ functionExit(thr); \
return (Return) result; \
JNI_END
@@ -1611,7 +1681,7 @@
if (result != NULL) { \
result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \
} \
- functionExit(env); \
+ functionExit(thr); \
return result; \
JNI_END
@@ -1639,7 +1709,7 @@
ElementType* orig_result = (ElementType *) check_wrapped_array_release( \
thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode); \
UNCHECKED()->Release##Result##ArrayElements(env, array, orig_result, mode); \
- functionExit(env); \
+ functionExit(thr); \
JNI_END
WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool)
@@ -1663,7 +1733,8 @@
check_primitive_array_type(thr, array, ElementTag); \
) \
UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Get"#Result"ArrayRegion"); \
+ functionExit(thr); \
JNI_END
WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
@@ -1687,7 +1758,8 @@
check_primitive_array_type(thr, array, ElementTag); \
) \
UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \
- functionExit(env); \
+ thr->set_pending_jni_exception_check("Set"#Result"ArrayRegion"); \
+ functionExit(thr); \
JNI_END
WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
@@ -1706,7 +1778,7 @@
jint nMethods))
functionEnter(thr);
jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1715,7 +1787,7 @@
jclass clazz))
functionEnter(thr);
jint result = UNCHECKED()->UnregisterNatives(env,clazz);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1727,7 +1799,7 @@
jniCheck::validate_object(thr, obj);
)
jint result = UNCHECKED()->MonitorEnter(env,obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1739,7 +1811,7 @@
jniCheck::validate_object(thr, obj);
)
jint result = UNCHECKED()->MonitorExit(env,obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1748,7 +1820,7 @@
JavaVM **vm))
functionEnter(thr);
jint result = UNCHECKED()->GetJavaVM(env,vm);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1763,7 +1835,8 @@
checkString(thr, str);
)
UNCHECKED()->GetStringRegion(env, str, start, len, buf);
- functionExit(env);
+ thr->set_pending_jni_exception_check("GetStringRegion");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void,
@@ -1777,7 +1850,8 @@
checkString(thr, str);
)
UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
- functionExit(env);
+ thr->set_pending_jni_exception_check("GetStringUTFRegion");
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(void *,
@@ -1792,7 +1866,7 @@
if (result != NULL) {
result = check_jni_wrap_copy_array(thr, array, result);
}
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1808,7 +1882,7 @@
// Check the element array...
void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical", array, carray, mode);
UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(const jchar*,
@@ -1820,7 +1894,7 @@
checkString(thr, string);
)
const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1836,7 +1910,7 @@
* string parameter as a minor sanity check
*/
UNCHECKED()->ReleaseStringCritical(env, str, chars);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jweak,
@@ -1849,7 +1923,7 @@
}
)
jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1858,14 +1932,15 @@
jweak ref))
functionEnterExceptionAllowed(thr);
UNCHECKED()->DeleteWeakGlobalRef(env, ref);
- functionExit(env);
+ functionExit(thr);
JNI_END
JNI_ENTRY_CHECKED(jboolean,
checked_jni_ExceptionCheck(JNIEnv *env))
+ thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr);
jboolean result = UNCHECKED()->ExceptionCheck(env);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1875,7 +1950,7 @@
jlong capacity))
functionEnter(thr);
jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1884,7 +1959,7 @@
jobject buf))
functionEnter(thr);
void* result = UNCHECKED()->GetDirectBufferAddress(env, buf);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1893,7 +1968,7 @@
jobject buf))
functionEnter(thr);
jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1906,7 +1981,7 @@
jniCheck::validate_object(thr, obj);
)
jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END
@@ -1915,7 +1990,7 @@
checked_jni_GetVersion(JNIEnv *env))
functionEnter(thr);
jint result = UNCHECKED()->GetVersion(env);
- functionExit(env);
+ functionExit(thr);
return result;
JNI_END