hotspot/src/share/vm/prims/jniCheck.cpp
changeset 25716 fc9bd7814b10
parent 25715 d5a8dbdc5150
parent 25629 812ae9c40c85
child 27880 afb974a04396
equal deleted inserted replaced
25715:d5a8dbdc5150 25716:fc9bd7814b10
   168  *
   168  *
   169  * - Some of the JNI array access functions do not return an error code, but may
   169  * - Some of the JNI array access functions do not return an error code, but may
   170  * throw an ArrayIndexOutOfBoundsException or ArrayStoreException.
   170  * throw an ArrayIndexOutOfBoundsException or ArrayStoreException.
   171  *
   171  *
   172  * In all other cases, a non-error return value guarantees that no exceptions have been thrown.
   172  * In all other cases, a non-error return value guarantees that no exceptions have been thrown.
       
   173  *
       
   174  * Programmers often defend against ArrayIndexOutOfBoundsException, so warning
       
   175  * for these functions would be pedantic.
   173  */
   176  */
   174 static inline void
   177 static inline void
   175 check_pending_exception(JavaThread* thr) {
   178 check_pending_exception(JavaThread* thr) {
   176   if (thr->has_pending_exception()) {
   179   if (thr->has_pending_exception()) {
   177     NativeReportJNIWarning(thr, "JNI call made with exception pending");
   180     NativeReportJNIWarning(thr, "JNI call made with exception pending");
   182         thr->get_pending_jni_exception_check());
   185         thr->get_pending_jni_exception_check());
   183       thr->print_stack();
   186       thr->print_stack();
   184     )
   187     )
   185     thr->clear_pending_jni_exception_check(); // Just complain once
   188     thr->clear_pending_jni_exception_check(); // Just complain once
   186   }
   189   }
       
   190 }
       
   191 
       
   192 /**
       
   193  * Add to the planned number of handles. I.e. plus current live & warning threshold
       
   194  */
       
   195 static inline void
       
   196 add_planned_handle_capacity(JNIHandleBlock* handles, size_t capacity) {
       
   197   handles->set_planned_capacity(capacity +
       
   198                                 handles->get_number_of_live_handles() +
       
   199                                 CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
   187 }
   200 }
   188 
   201 
   189 
   202 
   190 static inline void
   203 static inline void
   191 functionEnterCritical(JavaThread* thr)
   204 functionEnterCritical(JavaThread* thr)
   226       tty->print_cr("WARNING: JNI local refs: %zu, exceeds capacity: %zu",
   239       tty->print_cr("WARNING: JNI local refs: %zu, exceeds capacity: %zu",
   227           live_handles, planned_capacity);
   240           live_handles, planned_capacity);
   228       thr->print_stack();
   241       thr->print_stack();
   229     )
   242     )
   230     // Complain just the once, reset to current + warn threshold
   243     // Complain just the once, reset to current + warn threshold
   231     handles->set_planned_capacity(live_handles + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
   244     add_planned_handle_capacity(handles, 0);
   232   }
   245   }
   233 }
   246 }
   234 
   247 
   235 static inline void
   248 static inline void
   236 checkStaticFieldID(JavaThread* thr, jfieldID fid, jclass cls, int ftype)
   249 checkStaticFieldID(JavaThread* thr, jfieldID fid, jclass cls, int ftype)
   703     functionEnterExceptionAllowed(thr);
   716     functionEnterExceptionAllowed(thr);
   704     if (capacity < 0)
   717     if (capacity < 0)
   705       NativeReportJNIFatalError(thr, "negative capacity");
   718       NativeReportJNIFatalError(thr, "negative capacity");
   706     jint result = UNCHECKED()->PushLocalFrame(env, capacity);
   719     jint result = UNCHECKED()->PushLocalFrame(env, capacity);
   707     if (result == JNI_OK) {
   720     if (result == JNI_OK) {
   708       thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
   721       add_planned_handle_capacity(thr->active_handles(), capacity);
   709     }
   722     }
   710     functionExit(thr);
   723     functionExit(thr);
   711     return result;
   724     return result;
   712 JNI_END
   725 JNI_END
   713 
   726 
   807     if (capacity < 0) {
   820     if (capacity < 0) {
   808       NativeReportJNIFatalError(thr, "negative capacity");
   821       NativeReportJNIFatalError(thr, "negative capacity");
   809     }
   822     }
   810     jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity);
   823     jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity);
   811     if (result == JNI_OK) {
   824     if (result == JNI_OK) {
   812       thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
   825       add_planned_handle_capacity(thr->active_handles(), capacity);
   813     }
   826     }
   814     functionExit(thr);
   827     functionExit(thr);
   815     return result;
   828     return result;
   816 JNI_END
   829 JNI_END
   817 
   830 
  1611     functionEnter(thr);
  1624     functionEnter(thr);
  1612     IN_VM(
  1625     IN_VM(
  1613       check_is_obj_array(thr, array);
  1626       check_is_obj_array(thr, array);
  1614     )
  1627     )
  1615     jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
  1628     jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
  1616     thr->set_pending_jni_exception_check("GetObjectArrayElement");
       
  1617     functionExit(thr);
  1629     functionExit(thr);
  1618     return result;
  1630     return result;
  1619 JNI_END
  1631 JNI_END
  1620 
  1632 
  1621 JNI_ENTRY_CHECKED(void,
  1633 JNI_ENTRY_CHECKED(void,
  1626     functionEnter(thr);
  1638     functionEnter(thr);
  1627     IN_VM(
  1639     IN_VM(
  1628       check_is_obj_array(thr, array);
  1640       check_is_obj_array(thr, array);
  1629     )
  1641     )
  1630     UNCHECKED()->SetObjectArrayElement(env,array,index,val);
  1642     UNCHECKED()->SetObjectArrayElement(env,array,index,val);
  1631     thr->set_pending_jni_exception_check("SetObjectArrayElement");
       
  1632     functionExit(thr);
  1643     functionExit(thr);
  1633 JNI_END
  1644 JNI_END
  1634 
  1645 
  1635 #define WRAPPER_NewScalarArray(Return, Result) \
  1646 #define WRAPPER_NewScalarArray(Return, Result) \
  1636 JNI_ENTRY_CHECKED(Return, \
  1647 JNI_ENTRY_CHECKED(Return, \
  1716     functionEnter(thr); \
  1727     functionEnter(thr); \
  1717     IN_VM( \
  1728     IN_VM( \
  1718       check_primitive_array_type(thr, array, ElementTag); \
  1729       check_primitive_array_type(thr, array, ElementTag); \
  1719     ) \
  1730     ) \
  1720     UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \
  1731     UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \
  1721     thr->set_pending_jni_exception_check("Get"#Result"ArrayRegion"); \
       
  1722     functionExit(thr); \
  1732     functionExit(thr); \
  1723 JNI_END
  1733 JNI_END
  1724 
  1734 
  1725 WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
  1735 WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
  1726 WRAPPER_GetScalarArrayRegion(T_BYTE,    jbyte,    Byte)
  1736 WRAPPER_GetScalarArrayRegion(T_BYTE,    jbyte,    Byte)
  1741     functionEnter(thr); \
  1751     functionEnter(thr); \
  1742     IN_VM( \
  1752     IN_VM( \
  1743       check_primitive_array_type(thr, array, ElementTag); \
  1753       check_primitive_array_type(thr, array, ElementTag); \
  1744     ) \
  1754     ) \
  1745     UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \
  1755     UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \
  1746     thr->set_pending_jni_exception_check("Set"#Result"ArrayRegion"); \
       
  1747     functionExit(thr); \
  1756     functionExit(thr); \
  1748 JNI_END
  1757 JNI_END
  1749 
  1758 
  1750 WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
  1759 WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
  1751 WRAPPER_SetScalarArrayRegion(T_BYTE,    jbyte,    Byte)
  1760 WRAPPER_SetScalarArrayRegion(T_BYTE,    jbyte,    Byte)
  1818     functionEnter(thr);
  1827     functionEnter(thr);
  1819     IN_VM(
  1828     IN_VM(
  1820       checkString(thr, str);
  1829       checkString(thr, str);
  1821     )
  1830     )
  1822     UNCHECKED()->GetStringRegion(env, str, start, len, buf);
  1831     UNCHECKED()->GetStringRegion(env, str, start, len, buf);
  1823     thr->set_pending_jni_exception_check("GetStringRegion");
       
  1824     functionExit(thr);
  1832     functionExit(thr);
  1825 JNI_END
  1833 JNI_END
  1826 
  1834 
  1827 JNI_ENTRY_CHECKED(void,
  1835 JNI_ENTRY_CHECKED(void,
  1828   checked_jni_GetStringUTFRegion(JNIEnv *env,
  1836   checked_jni_GetStringUTFRegion(JNIEnv *env,
  1833     functionEnter(thr);
  1841     functionEnter(thr);
  1834     IN_VM(
  1842     IN_VM(
  1835       checkString(thr, str);
  1843       checkString(thr, str);
  1836     )
  1844     )
  1837     UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
  1845     UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
  1838     thr->set_pending_jni_exception_check("GetStringUTFRegion");
       
  1839     functionExit(thr);
  1846     functionExit(thr);
  1840 JNI_END
  1847 JNI_END
  1841 
  1848 
  1842 JNI_ENTRY_CHECKED(void *,
  1849 JNI_ENTRY_CHECKED(void *,
  1843   checked_jni_GetPrimitiveArrayCritical(JNIEnv *env,
  1850   checked_jni_GetPrimitiveArrayCritical(JNIEnv *env,