src/share/vm/prims/jniCheck.cpp

changeset 7627
d68158e12cea
parent 7033
29a5c2fd2d2e
child 7843
9904bb920313
     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  

mercurial