1.1 --- a/src/share/vm/prims/jniCheck.cpp Mon Mar 02 13:40:40 2015 +0100 1.2 +++ b/src/share/vm/prims/jniCheck.cpp Wed Mar 11 13:36:57 2015 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -53,6 +53,8 @@ 1.11 # include "jniTypes_ppc.hpp" 1.12 #endif 1.13 1.14 +// Complain every extra number of unplanned local refs 1.15 +#define CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD 32 1.16 1.17 // Heap objects are allowed to be directly referenced only in VM code, 1.18 // not in native code. 1.19 @@ -168,12 +170,42 @@ 1.20 * SUPPORT FUNCTIONS 1.21 */ 1.22 1.23 +/** 1.24 + * Check whether or not a programmer has actually checked for exceptions. According 1.25 + * to the JNI Specification ("jni/spec/design.html#java_exceptions"): 1.26 + * 1.27 + * There are two cases where the programmer needs to check for exceptions without 1.28 + * being able to first check an error code: 1.29 + * 1.30 + * - The JNI functions that invoke a Java method return the result of the Java method. 1.31 + * The programmer must call ExceptionOccurred() to check for possible exceptions 1.32 + * that occurred during the execution of the Java method. 1.33 + * 1.34 + * - Some of the JNI array access functions do not return an error code, but may 1.35 + * throw an ArrayIndexOutOfBoundsException or ArrayStoreException. 1.36 + * 1.37 + * In all other cases, a non-error return value guarantees that no exceptions have been thrown. 1.38 + */ 1.39 +static inline void 1.40 +check_pending_exception(JavaThread* thr) { 1.41 + if (thr->has_pending_exception()) { 1.42 + NativeReportJNIWarning(thr, "JNI call made with exception pending"); 1.43 + } 1.44 + if (thr->is_pending_jni_exception_check()) { 1.45 + IN_VM( 1.46 + tty->print_cr("WARNING in native method: JNI call made without checking exceptions when required to from %s", 1.47 + thr->get_pending_jni_exception_check()); 1.48 + thr->print_stack(); 1.49 + ) 1.50 + thr->clear_pending_jni_exception_check(); // Just complain once 1.51 + } 1.52 +} 1.53 + 1.54 + 1.55 static inline void 1.56 functionEnterCritical(JavaThread* thr) 1.57 { 1.58 - if (thr->has_pending_exception()) { 1.59 - NativeReportJNIWarning(thr, "JNI call made with exception pending"); 1.60 - } 1.61 + check_pending_exception(thr); 1.62 } 1.63 1.64 static inline void 1.65 @@ -187,9 +219,7 @@ 1.66 if (thr->in_critical()) { 1.67 tty->print_cr("%s", warn_other_function_in_critical); 1.68 } 1.69 - if (thr->has_pending_exception()) { 1.70 - NativeReportJNIWarning(thr, "JNI call made with exception pending"); 1.71 - } 1.72 + check_pending_exception(thr); 1.73 } 1.74 1.75 static inline void 1.76 @@ -201,9 +231,20 @@ 1.77 } 1.78 1.79 static inline void 1.80 -functionExit(JNIEnv *env) 1.81 +functionExit(JavaThread* thr) 1.82 { 1.83 - /* nothing to do at this time */ 1.84 + JNIHandleBlock* handles = thr->active_handles(); 1.85 + size_t planned_capacity = handles->get_planned_capacity(); 1.86 + size_t live_handles = handles->get_number_of_live_handles(); 1.87 + if (live_handles > planned_capacity) { 1.88 + IN_VM( 1.89 + tty->print_cr("WARNING: JNI local refs: %zu, exceeds capacity: %zu", 1.90 + live_handles, planned_capacity); 1.91 + thr->print_stack(); 1.92 + ) 1.93 + // Complain just the once, reset to current + warn threshold 1.94 + handles->set_planned_capacity(live_handles + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD); 1.95 + } 1.96 } 1.97 1.98 static inline void 1.99 @@ -508,7 +549,7 @@ 1.100 jniCheck::validate_object(thr, loader); 1.101 ) 1.102 jclass result = UNCHECKED()->DefineClass(env, name, loader, buf, len); 1.103 - functionExit(env); 1.104 + functionExit(thr); 1.105 return result; 1.106 JNI_END 1.107 1.108 @@ -520,7 +561,7 @@ 1.109 jniCheck::validate_class_descriptor(thr, name); 1.110 ) 1.111 jclass result = UNCHECKED()->FindClass(env, name); 1.112 - functionExit(env); 1.113 + functionExit(thr); 1.114 return result; 1.115 JNI_END 1.116 1.117 @@ -532,7 +573,7 @@ 1.118 jniCheck::validate_object(thr, method); 1.119 ) 1.120 jmethodID result = UNCHECKED()->FromReflectedMethod(env, method); 1.121 - functionExit(env); 1.122 + functionExit(thr); 1.123 return result; 1.124 JNI_END 1.125 1.126 @@ -544,7 +585,7 @@ 1.127 jniCheck::validate_object(thr, field); 1.128 ) 1.129 jfieldID result = UNCHECKED()->FromReflectedField(env, field); 1.130 - functionExit(env); 1.131 + functionExit(thr); 1.132 return result; 1.133 JNI_END 1.134 1.135 @@ -560,7 +601,7 @@ 1.136 ) 1.137 jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID, 1.138 isStatic); 1.139 - functionExit(env); 1.140 + functionExit(thr); 1.141 return result; 1.142 JNI_END 1.143 1.144 @@ -572,7 +613,7 @@ 1.145 jniCheck::validate_class(thr, sub, true); 1.146 ) 1.147 jclass result = UNCHECKED()->GetSuperclass(env, sub); 1.148 - functionExit(env); 1.149 + functionExit(thr); 1.150 return result; 1.151 JNI_END 1.152 1.153 @@ -586,7 +627,7 @@ 1.154 jniCheck::validate_class(thr, sup, true); 1.155 ) 1.156 jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup); 1.157 - functionExit(env); 1.158 + functionExit(thr); 1.159 return result; 1.160 JNI_END 1.161 1.162 @@ -601,7 +642,7 @@ 1.163 ) 1.164 jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID, 1.165 isStatic); 1.166 - functionExit(env); 1.167 + functionExit(thr); 1.168 return result; 1.169 JNI_END 1.170 1.171 @@ -619,7 +660,7 @@ 1.172 } 1.173 ) 1.174 jint result = UNCHECKED()->Throw(env, obj); 1.175 - functionExit(env); 1.176 + functionExit(thr); 1.177 return result; 1.178 JNI_END 1.179 1.180 @@ -634,15 +675,16 @@ 1.181 jniCheck::validate_throwable_klass(thr, k); 1.182 ) 1.183 jint result = UNCHECKED()->ThrowNew(env, clazz, msg); 1.184 - functionExit(env); 1.185 + functionExit(thr); 1.186 return result; 1.187 JNI_END 1.188 1.189 JNI_ENTRY_CHECKED(jthrowable, 1.190 checked_jni_ExceptionOccurred(JNIEnv *env)) 1.191 + thr->clear_pending_jni_exception_check(); 1.192 functionEnterExceptionAllowed(thr); 1.193 jthrowable result = UNCHECKED()->ExceptionOccurred(env); 1.194 - functionExit(env); 1.195 + functionExit(thr); 1.196 return result; 1.197 JNI_END 1.198 1.199 @@ -650,22 +692,24 @@ 1.200 checked_jni_ExceptionDescribe(JNIEnv *env)) 1.201 functionEnterExceptionAllowed(thr); 1.202 UNCHECKED()->ExceptionDescribe(env); 1.203 - functionExit(env); 1.204 + functionExit(thr); 1.205 JNI_END 1.206 1.207 JNI_ENTRY_CHECKED(void, 1.208 checked_jni_ExceptionClear(JNIEnv *env)) 1.209 + thr->clear_pending_jni_exception_check(); 1.210 functionEnterExceptionAllowed(thr); 1.211 UNCHECKED()->ExceptionClear(env); 1.212 - functionExit(env); 1.213 + functionExit(thr); 1.214 JNI_END 1.215 1.216 JNI_ENTRY_CHECKED(void, 1.217 checked_jni_FatalError(JNIEnv *env, 1.218 const char *msg)) 1.219 + thr->clear_pending_jni_exception_check(); 1.220 functionEnter(thr); 1.221 UNCHECKED()->FatalError(env, msg); 1.222 - functionExit(env); 1.223 + functionExit(thr); 1.224 JNI_END 1.225 1.226 JNI_ENTRY_CHECKED(jint, 1.227 @@ -675,7 +719,10 @@ 1.228 if (capacity < 0) 1.229 NativeReportJNIFatalError(thr, "negative capacity"); 1.230 jint result = UNCHECKED()->PushLocalFrame(env, capacity); 1.231 - functionExit(env); 1.232 + if (result == JNI_OK) { 1.233 + thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD); 1.234 + } 1.235 + functionExit(thr); 1.236 return result; 1.237 JNI_END 1.238 1.239 @@ -684,7 +731,7 @@ 1.240 jobject result)) 1.241 functionEnterExceptionAllowed(thr); 1.242 jobject res = UNCHECKED()->PopLocalFrame(env, result); 1.243 - functionExit(env); 1.244 + functionExit(thr); 1.245 return res; 1.246 JNI_END 1.247 1.248 @@ -698,7 +745,7 @@ 1.249 } 1.250 ) 1.251 jobject result = UNCHECKED()->NewGlobalRef(env,lobj); 1.252 - functionExit(env); 1.253 + functionExit(thr); 1.254 return result; 1.255 JNI_END 1.256 1.257 @@ -714,7 +761,7 @@ 1.258 } 1.259 ) 1.260 UNCHECKED()->DeleteGlobalRef(env,gref); 1.261 - functionExit(env); 1.262 + functionExit(thr); 1.263 JNI_END 1.264 1.265 JNI_ENTRY_CHECKED(void, 1.266 @@ -729,7 +776,7 @@ 1.267 "Invalid local JNI handle passed to DeleteLocalRef"); 1.268 ) 1.269 UNCHECKED()->DeleteLocalRef(env, obj); 1.270 - functionExit(env); 1.271 + functionExit(thr); 1.272 JNI_END 1.273 1.274 JNI_ENTRY_CHECKED(jboolean, 1.275 @@ -750,7 +797,7 @@ 1.276 } 1.277 ) 1.278 jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2); 1.279 - functionExit(env); 1.280 + functionExit(thr); 1.281 return result; 1.282 JNI_END 1.283 1.284 @@ -764,7 +811,7 @@ 1.285 } 1.286 ) 1.287 jobject result = UNCHECKED()->NewLocalRef(env, ref); 1.288 - functionExit(env); 1.289 + functionExit(thr); 1.290 return result; 1.291 JNI_END 1.292 1.293 @@ -776,7 +823,10 @@ 1.294 NativeReportJNIFatalError(thr, "negative capacity"); 1.295 } 1.296 jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity); 1.297 - functionExit(env); 1.298 + if (result == JNI_OK) { 1.299 + thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD); 1.300 + } 1.301 + functionExit(thr); 1.302 return result; 1.303 JNI_END 1.304 1.305 @@ -788,7 +838,7 @@ 1.306 jniCheck::validate_class(thr, clazz, false); 1.307 ) 1.308 jobject result = UNCHECKED()->AllocObject(env,clazz); 1.309 - functionExit(env); 1.310 + functionExit(thr); 1.311 return result; 1.312 JNI_END 1.313 1.314 @@ -806,7 +856,7 @@ 1.315 va_start(args, methodID); 1.316 jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); 1.317 va_end(args); 1.318 - functionExit(env); 1.319 + functionExit(thr); 1.320 return result; 1.321 JNI_END 1.322 1.323 @@ -821,7 +871,7 @@ 1.324 jniCheck::validate_jmethod_id(thr, methodID); 1.325 ) 1.326 jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); 1.327 - functionExit(env); 1.328 + functionExit(thr); 1.329 return result; 1.330 JNI_END 1.331 1.332 @@ -836,7 +886,7 @@ 1.333 jniCheck::validate_jmethod_id(thr, methodID); 1.334 ) 1.335 jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args); 1.336 - functionExit(env); 1.337 + functionExit(thr); 1.338 return result; 1.339 JNI_END 1.340 1.341 @@ -848,7 +898,7 @@ 1.342 jniCheck::validate_object(thr, obj); 1.343 ) 1.344 jclass result = UNCHECKED()->GetObjectClass(env,obj); 1.345 - functionExit(env); 1.346 + functionExit(thr); 1.347 return result; 1.348 JNI_END 1.349 1.350 @@ -862,7 +912,7 @@ 1.351 jniCheck::validate_class(thr, clazz, true); 1.352 ) 1.353 jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz); 1.354 - functionExit(env); 1.355 + functionExit(thr); 1.356 return result; 1.357 JNI_END 1.358 1.359 @@ -876,7 +926,7 @@ 1.360 jniCheck::validate_class(thr, clazz, false); 1.361 ) 1.362 jmethodID result = UNCHECKED()->GetMethodID(env,clazz,name,sig); 1.363 - functionExit(env); 1.364 + functionExit(thr); 1.365 return result; 1.366 JNI_END 1.367 1.368 @@ -895,7 +945,8 @@ 1.369 ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \ 1.370 args); \ 1.371 va_end(args); \ 1.372 - functionExit(env); \ 1.373 + thr->set_pending_jni_exception_check("Call"#Result"Method"); \ 1.374 + functionExit(thr); \ 1.375 return result; \ 1.376 JNI_END \ 1.377 \ 1.378 @@ -910,7 +961,8 @@ 1.379 ) \ 1.380 ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\ 1.381 args); \ 1.382 - functionExit(env); \ 1.383 + thr->set_pending_jni_exception_check("Call"#Result"MethodV"); \ 1.384 + functionExit(thr); \ 1.385 return result; \ 1.386 JNI_END \ 1.387 \ 1.388 @@ -925,7 +977,8 @@ 1.389 ) \ 1.390 ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\ 1.391 args); \ 1.392 - functionExit(env); \ 1.393 + thr->set_pending_jni_exception_check("Call"#Result"MethodA"); \ 1.394 + functionExit(thr); \ 1.395 return result; \ 1.396 JNI_END 1.397 1.398 @@ -952,7 +1005,8 @@ 1.399 va_start(args,methodID); 1.400 UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); 1.401 va_end(args); 1.402 - functionExit(env); 1.403 + thr->set_pending_jni_exception_check("CallVoidMethod"); 1.404 + functionExit(thr); 1.405 JNI_END 1.406 1.407 JNI_ENTRY_CHECKED(void, 1.408 @@ -965,7 +1019,8 @@ 1.409 jniCheck::validate_call_object(thr, obj, methodID); 1.410 ) 1.411 UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); 1.412 - functionExit(env); 1.413 + thr->set_pending_jni_exception_check("CallVoidMethodV"); 1.414 + functionExit(thr); 1.415 JNI_END 1.416 1.417 JNI_ENTRY_CHECKED(void, 1.418 @@ -978,7 +1033,8 @@ 1.419 jniCheck::validate_call_object(thr, obj, methodID); 1.420 ) 1.421 UNCHECKED()->CallVoidMethodA(env,obj,methodID,args); 1.422 - functionExit(env); 1.423 + thr->set_pending_jni_exception_check("CallVoidMethodA"); 1.424 + functionExit(thr); 1.425 JNI_END 1.426 1.427 #define WRAPPER_CallNonvirtualMethod(ResultType, Result) \ 1.428 @@ -1001,7 +1057,8 @@ 1.429 methodID,\ 1.430 args); \ 1.431 va_end(args); \ 1.432 - functionExit(env); \ 1.433 + thr->set_pending_jni_exception_check("CallNonvirtual"#Result"Method"); \ 1.434 + functionExit(thr); \ 1.435 return result; \ 1.436 JNI_END \ 1.437 \ 1.438 @@ -1021,7 +1078,8 @@ 1.439 clazz, \ 1.440 methodID,\ 1.441 args); \ 1.442 - functionExit(env); \ 1.443 + thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodV"); \ 1.444 + functionExit(thr); \ 1.445 return result; \ 1.446 JNI_END \ 1.447 \ 1.448 @@ -1041,7 +1099,8 @@ 1.449 clazz, \ 1.450 methodID,\ 1.451 args); \ 1.452 - functionExit(env); \ 1.453 + thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodA"); \ 1.454 + functionExit(thr); \ 1.455 return result; \ 1.456 JNI_END 1.457 1.458 @@ -1070,7 +1129,8 @@ 1.459 va_start(args,methodID); 1.460 UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); 1.461 va_end(args); 1.462 - functionExit(env); 1.463 + thr->set_pending_jni_exception_check("CallNonvirtualVoidMethod"); 1.464 + functionExit(thr); 1.465 JNI_END 1.466 1.467 JNI_ENTRY_CHECKED(void, 1.468 @@ -1085,7 +1145,8 @@ 1.469 jniCheck::validate_call_class(thr, clazz, methodID); 1.470 ) 1.471 UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); 1.472 - functionExit(env); 1.473 + thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV"); 1.474 + functionExit(thr); 1.475 JNI_END 1.476 1.477 JNI_ENTRY_CHECKED(void, 1.478 @@ -1100,7 +1161,8 @@ 1.479 jniCheck::validate_call_class(thr, clazz, methodID); 1.480 ) 1.481 UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args); 1.482 - functionExit(env); 1.483 + thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA"); 1.484 + functionExit(thr); 1.485 JNI_END 1.486 1.487 JNI_ENTRY_CHECKED(jfieldID, 1.488 @@ -1113,7 +1175,7 @@ 1.489 jniCheck::validate_class(thr, clazz, false); 1.490 ) 1.491 jfieldID result = UNCHECKED()->GetFieldID(env,clazz,name,sig); 1.492 - functionExit(env); 1.493 + functionExit(thr); 1.494 return result; 1.495 JNI_END 1.496 1.497 @@ -1127,7 +1189,7 @@ 1.498 checkInstanceFieldID(thr, fieldID, obj, FieldType); \ 1.499 ) \ 1.500 ReturnType result = UNCHECKED()->Get##Result##Field(env,obj,fieldID); \ 1.501 - functionExit(env); \ 1.502 + functionExit(thr); \ 1.503 return result; \ 1.504 JNI_END 1.505 1.506 @@ -1152,7 +1214,7 @@ 1.507 checkInstanceFieldID(thr, fieldID, obj, FieldType); \ 1.508 ) \ 1.509 UNCHECKED()->Set##Result##Field(env,obj,fieldID,val); \ 1.510 - functionExit(env); \ 1.511 + functionExit(thr); \ 1.512 JNI_END 1.513 1.514 WRAPPER_SetField(jobject, Object, T_OBJECT) 1.515 @@ -1176,7 +1238,7 @@ 1.516 jniCheck::validate_class(thr, clazz, false); 1.517 ) 1.518 jmethodID result = UNCHECKED()->GetStaticMethodID(env,clazz,name,sig); 1.519 - functionExit(env); 1.520 + functionExit(thr); 1.521 return result; 1.522 JNI_END 1.523 1.524 @@ -1198,7 +1260,8 @@ 1.525 methodID, \ 1.526 args); \ 1.527 va_end(args); \ 1.528 - functionExit(env); \ 1.529 + thr->set_pending_jni_exception_check("CallStatic"#Result"Method"); \ 1.530 + functionExit(thr); \ 1.531 return result; \ 1.532 JNI_END \ 1.533 \ 1.534 @@ -1216,7 +1279,8 @@ 1.535 clazz, \ 1.536 methodID, \ 1.537 args); \ 1.538 - functionExit(env); \ 1.539 + thr->set_pending_jni_exception_check("CallStatic"#Result"MethodV"); \ 1.540 + functionExit(thr); \ 1.541 return result; \ 1.542 JNI_END \ 1.543 \ 1.544 @@ -1234,7 +1298,8 @@ 1.545 clazz, \ 1.546 methodID, \ 1.547 args); \ 1.548 - functionExit(env); \ 1.549 + thr->set_pending_jni_exception_check("CallStatic"#Result"MethodA"); \ 1.550 + functionExit(thr); \ 1.551 return result; \ 1.552 JNI_END 1.553 1.554 @@ -1262,7 +1327,8 @@ 1.555 va_start(args,methodID); 1.556 UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); 1.557 va_end(args); 1.558 - functionExit(env); 1.559 + thr->set_pending_jni_exception_check("CallStaticVoidMethod"); 1.560 + functionExit(thr); 1.561 JNI_END 1.562 1.563 JNI_ENTRY_CHECKED(void, 1.564 @@ -1276,7 +1342,8 @@ 1.565 jniCheck::validate_class(thr, cls, false); 1.566 ) 1.567 UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); 1.568 - functionExit(env); 1.569 + thr->set_pending_jni_exception_check("CallStaticVoidMethodV"); 1.570 + functionExit(thr); 1.571 JNI_END 1.572 1.573 JNI_ENTRY_CHECKED(void, 1.574 @@ -1290,7 +1357,8 @@ 1.575 jniCheck::validate_class(thr, cls, false); 1.576 ) 1.577 UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args); 1.578 - functionExit(env); 1.579 + thr->set_pending_jni_exception_check("CallStaticVoidMethodA"); 1.580 + functionExit(thr); 1.581 JNI_END 1.582 1.583 JNI_ENTRY_CHECKED(jfieldID, 1.584 @@ -1303,7 +1371,7 @@ 1.585 jniCheck::validate_class(thr, clazz, false); 1.586 ) 1.587 jfieldID result = UNCHECKED()->GetStaticFieldID(env,clazz,name,sig); 1.588 - functionExit(env); 1.589 + functionExit(thr); 1.590 return result; 1.591 JNI_END 1.592 1.593 @@ -1320,7 +1388,7 @@ 1.594 ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \ 1.595 clazz, \ 1.596 fieldID); \ 1.597 - functionExit(env); \ 1.598 + functionExit(thr); \ 1.599 return result; \ 1.600 JNI_END 1.601 1.602 @@ -1346,7 +1414,7 @@ 1.603 checkStaticFieldID(thr, fieldID, clazz, FieldType); \ 1.604 ) \ 1.605 UNCHECKED()->SetStatic##Result##Field(env,clazz,fieldID,value); \ 1.606 - functionExit(env); \ 1.607 + functionExit(thr); \ 1.608 JNI_END 1.609 1.610 WRAPPER_SetStaticField(jobject, Object, T_OBJECT) 1.611 @@ -1366,7 +1434,7 @@ 1.612 jsize len)) 1.613 functionEnter(thr); 1.614 jstring result = UNCHECKED()->NewString(env,unicode,len); 1.615 - functionExit(env); 1.616 + functionExit(thr); 1.617 return result; 1.618 JNI_END 1.619 1.620 @@ -1378,7 +1446,7 @@ 1.621 checkString(thr, str); 1.622 ) 1.623 jsize result = UNCHECKED()->GetStringLength(env,str); 1.624 - functionExit(env); 1.625 + functionExit(thr); 1.626 return result; 1.627 JNI_END 1.628 1.629 @@ -1407,7 +1475,7 @@ 1.630 // Note that the dtrace arguments for the allocated memory will not match up with this solution. 1.631 FreeHeap((char*)result); 1.632 } 1.633 - functionExit(env); 1.634 + functionExit(thr); 1.635 return new_result; 1.636 JNI_END 1.637 1.638 @@ -1442,7 +1510,7 @@ 1.639 UNCHECKED()->ReleaseStringChars(env, str, 1.640 (const jchar*) guarded.release_for_freeing()); 1.641 } 1.642 - functionExit(env); 1.643 + functionExit(thr); 1.644 JNI_END 1.645 1.646 JNI_ENTRY_CHECKED(jstring, 1.647 @@ -1450,7 +1518,7 @@ 1.648 const char *utf)) 1.649 functionEnter(thr); 1.650 jstring result = UNCHECKED()->NewStringUTF(env,utf); 1.651 - functionExit(env); 1.652 + functionExit(thr); 1.653 return result; 1.654 JNI_END 1.655 1.656 @@ -1462,7 +1530,7 @@ 1.657 checkString(thr, str); 1.658 ) 1.659 jsize result = UNCHECKED()->GetStringUTFLength(env,str); 1.660 - functionExit(env); 1.661 + functionExit(thr); 1.662 return result; 1.663 JNI_END 1.664 1.665 @@ -1490,7 +1558,7 @@ 1.666 // Note that the dtrace arguments for the allocated memory will not match up with this solution. 1.667 FreeHeap((char*)result, mtInternal); 1.668 } 1.669 - functionExit(env); 1.670 + functionExit(thr); 1.671 return new_result; 1.672 JNI_END 1.673 1.674 @@ -1525,7 +1593,7 @@ 1.675 UNCHECKED()->ReleaseStringUTFChars(env, str, 1.676 (const char*) guarded.release_for_freeing()); 1.677 } 1.678 - functionExit(env); 1.679 + functionExit(thr); 1.680 JNI_END 1.681 1.682 JNI_ENTRY_CHECKED(jsize, 1.683 @@ -1536,7 +1604,7 @@ 1.684 check_is_array(thr, array); 1.685 ) 1.686 jsize result = UNCHECKED()->GetArrayLength(env,array); 1.687 - functionExit(env); 1.688 + functionExit(thr); 1.689 return result; 1.690 JNI_END 1.691 1.692 @@ -1547,7 +1615,7 @@ 1.693 jobject init)) 1.694 functionEnter(thr); 1.695 jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init); 1.696 - functionExit(env); 1.697 + functionExit(thr); 1.698 return result; 1.699 JNI_END 1.700 1.701 @@ -1560,7 +1628,8 @@ 1.702 check_is_obj_array(thr, array); 1.703 ) 1.704 jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index); 1.705 - functionExit(env); 1.706 + thr->set_pending_jni_exception_check("GetObjectArrayElement"); 1.707 + functionExit(thr); 1.708 return result; 1.709 JNI_END 1.710 1.711 @@ -1574,7 +1643,8 @@ 1.712 check_is_obj_array(thr, array); 1.713 ) 1.714 UNCHECKED()->SetObjectArrayElement(env,array,index,val); 1.715 - functionExit(env); 1.716 + thr->set_pending_jni_exception_check("SetObjectArrayElement"); 1.717 + functionExit(thr); 1.718 JNI_END 1.719 1.720 #define WRAPPER_NewScalarArray(Return, Result) \ 1.721 @@ -1583,7 +1653,7 @@ 1.722 jsize len)) \ 1.723 functionEnter(thr); \ 1.724 Return result = UNCHECKED()->New##Result##Array(env,len); \ 1.725 - functionExit(env); \ 1.726 + functionExit(thr); \ 1.727 return (Return) result; \ 1.728 JNI_END 1.729 1.730 @@ -1611,7 +1681,7 @@ 1.731 if (result != NULL) { \ 1.732 result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \ 1.733 } \ 1.734 - functionExit(env); \ 1.735 + functionExit(thr); \ 1.736 return result; \ 1.737 JNI_END 1.738 1.739 @@ -1639,7 +1709,7 @@ 1.740 ElementType* orig_result = (ElementType *) check_wrapped_array_release( \ 1.741 thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode); \ 1.742 UNCHECKED()->Release##Result##ArrayElements(env, array, orig_result, mode); \ 1.743 - functionExit(env); \ 1.744 + functionExit(thr); \ 1.745 JNI_END 1.746 1.747 WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool) 1.748 @@ -1663,7 +1733,8 @@ 1.749 check_primitive_array_type(thr, array, ElementTag); \ 1.750 ) \ 1.751 UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \ 1.752 - functionExit(env); \ 1.753 + thr->set_pending_jni_exception_check("Get"#Result"ArrayRegion"); \ 1.754 + functionExit(thr); \ 1.755 JNI_END 1.756 1.757 WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) 1.758 @@ -1687,7 +1758,8 @@ 1.759 check_primitive_array_type(thr, array, ElementTag); \ 1.760 ) \ 1.761 UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \ 1.762 - functionExit(env); \ 1.763 + thr->set_pending_jni_exception_check("Set"#Result"ArrayRegion"); \ 1.764 + functionExit(thr); \ 1.765 JNI_END 1.766 1.767 WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) 1.768 @@ -1706,7 +1778,7 @@ 1.769 jint nMethods)) 1.770 functionEnter(thr); 1.771 jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods); 1.772 - functionExit(env); 1.773 + functionExit(thr); 1.774 return result; 1.775 JNI_END 1.776 1.777 @@ -1715,7 +1787,7 @@ 1.778 jclass clazz)) 1.779 functionEnter(thr); 1.780 jint result = UNCHECKED()->UnregisterNatives(env,clazz); 1.781 - functionExit(env); 1.782 + functionExit(thr); 1.783 return result; 1.784 JNI_END 1.785 1.786 @@ -1727,7 +1799,7 @@ 1.787 jniCheck::validate_object(thr, obj); 1.788 ) 1.789 jint result = UNCHECKED()->MonitorEnter(env,obj); 1.790 - functionExit(env); 1.791 + functionExit(thr); 1.792 return result; 1.793 JNI_END 1.794 1.795 @@ -1739,7 +1811,7 @@ 1.796 jniCheck::validate_object(thr, obj); 1.797 ) 1.798 jint result = UNCHECKED()->MonitorExit(env,obj); 1.799 - functionExit(env); 1.800 + functionExit(thr); 1.801 return result; 1.802 JNI_END 1.803 1.804 @@ -1748,7 +1820,7 @@ 1.805 JavaVM **vm)) 1.806 functionEnter(thr); 1.807 jint result = UNCHECKED()->GetJavaVM(env,vm); 1.808 - functionExit(env); 1.809 + functionExit(thr); 1.810 return result; 1.811 JNI_END 1.812 1.813 @@ -1763,7 +1835,8 @@ 1.814 checkString(thr, str); 1.815 ) 1.816 UNCHECKED()->GetStringRegion(env, str, start, len, buf); 1.817 - functionExit(env); 1.818 + thr->set_pending_jni_exception_check("GetStringRegion"); 1.819 + functionExit(thr); 1.820 JNI_END 1.821 1.822 JNI_ENTRY_CHECKED(void, 1.823 @@ -1777,7 +1850,8 @@ 1.824 checkString(thr, str); 1.825 ) 1.826 UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf); 1.827 - functionExit(env); 1.828 + thr->set_pending_jni_exception_check("GetStringUTFRegion"); 1.829 + functionExit(thr); 1.830 JNI_END 1.831 1.832 JNI_ENTRY_CHECKED(void *, 1.833 @@ -1792,7 +1866,7 @@ 1.834 if (result != NULL) { 1.835 result = check_jni_wrap_copy_array(thr, array, result); 1.836 } 1.837 - functionExit(env); 1.838 + functionExit(thr); 1.839 return result; 1.840 JNI_END 1.841 1.842 @@ -1808,7 +1882,7 @@ 1.843 // Check the element array... 1.844 void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical", array, carray, mode); 1.845 UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode); 1.846 - functionExit(env); 1.847 + functionExit(thr); 1.848 JNI_END 1.849 1.850 JNI_ENTRY_CHECKED(const jchar*, 1.851 @@ -1820,7 +1894,7 @@ 1.852 checkString(thr, string); 1.853 ) 1.854 const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy); 1.855 - functionExit(env); 1.856 + functionExit(thr); 1.857 return result; 1.858 JNI_END 1.859 1.860 @@ -1836,7 +1910,7 @@ 1.861 * string parameter as a minor sanity check 1.862 */ 1.863 UNCHECKED()->ReleaseStringCritical(env, str, chars); 1.864 - functionExit(env); 1.865 + functionExit(thr); 1.866 JNI_END 1.867 1.868 JNI_ENTRY_CHECKED(jweak, 1.869 @@ -1849,7 +1923,7 @@ 1.870 } 1.871 ) 1.872 jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj); 1.873 - functionExit(env); 1.874 + functionExit(thr); 1.875 return result; 1.876 JNI_END 1.877 1.878 @@ -1858,14 +1932,15 @@ 1.879 jweak ref)) 1.880 functionEnterExceptionAllowed(thr); 1.881 UNCHECKED()->DeleteWeakGlobalRef(env, ref); 1.882 - functionExit(env); 1.883 + functionExit(thr); 1.884 JNI_END 1.885 1.886 JNI_ENTRY_CHECKED(jboolean, 1.887 checked_jni_ExceptionCheck(JNIEnv *env)) 1.888 + thr->clear_pending_jni_exception_check(); 1.889 functionEnterExceptionAllowed(thr); 1.890 jboolean result = UNCHECKED()->ExceptionCheck(env); 1.891 - functionExit(env); 1.892 + functionExit(thr); 1.893 return result; 1.894 JNI_END 1.895 1.896 @@ -1875,7 +1950,7 @@ 1.897 jlong capacity)) 1.898 functionEnter(thr); 1.899 jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity); 1.900 - functionExit(env); 1.901 + functionExit(thr); 1.902 return result; 1.903 JNI_END 1.904 1.905 @@ -1884,7 +1959,7 @@ 1.906 jobject buf)) 1.907 functionEnter(thr); 1.908 void* result = UNCHECKED()->GetDirectBufferAddress(env, buf); 1.909 - functionExit(env); 1.910 + functionExit(thr); 1.911 return result; 1.912 JNI_END 1.913 1.914 @@ -1893,7 +1968,7 @@ 1.915 jobject buf)) 1.916 functionEnter(thr); 1.917 jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf); 1.918 - functionExit(env); 1.919 + functionExit(thr); 1.920 return result; 1.921 JNI_END 1.922 1.923 @@ -1906,7 +1981,7 @@ 1.924 jniCheck::validate_object(thr, obj); 1.925 ) 1.926 jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj); 1.927 - functionExit(env); 1.928 + functionExit(thr); 1.929 return result; 1.930 JNI_END 1.931 1.932 @@ -1915,7 +1990,7 @@ 1.933 checked_jni_GetVersion(JNIEnv *env)) 1.934 functionEnter(thr); 1.935 jint result = UNCHECKED()->GetVersion(env); 1.936 - functionExit(env); 1.937 + functionExit(thr); 1.938 return result; 1.939 JNI_END 1.940