Mercurial > hg > graal-jvmci-8
diff src/share/vm/prims/jniCheck.cpp @ 23286:dd9cc155639c
Merge with jdk8u66-b17
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Thu, 07 Jan 2016 17:28:46 +0100 |
parents | 7848fc12602b 9904bb920313 |
children | 9b69cec6d01b |
line wrap: on
line diff
--- a/src/share/vm/prims/jniCheck.cpp Fri Jan 22 12:48:57 2016 -1000 +++ b/src/share/vm/prims/jniCheck.cpp Thu Jan 07 17:28:46 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -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,55 @@ * 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. + * + * Programmers often defend against ArrayIndexOutOfBoundsException, so warning + * for these functions would be pedantic. + */ +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 + } +} + +/** + * Add to the planned number of handles. I.e. plus current live & warning threshold + */ +static inline void +add_planned_handle_capacity(JNIHandleBlock* handles, size_t capacity) { + handles->set_planned_capacity(capacity + + handles->get_number_of_live_handles() + + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD); +} + + 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 +232,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 +244,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 + add_planned_handle_capacity(handles, 0); + } } static inline void @@ -508,7 +562,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 +574,7 @@ jniCheck::validate_class_descriptor(thr, name); ) jclass result = UNCHECKED()->FindClass(env, name); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -532,7 +586,7 @@ jniCheck::validate_object(thr, method); ) jmethodID result = UNCHECKED()->FromReflectedMethod(env, method); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -544,7 +598,7 @@ jniCheck::validate_object(thr, field); ) jfieldID result = UNCHECKED()->FromReflectedField(env, field); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -560,7 +614,7 @@ ) jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID, isStatic); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -572,7 +626,7 @@ jniCheck::validate_class(thr, sub, true); ) jclass result = UNCHECKED()->GetSuperclass(env, sub); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -586,7 +640,7 @@ jniCheck::validate_class(thr, sup, true); ) jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -601,7 +655,7 @@ ) jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID, isStatic); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -619,7 +673,7 @@ } ) jint result = UNCHECKED()->Throw(env, obj); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -634,15 +688,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 +705,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 +732,10 @@ if (capacity < 0) NativeReportJNIFatalError(thr, "negative capacity"); jint result = UNCHECKED()->PushLocalFrame(env, capacity); - functionExit(env); + if (result == JNI_OK) { + add_planned_handle_capacity(thr->active_handles(), capacity); + } + functionExit(thr); return result; JNI_END @@ -684,7 +744,7 @@ jobject result)) functionEnterExceptionAllowed(thr); jobject res = UNCHECKED()->PopLocalFrame(env, result); - functionExit(env); + functionExit(thr); return res; JNI_END @@ -698,7 +758,7 @@ } ) jobject result = UNCHECKED()->NewGlobalRef(env,lobj); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -714,7 +774,7 @@ } ) UNCHECKED()->DeleteGlobalRef(env,gref); - functionExit(env); + functionExit(thr); JNI_END JNI_ENTRY_CHECKED(void, @@ -729,7 +789,7 @@ "Invalid local JNI handle passed to DeleteLocalRef"); ) UNCHECKED()->DeleteLocalRef(env, obj); - functionExit(env); + functionExit(thr); JNI_END JNI_ENTRY_CHECKED(jboolean, @@ -750,7 +810,7 @@ } ) jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -764,7 +824,7 @@ } ) jobject result = UNCHECKED()->NewLocalRef(env, ref); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -776,7 +836,10 @@ NativeReportJNIFatalError(thr, "negative capacity"); } jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity); - functionExit(env); + if (result == JNI_OK) { + add_planned_handle_capacity(thr->active_handles(), capacity); + } + functionExit(thr); return result; JNI_END @@ -788,7 +851,7 @@ jniCheck::validate_class(thr, clazz, false); ) jobject result = UNCHECKED()->AllocObject(env,clazz); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -806,7 +869,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 +884,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 +899,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 +911,7 @@ jniCheck::validate_object(thr, obj); ) jclass result = UNCHECKED()->GetObjectClass(env,obj); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -862,7 +925,7 @@ jniCheck::validate_class(thr, clazz, true); ) jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -876,7 +939,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 +958,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 +974,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 +990,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 +1018,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 +1032,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 +1046,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 +1070,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 +1091,8 @@ clazz, \ methodID,\ args); \ - functionExit(env); \ + thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodV"); \ + functionExit(thr); \ return result; \ JNI_END \ \ @@ -1041,7 +1112,8 @@ clazz, \ methodID,\ args); \ - functionExit(env); \ + thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodA"); \ + functionExit(thr); \ return result; \ JNI_END @@ -1070,7 +1142,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 +1158,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 +1174,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 +1188,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 +1202,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 +1227,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 +1251,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 +1273,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 +1292,8 @@ clazz, \ methodID, \ args); \ - functionExit(env); \ + thr->set_pending_jni_exception_check("CallStatic"#Result"MethodV"); \ + functionExit(thr); \ return result; \ JNI_END \ \ @@ -1234,7 +1311,8 @@ clazz, \ methodID, \ args); \ - functionExit(env); \ + thr->set_pending_jni_exception_check("CallStatic"#Result"MethodA"); \ + functionExit(thr); \ return result; \ JNI_END @@ -1262,7 +1340,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 +1355,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 +1370,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 +1384,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 +1401,7 @@ ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \ clazz, \ fieldID); \ - functionExit(env); \ + functionExit(thr); \ return result; \ JNI_END @@ -1346,7 +1427,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 +1447,7 @@ jsize len)) functionEnter(thr); jstring result = UNCHECKED()->NewString(env,unicode,len); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1378,7 +1459,7 @@ checkString(thr, str); ) jsize result = UNCHECKED()->GetStringLength(env,str); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1407,7 +1488,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 +1523,7 @@ UNCHECKED()->ReleaseStringChars(env, str, (const jchar*) guarded.release_for_freeing()); } - functionExit(env); + functionExit(thr); JNI_END JNI_ENTRY_CHECKED(jstring, @@ -1450,7 +1531,7 @@ const char *utf)) functionEnter(thr); jstring result = UNCHECKED()->NewStringUTF(env,utf); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1462,7 +1543,7 @@ checkString(thr, str); ) jsize result = UNCHECKED()->GetStringUTFLength(env,str); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1490,7 +1571,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 +1606,7 @@ UNCHECKED()->ReleaseStringUTFChars(env, str, (const char*) guarded.release_for_freeing()); } - functionExit(env); + functionExit(thr); JNI_END JNI_ENTRY_CHECKED(jsize, @@ -1536,7 +1617,7 @@ check_is_array(thr, array); ) jsize result = UNCHECKED()->GetArrayLength(env,array); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1547,7 +1628,7 @@ jobject init)) functionEnter(thr); jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1560,7 +1641,7 @@ check_is_obj_array(thr, array); ) jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1574,7 +1655,7 @@ check_is_obj_array(thr, array); ) UNCHECKED()->SetObjectArrayElement(env,array,index,val); - functionExit(env); + functionExit(thr); JNI_END #define WRAPPER_NewScalarArray(Return, Result) \ @@ -1583,7 +1664,7 @@ jsize len)) \ functionEnter(thr); \ Return result = UNCHECKED()->New##Result##Array(env,len); \ - functionExit(env); \ + functionExit(thr); \ return (Return) result; \ JNI_END @@ -1611,7 +1692,7 @@ if (result != NULL) { \ result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \ } \ - functionExit(env); \ + functionExit(thr); \ return result; \ JNI_END @@ -1639,7 +1720,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 +1744,7 @@ check_primitive_array_type(thr, array, ElementTag); \ ) \ UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \ - functionExit(env); \ + functionExit(thr); \ JNI_END WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) @@ -1687,7 +1768,7 @@ check_primitive_array_type(thr, array, ElementTag); \ ) \ UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \ - functionExit(env); \ + functionExit(thr); \ JNI_END WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) @@ -1706,7 +1787,7 @@ jint nMethods)) functionEnter(thr); jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1715,7 +1796,7 @@ jclass clazz)) functionEnter(thr); jint result = UNCHECKED()->UnregisterNatives(env,clazz); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1727,7 +1808,7 @@ jniCheck::validate_object(thr, obj); ) jint result = UNCHECKED()->MonitorEnter(env,obj); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1739,7 +1820,7 @@ jniCheck::validate_object(thr, obj); ) jint result = UNCHECKED()->MonitorExit(env,obj); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1748,7 +1829,7 @@ JavaVM **vm)) functionEnter(thr); jint result = UNCHECKED()->GetJavaVM(env,vm); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1763,7 +1844,7 @@ checkString(thr, str); ) UNCHECKED()->GetStringRegion(env, str, start, len, buf); - functionExit(env); + functionExit(thr); JNI_END JNI_ENTRY_CHECKED(void, @@ -1777,7 +1858,7 @@ checkString(thr, str); ) UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf); - functionExit(env); + functionExit(thr); JNI_END JNI_ENTRY_CHECKED(void *, @@ -1792,7 +1873,7 @@ if (result != NULL) { result = check_jni_wrap_copy_array(thr, array, result); } - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1808,7 +1889,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 +1901,7 @@ checkString(thr, string); ) const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1836,7 +1917,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 +1930,7 @@ } ) jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1858,14 +1939,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 +1957,7 @@ jlong capacity)) functionEnter(thr); jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1884,7 +1966,7 @@ jobject buf)) functionEnter(thr); void* result = UNCHECKED()->GetDirectBufferAddress(env, buf); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1893,7 +1975,7 @@ jobject buf)) functionEnter(thr); jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1906,7 +1988,7 @@ jniCheck::validate_object(thr, obj); ) jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj); - functionExit(env); + functionExit(thr); return result; JNI_END @@ -1915,7 +1997,7 @@ checked_jni_GetVersion(JNIEnv *env)) functionEnter(thr); jint result = UNCHECKED()->GetVersion(env); - functionExit(env); + functionExit(thr); return result; JNI_END