提交 6cbab986 编写于 作者: A amurillo

Merge

...@@ -51,6 +51,9 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -51,6 +51,9 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
private static final int C_INT32_SIZE = 4; private static final int C_INT32_SIZE = 4;
private static final int C_INT64_SIZE = 8; private static final int C_INT64_SIZE = 8;
private static int pointerSize = UNINITIALIZED_SIZE; private static int pointerSize = UNINITIALIZED_SIZE;
// Counter to ensure read loops terminate:
private static final int MAX_DUPLICATE_DEFINITIONS = 100;
private int duplicateDefCount = 0;
private static final boolean DEBUG; private static final boolean DEBUG;
static { static {
...@@ -166,6 +169,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -166,6 +169,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset"); typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride"); typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
if (typeEntryArrayStride == 0L) {
throw new RuntimeException("zero stride: cannot read types.");
}
// Start iterating down it until we find an entry with no name // Start iterating down it until we find an entry with no name
Address typeNameAddr = null; Address typeNameAddr = null;
do { do {
...@@ -192,7 +199,11 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -192,7 +199,11 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
} }
entryAddr = entryAddr.addOffsetTo(typeEntryArrayStride); entryAddr = entryAddr.addOffsetTo(typeEntryArrayStride);
} while (typeNameAddr != null); } while (typeNameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS);
if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) {
throw new RuntimeException("too many duplicate definitions");
}
} }
private void initializePrimitiveTypes() { private void initializePrimitiveTypes() {
...@@ -395,6 +406,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -395,6 +406,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
structEntryAddressOffset = getLongValueFromProcess("gHotSpotVMStructEntryAddressOffset"); structEntryAddressOffset = getLongValueFromProcess("gHotSpotVMStructEntryAddressOffset");
structEntryArrayStride = getLongValueFromProcess("gHotSpotVMStructEntryArrayStride"); structEntryArrayStride = getLongValueFromProcess("gHotSpotVMStructEntryArrayStride");
if (structEntryArrayStride == 0L) {
throw new RuntimeException("zero stride: cannot read types.");
}
// Fetch the address of the VMStructEntry* // Fetch the address of the VMStructEntry*
Address entryAddr = lookupInProcess("gHotSpotVMStructs"); Address entryAddr = lookupInProcess("gHotSpotVMStructs");
// Dereference this once to get the pointer to the first VMStructEntry // Dereference this once to get the pointer to the first VMStructEntry
...@@ -472,6 +487,11 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -472,6 +487,11 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
intConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMIntConstantEntryValueOffset"); intConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMIntConstantEntryValueOffset");
intConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMIntConstantEntryArrayStride"); intConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMIntConstantEntryArrayStride");
if (intConstantEntryArrayStride == 0L) {
throw new RuntimeException("zero stride: cannot read types.");
}
// Fetch the address of the VMIntConstantEntry* // Fetch the address of the VMIntConstantEntry*
Address entryAddr = lookupInProcess("gHotSpotVMIntConstants"); Address entryAddr = lookupInProcess("gHotSpotVMIntConstants");
// Dereference this once to get the pointer to the first VMIntConstantEntry // Dereference this once to get the pointer to the first VMIntConstantEntry
...@@ -501,12 +521,17 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -501,12 +521,17 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
} else { } else {
System.err.println("Warning: the int constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMIntConstants) " + System.err.println("Warning: the int constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMIntConstants) " +
"had its value declared as " + value + " twice. Continuing."); "had its value declared as " + value + " twice. Continuing.");
duplicateDefCount++;
} }
} }
} }
entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride); entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride);
} while (nameAddr != null); } while (nameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS);
if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) {
throw new RuntimeException("too many duplicate definitions");
}
} }
private void readVMLongConstants() { private void readVMLongConstants() {
...@@ -519,6 +544,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -519,6 +544,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
longConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMLongConstantEntryValueOffset"); longConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMLongConstantEntryValueOffset");
longConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMLongConstantEntryArrayStride"); longConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMLongConstantEntryArrayStride");
if (longConstantEntryArrayStride == 0L) {
throw new RuntimeException("zero stride: cannot read types.");
}
// Fetch the address of the VMLongConstantEntry* // Fetch the address of the VMLongConstantEntry*
Address entryAddr = lookupInProcess("gHotSpotVMLongConstants"); Address entryAddr = lookupInProcess("gHotSpotVMLongConstants");
// Dereference this once to get the pointer to the first VMLongConstantEntry // Dereference this once to get the pointer to the first VMLongConstantEntry
...@@ -548,12 +577,17 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -548,12 +577,17 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
} else { } else {
System.err.println("Warning: the long constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMLongConstants) " + System.err.println("Warning: the long constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMLongConstants) " +
"had its value declared as " + value + " twice. Continuing."); "had its value declared as " + value + " twice. Continuing.");
duplicateDefCount++;
} }
} }
} }
entryAddr = entryAddr.addOffsetTo(longConstantEntryArrayStride); entryAddr = entryAddr.addOffsetTo(longConstantEntryArrayStride);
} while (nameAddr != null); } while (nameAddr != null && duplicateDefCount < MAX_DUPLICATE_DEFINITIONS);
if (duplicateDefCount >= MAX_DUPLICATE_DEFINITIONS) {
throw new RuntimeException("too many duplicate definitions.");
}
} }
private BasicType lookupOrFail(String typeName) { private BasicType lookupOrFail(String typeName) {
...@@ -740,9 +774,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -740,9 +774,10 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
} }
if (!typeNameIsPointerType(typeName)) { if (!typeNameIsPointerType(typeName)) {
System.err.println("Warning: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " + System.err.println("Warning: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " +
"had its size declared as " + size + " twice. Continuing."); "had its size declared as " + size + " twice. Continuing.");
} duplicateDefCount++;
}
} }
} }
......
...@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2015 ...@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2015
HS_MAJOR_VER=25 HS_MAJOR_VER=25
HS_MINOR_VER=60 HS_MINOR_VER=60
HS_BUILD_NUMBER=06 HS_BUILD_NUMBER=07
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=8 JDK_MINOR_VER=8
......
/* /*
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -41,7 +41,9 @@ ...@@ -41,7 +41,9 @@
* JNI conversion, which should be sorted out later. * JNI conversion, which should be sorted out later.
*/ */
#define __USE_LEGACY_PROTOTYPES__
#include <dirent.h> /* For DIR */ #include <dirent.h> /* For DIR */
#undef __USE_LEGACY_PROTOTYPES__
#include <sys/param.h> /* For MAXPATHLEN */ #include <sys/param.h> /* For MAXPATHLEN */
#include <sys/socket.h> /* For socklen_t */ #include <sys/socket.h> /* For socklen_t */
#include <unistd.h> /* For F_OK, R_OK, W_OK */ #include <unistd.h> /* For F_OK, R_OK, W_OK */
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#define TRACE_BCEA(level, code) #define TRACE_BCEA(level, code)
#endif #endif
// Maintain a map of which aguments a local variable or // Maintain a map of which arguments a local variable or
// stack slot may contain. In addition to tracking // stack slot may contain. In addition to tracking
// arguments, it tracks two special values, "allocated" // arguments, it tracks two special values, "allocated"
// which represents any object allocated in the current // which represents any object allocated in the current
...@@ -318,14 +318,16 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* ...@@ -318,14 +318,16 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod*
bool must_record_dependencies = false; bool must_record_dependencies = false;
for (i = arg_size - 1; i >= 0; i--) { for (i = arg_size - 1; i >= 0; i--) {
ArgumentMap arg = state.raw_pop(); ArgumentMap arg = state.raw_pop();
if (!is_argument(arg)) // Check if callee arg is a caller arg or an allocated object
bool allocated = arg.contains_allocated();
if (!(is_argument(arg) || allocated))
continue; continue;
for (int j = 0; j < _arg_size; j++) { for (int j = 0; j < _arg_size; j++) {
if (arg.contains(j)) { if (arg.contains(j)) {
_arg_modified[j] |= analyzer._arg_modified[i]; _arg_modified[j] |= analyzer._arg_modified[i];
} }
} }
if (!is_arg_stack(arg)) { if (!(is_arg_stack(arg) || allocated)) {
// arguments have already been recognized as escaping // arguments have already been recognized as escaping
} else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) { } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) {
set_method_escape(arg); set_method_escape(arg);
......
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -235,7 +235,7 @@ protected: ...@@ -235,7 +235,7 @@ protected:
* @return the size of the user data. * @return the size of the user data.
*/ */
size_t get_user_size() const { size_t get_user_size() const {
assert(_base_addr, "Not wrapping any memory"); assert(_base_addr != NULL, "Not wrapping any memory");
return get_head_guard()->get_user_size(); return get_head_guard()->get_user_size();
} }
...@@ -245,7 +245,7 @@ protected: ...@@ -245,7 +245,7 @@ protected:
* @return the user data pointer. * @return the user data pointer.
*/ */
u_char* get_user_ptr() const { u_char* get_user_ptr() const {
assert(_base_addr, "Not wrapping any memory"); assert(_base_addr != NULL, "Not wrapping any memory");
return _base_addr + sizeof(GuardHeader); return _base_addr + sizeof(GuardHeader);
} }
...@@ -281,7 +281,7 @@ protected: ...@@ -281,7 +281,7 @@ protected:
memset(get_user_ptr(), ch, get_user_size()); memset(get_user_ptr(), ch, get_user_size());
} }
public: public:
/** /**
* Return the total size required for wrapping the given user size. * Return the total size required for wrapping the given user size.
* *
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -53,6 +53,8 @@ ...@@ -53,6 +53,8 @@
# include "jniTypes_ppc.hpp" # include "jniTypes_ppc.hpp"
#endif #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, // Heap objects are allowed to be directly referenced only in VM code,
// not in native code. // not in native code.
...@@ -168,12 +170,42 @@ static void NativeReportJNIWarning(JavaThread* thr, const char *msg) { ...@@ -168,12 +170,42 @@ static void NativeReportJNIWarning(JavaThread* thr, const char *msg) {
* SUPPORT FUNCTIONS * SUPPORT FUNCTIONS
*/ */
/**
* Check whether or not a programmer has actually checked for exceptions. According
* to the JNI Specification ("jni/spec/design.html#java_exceptions"):
*
* There are two cases where the programmer needs to check for exceptions without
* being able to first check an error code:
*
* - The JNI functions that invoke a Java method return the result of the Java method.
* The programmer must call ExceptionOccurred() to check for possible exceptions
* that occurred during the execution of the Java method.
*
* - Some of the JNI array access functions do not return an error code, but may
* throw an ArrayIndexOutOfBoundsException or ArrayStoreException.
*
* In all other cases, a non-error return value guarantees that no exceptions have been thrown.
*/
static inline void static inline void
functionEnterCritical(JavaThread* thr) check_pending_exception(JavaThread* thr) {
{
if (thr->has_pending_exception()) { if (thr->has_pending_exception()) {
NativeReportJNIWarning(thr, "JNI call made with exception pending"); NativeReportJNIWarning(thr, "JNI call made with exception pending");
} }
if (thr->is_pending_jni_exception_check()) {
IN_VM(
tty->print_cr("WARNING in native method: JNI call made without checking exceptions when required to from %s",
thr->get_pending_jni_exception_check());
thr->print_stack();
)
thr->clear_pending_jni_exception_check(); // Just complain once
}
}
static inline void
functionEnterCritical(JavaThread* thr)
{
check_pending_exception(thr);
} }
static inline void static inline void
...@@ -187,9 +219,7 @@ functionEnter(JavaThread* thr) ...@@ -187,9 +219,7 @@ functionEnter(JavaThread* thr)
if (thr->in_critical()) { if (thr->in_critical()) {
tty->print_cr("%s", warn_other_function_in_critical); tty->print_cr("%s", warn_other_function_in_critical);
} }
if (thr->has_pending_exception()) { check_pending_exception(thr);
NativeReportJNIWarning(thr, "JNI call made with exception pending");
}
} }
static inline void static inline void
...@@ -201,9 +231,20 @@ functionEnterExceptionAllowed(JavaThread* thr) ...@@ -201,9 +231,20 @@ functionEnterExceptionAllowed(JavaThread* thr)
} }
static inline void static inline void
functionExit(JNIEnv *env) functionExit(JavaThread* thr)
{ {
/* nothing to do at this time */ JNIHandleBlock* handles = thr->active_handles();
size_t planned_capacity = handles->get_planned_capacity();
size_t live_handles = handles->get_number_of_live_handles();
if (live_handles > planned_capacity) {
IN_VM(
tty->print_cr("WARNING: JNI local refs: %zu, exceeds capacity: %zu",
live_handles, planned_capacity);
thr->print_stack();
)
// Complain just the once, reset to current + warn threshold
handles->set_planned_capacity(live_handles + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
}
} }
static inline void static inline void
...@@ -508,7 +549,7 @@ JNI_ENTRY_CHECKED(jclass, ...@@ -508,7 +549,7 @@ JNI_ENTRY_CHECKED(jclass,
jniCheck::validate_object(thr, loader); jniCheck::validate_object(thr, loader);
) )
jclass result = UNCHECKED()->DefineClass(env, name, loader, buf, len); jclass result = UNCHECKED()->DefineClass(env, name, loader, buf, len);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -520,7 +561,7 @@ JNI_ENTRY_CHECKED(jclass, ...@@ -520,7 +561,7 @@ JNI_ENTRY_CHECKED(jclass,
jniCheck::validate_class_descriptor(thr, name); jniCheck::validate_class_descriptor(thr, name);
) )
jclass result = UNCHECKED()->FindClass(env, name); jclass result = UNCHECKED()->FindClass(env, name);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -532,7 +573,7 @@ JNI_ENTRY_CHECKED(jmethodID, ...@@ -532,7 +573,7 @@ JNI_ENTRY_CHECKED(jmethodID,
jniCheck::validate_object(thr, method); jniCheck::validate_object(thr, method);
) )
jmethodID result = UNCHECKED()->FromReflectedMethod(env, method); jmethodID result = UNCHECKED()->FromReflectedMethod(env, method);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -544,7 +585,7 @@ JNI_ENTRY_CHECKED(jfieldID, ...@@ -544,7 +585,7 @@ JNI_ENTRY_CHECKED(jfieldID,
jniCheck::validate_object(thr, field); jniCheck::validate_object(thr, field);
) )
jfieldID result = UNCHECKED()->FromReflectedField(env, field); jfieldID result = UNCHECKED()->FromReflectedField(env, field);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -560,7 +601,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -560,7 +601,7 @@ JNI_ENTRY_CHECKED(jobject,
) )
jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID, jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID,
isStatic); isStatic);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -572,7 +613,7 @@ JNI_ENTRY_CHECKED(jclass, ...@@ -572,7 +613,7 @@ JNI_ENTRY_CHECKED(jclass,
jniCheck::validate_class(thr, sub, true); jniCheck::validate_class(thr, sub, true);
) )
jclass result = UNCHECKED()->GetSuperclass(env, sub); jclass result = UNCHECKED()->GetSuperclass(env, sub);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -586,7 +627,7 @@ JNI_ENTRY_CHECKED(jboolean, ...@@ -586,7 +627,7 @@ JNI_ENTRY_CHECKED(jboolean,
jniCheck::validate_class(thr, sup, true); jniCheck::validate_class(thr, sup, true);
) )
jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup); jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -601,7 +642,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -601,7 +642,7 @@ JNI_ENTRY_CHECKED(jobject,
) )
jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID, jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID,
isStatic); isStatic);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -619,7 +660,7 @@ JNI_ENTRY_CHECKED(jint, ...@@ -619,7 +660,7 @@ JNI_ENTRY_CHECKED(jint,
} }
) )
jint result = UNCHECKED()->Throw(env, obj); jint result = UNCHECKED()->Throw(env, obj);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -634,15 +675,16 @@ JNI_ENTRY_CHECKED(jint, ...@@ -634,15 +675,16 @@ JNI_ENTRY_CHECKED(jint,
jniCheck::validate_throwable_klass(thr, k); jniCheck::validate_throwable_klass(thr, k);
) )
jint result = UNCHECKED()->ThrowNew(env, clazz, msg); jint result = UNCHECKED()->ThrowNew(env, clazz, msg);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
JNI_ENTRY_CHECKED(jthrowable, JNI_ENTRY_CHECKED(jthrowable,
checked_jni_ExceptionOccurred(JNIEnv *env)) checked_jni_ExceptionOccurred(JNIEnv *env))
thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr); functionEnterExceptionAllowed(thr);
jthrowable result = UNCHECKED()->ExceptionOccurred(env); jthrowable result = UNCHECKED()->ExceptionOccurred(env);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -650,22 +692,24 @@ JNI_ENTRY_CHECKED(void, ...@@ -650,22 +692,24 @@ JNI_ENTRY_CHECKED(void,
checked_jni_ExceptionDescribe(JNIEnv *env)) checked_jni_ExceptionDescribe(JNIEnv *env))
functionEnterExceptionAllowed(thr); functionEnterExceptionAllowed(thr);
UNCHECKED()->ExceptionDescribe(env); UNCHECKED()->ExceptionDescribe(env);
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
checked_jni_ExceptionClear(JNIEnv *env)) checked_jni_ExceptionClear(JNIEnv *env))
thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr); functionEnterExceptionAllowed(thr);
UNCHECKED()->ExceptionClear(env); UNCHECKED()->ExceptionClear(env);
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
checked_jni_FatalError(JNIEnv *env, checked_jni_FatalError(JNIEnv *env,
const char *msg)) const char *msg))
thr->clear_pending_jni_exception_check();
functionEnter(thr); functionEnter(thr);
UNCHECKED()->FatalError(env, msg); UNCHECKED()->FatalError(env, msg);
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(jint, JNI_ENTRY_CHECKED(jint,
...@@ -675,7 +719,10 @@ JNI_ENTRY_CHECKED(jint, ...@@ -675,7 +719,10 @@ JNI_ENTRY_CHECKED(jint,
if (capacity < 0) if (capacity < 0)
NativeReportJNIFatalError(thr, "negative capacity"); NativeReportJNIFatalError(thr, "negative capacity");
jint result = UNCHECKED()->PushLocalFrame(env, capacity); jint result = UNCHECKED()->PushLocalFrame(env, capacity);
functionExit(env); if (result == JNI_OK) {
thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
}
functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -684,7 +731,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -684,7 +731,7 @@ JNI_ENTRY_CHECKED(jobject,
jobject result)) jobject result))
functionEnterExceptionAllowed(thr); functionEnterExceptionAllowed(thr);
jobject res = UNCHECKED()->PopLocalFrame(env, result); jobject res = UNCHECKED()->PopLocalFrame(env, result);
functionExit(env); functionExit(thr);
return res; return res;
JNI_END JNI_END
...@@ -698,7 +745,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -698,7 +745,7 @@ JNI_ENTRY_CHECKED(jobject,
} }
) )
jobject result = UNCHECKED()->NewGlobalRef(env,lobj); jobject result = UNCHECKED()->NewGlobalRef(env,lobj);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -714,7 +761,7 @@ JNI_ENTRY_CHECKED(void, ...@@ -714,7 +761,7 @@ JNI_ENTRY_CHECKED(void,
} }
) )
UNCHECKED()->DeleteGlobalRef(env,gref); UNCHECKED()->DeleteGlobalRef(env,gref);
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
...@@ -729,7 +776,7 @@ JNI_ENTRY_CHECKED(void, ...@@ -729,7 +776,7 @@ JNI_ENTRY_CHECKED(void,
"Invalid local JNI handle passed to DeleteLocalRef"); "Invalid local JNI handle passed to DeleteLocalRef");
) )
UNCHECKED()->DeleteLocalRef(env, obj); UNCHECKED()->DeleteLocalRef(env, obj);
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(jboolean, JNI_ENTRY_CHECKED(jboolean,
...@@ -750,7 +797,7 @@ JNI_ENTRY_CHECKED(jboolean, ...@@ -750,7 +797,7 @@ JNI_ENTRY_CHECKED(jboolean,
} }
) )
jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2); jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -764,7 +811,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -764,7 +811,7 @@ JNI_ENTRY_CHECKED(jobject,
} }
) )
jobject result = UNCHECKED()->NewLocalRef(env, ref); jobject result = UNCHECKED()->NewLocalRef(env, ref);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -776,7 +823,10 @@ JNI_ENTRY_CHECKED(jint, ...@@ -776,7 +823,10 @@ JNI_ENTRY_CHECKED(jint,
NativeReportJNIFatalError(thr, "negative capacity"); NativeReportJNIFatalError(thr, "negative capacity");
} }
jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity); jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity);
functionExit(env); if (result == JNI_OK) {
thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
}
functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -788,7 +838,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -788,7 +838,7 @@ JNI_ENTRY_CHECKED(jobject,
jniCheck::validate_class(thr, clazz, false); jniCheck::validate_class(thr, clazz, false);
) )
jobject result = UNCHECKED()->AllocObject(env,clazz); jobject result = UNCHECKED()->AllocObject(env,clazz);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -806,7 +856,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -806,7 +856,7 @@ JNI_ENTRY_CHECKED(jobject,
va_start(args, methodID); va_start(args, methodID);
jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
va_end(args); va_end(args);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -821,7 +871,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -821,7 +871,7 @@ JNI_ENTRY_CHECKED(jobject,
jniCheck::validate_jmethod_id(thr, methodID); jniCheck::validate_jmethod_id(thr, methodID);
) )
jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -836,7 +886,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -836,7 +886,7 @@ JNI_ENTRY_CHECKED(jobject,
jniCheck::validate_jmethod_id(thr, methodID); jniCheck::validate_jmethod_id(thr, methodID);
) )
jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args); jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -848,7 +898,7 @@ JNI_ENTRY_CHECKED(jclass, ...@@ -848,7 +898,7 @@ JNI_ENTRY_CHECKED(jclass,
jniCheck::validate_object(thr, obj); jniCheck::validate_object(thr, obj);
) )
jclass result = UNCHECKED()->GetObjectClass(env,obj); jclass result = UNCHECKED()->GetObjectClass(env,obj);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -862,7 +912,7 @@ JNI_ENTRY_CHECKED(jboolean, ...@@ -862,7 +912,7 @@ JNI_ENTRY_CHECKED(jboolean,
jniCheck::validate_class(thr, clazz, true); jniCheck::validate_class(thr, clazz, true);
) )
jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz); jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -876,7 +926,7 @@ JNI_ENTRY_CHECKED(jmethodID, ...@@ -876,7 +926,7 @@ JNI_ENTRY_CHECKED(jmethodID,
jniCheck::validate_class(thr, clazz, false); jniCheck::validate_class(thr, clazz, false);
) )
jmethodID result = UNCHECKED()->GetMethodID(env,clazz,name,sig); jmethodID result = UNCHECKED()->GetMethodID(env,clazz,name,sig);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -895,7 +945,8 @@ JNI_ENTRY_CHECKED(ResultType, \ ...@@ -895,7 +945,8 @@ JNI_ENTRY_CHECKED(ResultType, \
ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \ ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \
args); \ args); \
va_end(args); \ va_end(args); \
functionExit(env); \ thr->set_pending_jni_exception_check("Call"#Result"Method"); \
functionExit(thr); \
return result; \ return result; \
JNI_END \ JNI_END \
\ \
...@@ -910,7 +961,8 @@ JNI_ENTRY_CHECKED(ResultType, \ ...@@ -910,7 +961,8 @@ JNI_ENTRY_CHECKED(ResultType, \
) \ ) \
ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\ ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\
args); \ args); \
functionExit(env); \ thr->set_pending_jni_exception_check("Call"#Result"MethodV"); \
functionExit(thr); \
return result; \ return result; \
JNI_END \ JNI_END \
\ \
...@@ -925,7 +977,8 @@ JNI_ENTRY_CHECKED(ResultType, \ ...@@ -925,7 +977,8 @@ JNI_ENTRY_CHECKED(ResultType, \
) \ ) \
ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\ ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\
args); \ args); \
functionExit(env); \ thr->set_pending_jni_exception_check("Call"#Result"MethodA"); \
functionExit(thr); \
return result; \ return result; \
JNI_END JNI_END
...@@ -952,7 +1005,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -952,7 +1005,8 @@ JNI_ENTRY_CHECKED(void,
va_start(args,methodID); va_start(args,methodID);
UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
va_end(args); va_end(args);
functionExit(env); thr->set_pending_jni_exception_check("CallVoidMethod");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
...@@ -965,7 +1019,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -965,7 +1019,8 @@ JNI_ENTRY_CHECKED(void,
jniCheck::validate_call_object(thr, obj, methodID); jniCheck::validate_call_object(thr, obj, methodID);
) )
UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
functionExit(env); thr->set_pending_jni_exception_check("CallVoidMethodV");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
...@@ -978,7 +1033,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -978,7 +1033,8 @@ JNI_ENTRY_CHECKED(void,
jniCheck::validate_call_object(thr, obj, methodID); jniCheck::validate_call_object(thr, obj, methodID);
) )
UNCHECKED()->CallVoidMethodA(env,obj,methodID,args); UNCHECKED()->CallVoidMethodA(env,obj,methodID,args);
functionExit(env); thr->set_pending_jni_exception_check("CallVoidMethodA");
functionExit(thr);
JNI_END JNI_END
#define WRAPPER_CallNonvirtualMethod(ResultType, Result) \ #define WRAPPER_CallNonvirtualMethod(ResultType, Result) \
...@@ -1001,7 +1057,8 @@ JNI_ENTRY_CHECKED(ResultType, \ ...@@ -1001,7 +1057,8 @@ JNI_ENTRY_CHECKED(ResultType, \
methodID,\ methodID,\
args); \ args); \
va_end(args); \ va_end(args); \
functionExit(env); \ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"Method"); \
functionExit(thr); \
return result; \ return result; \
JNI_END \ JNI_END \
\ \
...@@ -1021,7 +1078,8 @@ JNI_ENTRY_CHECKED(ResultType, \ ...@@ -1021,7 +1078,8 @@ JNI_ENTRY_CHECKED(ResultType, \
clazz, \ clazz, \
methodID,\ methodID,\
args); \ args); \
functionExit(env); \ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodV"); \
functionExit(thr); \
return result; \ return result; \
JNI_END \ JNI_END \
\ \
...@@ -1041,7 +1099,8 @@ JNI_ENTRY_CHECKED(ResultType, \ ...@@ -1041,7 +1099,8 @@ JNI_ENTRY_CHECKED(ResultType, \
clazz, \ clazz, \
methodID,\ methodID,\
args); \ args); \
functionExit(env); \ thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodA"); \
functionExit(thr); \
return result; \ return result; \
JNI_END JNI_END
...@@ -1070,7 +1129,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1070,7 +1129,8 @@ JNI_ENTRY_CHECKED(void,
va_start(args,methodID); va_start(args,methodID);
UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
va_end(args); va_end(args);
functionExit(env); thr->set_pending_jni_exception_check("CallNonvirtualVoidMethod");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
...@@ -1085,7 +1145,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1085,7 +1145,8 @@ JNI_ENTRY_CHECKED(void,
jniCheck::validate_call_class(thr, clazz, methodID); jniCheck::validate_call_class(thr, clazz, methodID);
) )
UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
functionExit(env); thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
...@@ -1100,7 +1161,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1100,7 +1161,8 @@ JNI_ENTRY_CHECKED(void,
jniCheck::validate_call_class(thr, clazz, methodID); jniCheck::validate_call_class(thr, clazz, methodID);
) )
UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args); UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args);
functionExit(env); thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(jfieldID, JNI_ENTRY_CHECKED(jfieldID,
...@@ -1113,7 +1175,7 @@ JNI_ENTRY_CHECKED(jfieldID, ...@@ -1113,7 +1175,7 @@ JNI_ENTRY_CHECKED(jfieldID,
jniCheck::validate_class(thr, clazz, false); jniCheck::validate_class(thr, clazz, false);
) )
jfieldID result = UNCHECKED()->GetFieldID(env,clazz,name,sig); jfieldID result = UNCHECKED()->GetFieldID(env,clazz,name,sig);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1127,7 +1189,7 @@ JNI_ENTRY_CHECKED(ReturnType, \ ...@@ -1127,7 +1189,7 @@ JNI_ENTRY_CHECKED(ReturnType, \
checkInstanceFieldID(thr, fieldID, obj, FieldType); \ checkInstanceFieldID(thr, fieldID, obj, FieldType); \
) \ ) \
ReturnType result = UNCHECKED()->Get##Result##Field(env,obj,fieldID); \ ReturnType result = UNCHECKED()->Get##Result##Field(env,obj,fieldID); \
functionExit(env); \ functionExit(thr); \
return result; \ return result; \
JNI_END JNI_END
...@@ -1152,7 +1214,7 @@ JNI_ENTRY_CHECKED(void, \ ...@@ -1152,7 +1214,7 @@ JNI_ENTRY_CHECKED(void, \
checkInstanceFieldID(thr, fieldID, obj, FieldType); \ checkInstanceFieldID(thr, fieldID, obj, FieldType); \
) \ ) \
UNCHECKED()->Set##Result##Field(env,obj,fieldID,val); \ UNCHECKED()->Set##Result##Field(env,obj,fieldID,val); \
functionExit(env); \ functionExit(thr); \
JNI_END JNI_END
WRAPPER_SetField(jobject, Object, T_OBJECT) WRAPPER_SetField(jobject, Object, T_OBJECT)
...@@ -1176,7 +1238,7 @@ JNI_ENTRY_CHECKED(jmethodID, ...@@ -1176,7 +1238,7 @@ JNI_ENTRY_CHECKED(jmethodID,
jniCheck::validate_class(thr, clazz, false); jniCheck::validate_class(thr, clazz, false);
) )
jmethodID result = UNCHECKED()->GetStaticMethodID(env,clazz,name,sig); jmethodID result = UNCHECKED()->GetStaticMethodID(env,clazz,name,sig);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1198,7 +1260,8 @@ JNI_ENTRY_CHECKED(ReturnType, \ ...@@ -1198,7 +1260,8 @@ JNI_ENTRY_CHECKED(ReturnType, \
methodID, \ methodID, \
args); \ args); \
va_end(args); \ va_end(args); \
functionExit(env); \ thr->set_pending_jni_exception_check("CallStatic"#Result"Method"); \
functionExit(thr); \
return result; \ return result; \
JNI_END \ JNI_END \
\ \
...@@ -1216,7 +1279,8 @@ JNI_ENTRY_CHECKED(ReturnType, \ ...@@ -1216,7 +1279,8 @@ JNI_ENTRY_CHECKED(ReturnType, \
clazz, \ clazz, \
methodID, \ methodID, \
args); \ args); \
functionExit(env); \ thr->set_pending_jni_exception_check("CallStatic"#Result"MethodV"); \
functionExit(thr); \
return result; \ return result; \
JNI_END \ JNI_END \
\ \
...@@ -1234,7 +1298,8 @@ JNI_ENTRY_CHECKED(ReturnType, \ ...@@ -1234,7 +1298,8 @@ JNI_ENTRY_CHECKED(ReturnType, \
clazz, \ clazz, \
methodID, \ methodID, \
args); \ args); \
functionExit(env); \ thr->set_pending_jni_exception_check("CallStatic"#Result"MethodA"); \
functionExit(thr); \
return result; \ return result; \
JNI_END JNI_END
...@@ -1262,7 +1327,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1262,7 +1327,8 @@ JNI_ENTRY_CHECKED(void,
va_start(args,methodID); va_start(args,methodID);
UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
va_end(args); va_end(args);
functionExit(env); thr->set_pending_jni_exception_check("CallStaticVoidMethod");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
...@@ -1276,7 +1342,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1276,7 +1342,8 @@ JNI_ENTRY_CHECKED(void,
jniCheck::validate_class(thr, cls, false); jniCheck::validate_class(thr, cls, false);
) )
UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
functionExit(env); thr->set_pending_jni_exception_check("CallStaticVoidMethodV");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
...@@ -1290,7 +1357,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1290,7 +1357,8 @@ JNI_ENTRY_CHECKED(void,
jniCheck::validate_class(thr, cls, false); jniCheck::validate_class(thr, cls, false);
) )
UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args); UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args);
functionExit(env); thr->set_pending_jni_exception_check("CallStaticVoidMethodA");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(jfieldID, JNI_ENTRY_CHECKED(jfieldID,
...@@ -1303,7 +1371,7 @@ JNI_ENTRY_CHECKED(jfieldID, ...@@ -1303,7 +1371,7 @@ JNI_ENTRY_CHECKED(jfieldID,
jniCheck::validate_class(thr, clazz, false); jniCheck::validate_class(thr, clazz, false);
) )
jfieldID result = UNCHECKED()->GetStaticFieldID(env,clazz,name,sig); jfieldID result = UNCHECKED()->GetStaticFieldID(env,clazz,name,sig);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1320,7 +1388,7 @@ JNI_ENTRY_CHECKED(ReturnType, \ ...@@ -1320,7 +1388,7 @@ JNI_ENTRY_CHECKED(ReturnType, \
ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \ ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \
clazz, \ clazz, \
fieldID); \ fieldID); \
functionExit(env); \ functionExit(thr); \
return result; \ return result; \
JNI_END JNI_END
...@@ -1346,7 +1414,7 @@ JNI_ENTRY_CHECKED(void, \ ...@@ -1346,7 +1414,7 @@ JNI_ENTRY_CHECKED(void, \
checkStaticFieldID(thr, fieldID, clazz, FieldType); \ checkStaticFieldID(thr, fieldID, clazz, FieldType); \
) \ ) \
UNCHECKED()->SetStatic##Result##Field(env,clazz,fieldID,value); \ UNCHECKED()->SetStatic##Result##Field(env,clazz,fieldID,value); \
functionExit(env); \ functionExit(thr); \
JNI_END JNI_END
WRAPPER_SetStaticField(jobject, Object, T_OBJECT) WRAPPER_SetStaticField(jobject, Object, T_OBJECT)
...@@ -1366,7 +1434,7 @@ JNI_ENTRY_CHECKED(jstring, ...@@ -1366,7 +1434,7 @@ JNI_ENTRY_CHECKED(jstring,
jsize len)) jsize len))
functionEnter(thr); functionEnter(thr);
jstring result = UNCHECKED()->NewString(env,unicode,len); jstring result = UNCHECKED()->NewString(env,unicode,len);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1378,7 +1446,7 @@ JNI_ENTRY_CHECKED(jsize, ...@@ -1378,7 +1446,7 @@ JNI_ENTRY_CHECKED(jsize,
checkString(thr, str); checkString(thr, str);
) )
jsize result = UNCHECKED()->GetStringLength(env,str); jsize result = UNCHECKED()->GetStringLength(env,str);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1407,7 +1475,7 @@ JNI_ENTRY_CHECKED(const jchar *, ...@@ -1407,7 +1475,7 @@ JNI_ENTRY_CHECKED(const jchar *,
// Note that the dtrace arguments for the allocated memory will not match up with this solution. // Note that the dtrace arguments for the allocated memory will not match up with this solution.
FreeHeap((char*)result); FreeHeap((char*)result);
} }
functionExit(env); functionExit(thr);
return new_result; return new_result;
JNI_END JNI_END
...@@ -1442,7 +1510,7 @@ JNI_ENTRY_CHECKED(void, ...@@ -1442,7 +1510,7 @@ JNI_ENTRY_CHECKED(void,
UNCHECKED()->ReleaseStringChars(env, str, UNCHECKED()->ReleaseStringChars(env, str,
(const jchar*) guarded.release_for_freeing()); (const jchar*) guarded.release_for_freeing());
} }
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(jstring, JNI_ENTRY_CHECKED(jstring,
...@@ -1450,7 +1518,7 @@ JNI_ENTRY_CHECKED(jstring, ...@@ -1450,7 +1518,7 @@ JNI_ENTRY_CHECKED(jstring,
const char *utf)) const char *utf))
functionEnter(thr); functionEnter(thr);
jstring result = UNCHECKED()->NewStringUTF(env,utf); jstring result = UNCHECKED()->NewStringUTF(env,utf);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1462,7 +1530,7 @@ JNI_ENTRY_CHECKED(jsize, ...@@ -1462,7 +1530,7 @@ JNI_ENTRY_CHECKED(jsize,
checkString(thr, str); checkString(thr, str);
) )
jsize result = UNCHECKED()->GetStringUTFLength(env,str); jsize result = UNCHECKED()->GetStringUTFLength(env,str);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1490,7 +1558,7 @@ JNI_ENTRY_CHECKED(const char *, ...@@ -1490,7 +1558,7 @@ JNI_ENTRY_CHECKED(const char *,
// Note that the dtrace arguments for the allocated memory will not match up with this solution. // Note that the dtrace arguments for the allocated memory will not match up with this solution.
FreeHeap((char*)result, mtInternal); FreeHeap((char*)result, mtInternal);
} }
functionExit(env); functionExit(thr);
return new_result; return new_result;
JNI_END JNI_END
...@@ -1525,7 +1593,7 @@ JNI_ENTRY_CHECKED(void, ...@@ -1525,7 +1593,7 @@ JNI_ENTRY_CHECKED(void,
UNCHECKED()->ReleaseStringUTFChars(env, str, UNCHECKED()->ReleaseStringUTFChars(env, str,
(const char*) guarded.release_for_freeing()); (const char*) guarded.release_for_freeing());
} }
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(jsize, JNI_ENTRY_CHECKED(jsize,
...@@ -1536,7 +1604,7 @@ JNI_ENTRY_CHECKED(jsize, ...@@ -1536,7 +1604,7 @@ JNI_ENTRY_CHECKED(jsize,
check_is_array(thr, array); check_is_array(thr, array);
) )
jsize result = UNCHECKED()->GetArrayLength(env,array); jsize result = UNCHECKED()->GetArrayLength(env,array);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1547,7 +1615,7 @@ JNI_ENTRY_CHECKED(jobjectArray, ...@@ -1547,7 +1615,7 @@ JNI_ENTRY_CHECKED(jobjectArray,
jobject init)) jobject init))
functionEnter(thr); functionEnter(thr);
jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init); jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1560,7 +1628,8 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -1560,7 +1628,8 @@ JNI_ENTRY_CHECKED(jobject,
check_is_obj_array(thr, array); check_is_obj_array(thr, array);
) )
jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index); jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
functionExit(env); thr->set_pending_jni_exception_check("GetObjectArrayElement");
functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1574,7 +1643,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1574,7 +1643,8 @@ JNI_ENTRY_CHECKED(void,
check_is_obj_array(thr, array); check_is_obj_array(thr, array);
) )
UNCHECKED()->SetObjectArrayElement(env,array,index,val); UNCHECKED()->SetObjectArrayElement(env,array,index,val);
functionExit(env); thr->set_pending_jni_exception_check("SetObjectArrayElement");
functionExit(thr);
JNI_END JNI_END
#define WRAPPER_NewScalarArray(Return, Result) \ #define WRAPPER_NewScalarArray(Return, Result) \
...@@ -1583,7 +1653,7 @@ JNI_ENTRY_CHECKED(Return, \ ...@@ -1583,7 +1653,7 @@ JNI_ENTRY_CHECKED(Return, \
jsize len)) \ jsize len)) \
functionEnter(thr); \ functionEnter(thr); \
Return result = UNCHECKED()->New##Result##Array(env,len); \ Return result = UNCHECKED()->New##Result##Array(env,len); \
functionExit(env); \ functionExit(thr); \
return (Return) result; \ return (Return) result; \
JNI_END JNI_END
...@@ -1611,7 +1681,7 @@ JNI_ENTRY_CHECKED(ElementType *, \ ...@@ -1611,7 +1681,7 @@ JNI_ENTRY_CHECKED(ElementType *, \
if (result != NULL) { \ if (result != NULL) { \
result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \ result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \
} \ } \
functionExit(env); \ functionExit(thr); \
return result; \ return result; \
JNI_END JNI_END
...@@ -1639,7 +1709,7 @@ JNI_ENTRY_CHECKED(void, \ ...@@ -1639,7 +1709,7 @@ JNI_ENTRY_CHECKED(void, \
ElementType* orig_result = (ElementType *) check_wrapped_array_release( \ ElementType* orig_result = (ElementType *) check_wrapped_array_release( \
thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode); \ thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode); \
UNCHECKED()->Release##Result##ArrayElements(env, array, orig_result, mode); \ UNCHECKED()->Release##Result##ArrayElements(env, array, orig_result, mode); \
functionExit(env); \ functionExit(thr); \
JNI_END JNI_END
WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool) WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool)
...@@ -1663,7 +1733,8 @@ JNI_ENTRY_CHECKED(void, \ ...@@ -1663,7 +1733,8 @@ JNI_ENTRY_CHECKED(void, \
check_primitive_array_type(thr, array, ElementTag); \ check_primitive_array_type(thr, array, ElementTag); \
) \ ) \
UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \ UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \
functionExit(env); \ thr->set_pending_jni_exception_check("Get"#Result"ArrayRegion"); \
functionExit(thr); \
JNI_END JNI_END
WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
...@@ -1687,7 +1758,8 @@ JNI_ENTRY_CHECKED(void, \ ...@@ -1687,7 +1758,8 @@ JNI_ENTRY_CHECKED(void, \
check_primitive_array_type(thr, array, ElementTag); \ check_primitive_array_type(thr, array, ElementTag); \
) \ ) \
UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \ UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \
functionExit(env); \ thr->set_pending_jni_exception_check("Set"#Result"ArrayRegion"); \
functionExit(thr); \
JNI_END JNI_END
WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean)
...@@ -1706,7 +1778,7 @@ JNI_ENTRY_CHECKED(jint, ...@@ -1706,7 +1778,7 @@ JNI_ENTRY_CHECKED(jint,
jint nMethods)) jint nMethods))
functionEnter(thr); functionEnter(thr);
jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods); jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1715,7 +1787,7 @@ JNI_ENTRY_CHECKED(jint, ...@@ -1715,7 +1787,7 @@ JNI_ENTRY_CHECKED(jint,
jclass clazz)) jclass clazz))
functionEnter(thr); functionEnter(thr);
jint result = UNCHECKED()->UnregisterNatives(env,clazz); jint result = UNCHECKED()->UnregisterNatives(env,clazz);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1727,7 +1799,7 @@ JNI_ENTRY_CHECKED(jint, ...@@ -1727,7 +1799,7 @@ JNI_ENTRY_CHECKED(jint,
jniCheck::validate_object(thr, obj); jniCheck::validate_object(thr, obj);
) )
jint result = UNCHECKED()->MonitorEnter(env,obj); jint result = UNCHECKED()->MonitorEnter(env,obj);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1739,7 +1811,7 @@ JNI_ENTRY_CHECKED(jint, ...@@ -1739,7 +1811,7 @@ JNI_ENTRY_CHECKED(jint,
jniCheck::validate_object(thr, obj); jniCheck::validate_object(thr, obj);
) )
jint result = UNCHECKED()->MonitorExit(env,obj); jint result = UNCHECKED()->MonitorExit(env,obj);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1748,7 +1820,7 @@ JNI_ENTRY_CHECKED(jint, ...@@ -1748,7 +1820,7 @@ JNI_ENTRY_CHECKED(jint,
JavaVM **vm)) JavaVM **vm))
functionEnter(thr); functionEnter(thr);
jint result = UNCHECKED()->GetJavaVM(env,vm); jint result = UNCHECKED()->GetJavaVM(env,vm);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1763,7 +1835,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1763,7 +1835,8 @@ JNI_ENTRY_CHECKED(void,
checkString(thr, str); checkString(thr, str);
) )
UNCHECKED()->GetStringRegion(env, str, start, len, buf); UNCHECKED()->GetStringRegion(env, str, start, len, buf);
functionExit(env); thr->set_pending_jni_exception_check("GetStringRegion");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void, JNI_ENTRY_CHECKED(void,
...@@ -1777,7 +1850,8 @@ JNI_ENTRY_CHECKED(void, ...@@ -1777,7 +1850,8 @@ JNI_ENTRY_CHECKED(void,
checkString(thr, str); checkString(thr, str);
) )
UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf); UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
functionExit(env); thr->set_pending_jni_exception_check("GetStringUTFRegion");
functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(void *, JNI_ENTRY_CHECKED(void *,
...@@ -1792,7 +1866,7 @@ JNI_ENTRY_CHECKED(void *, ...@@ -1792,7 +1866,7 @@ JNI_ENTRY_CHECKED(void *,
if (result != NULL) { if (result != NULL) {
result = check_jni_wrap_copy_array(thr, array, result); result = check_jni_wrap_copy_array(thr, array, result);
} }
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1808,7 +1882,7 @@ JNI_ENTRY_CHECKED(void, ...@@ -1808,7 +1882,7 @@ JNI_ENTRY_CHECKED(void,
// Check the element array... // Check the element array...
void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical", array, carray, mode); void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical", array, carray, mode);
UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode); UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode);
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(const jchar*, JNI_ENTRY_CHECKED(const jchar*,
...@@ -1820,7 +1894,7 @@ JNI_ENTRY_CHECKED(const jchar*, ...@@ -1820,7 +1894,7 @@ JNI_ENTRY_CHECKED(const jchar*,
checkString(thr, string); checkString(thr, string);
) )
const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy); const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1836,7 +1910,7 @@ JNI_ENTRY_CHECKED(void, ...@@ -1836,7 +1910,7 @@ JNI_ENTRY_CHECKED(void,
* string parameter as a minor sanity check * string parameter as a minor sanity check
*/ */
UNCHECKED()->ReleaseStringCritical(env, str, chars); UNCHECKED()->ReleaseStringCritical(env, str, chars);
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(jweak, JNI_ENTRY_CHECKED(jweak,
...@@ -1849,7 +1923,7 @@ JNI_ENTRY_CHECKED(jweak, ...@@ -1849,7 +1923,7 @@ JNI_ENTRY_CHECKED(jweak,
} }
) )
jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj); jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1858,14 +1932,15 @@ JNI_ENTRY_CHECKED(void, ...@@ -1858,14 +1932,15 @@ JNI_ENTRY_CHECKED(void,
jweak ref)) jweak ref))
functionEnterExceptionAllowed(thr); functionEnterExceptionAllowed(thr);
UNCHECKED()->DeleteWeakGlobalRef(env, ref); UNCHECKED()->DeleteWeakGlobalRef(env, ref);
functionExit(env); functionExit(thr);
JNI_END JNI_END
JNI_ENTRY_CHECKED(jboolean, JNI_ENTRY_CHECKED(jboolean,
checked_jni_ExceptionCheck(JNIEnv *env)) checked_jni_ExceptionCheck(JNIEnv *env))
thr->clear_pending_jni_exception_check();
functionEnterExceptionAllowed(thr); functionEnterExceptionAllowed(thr);
jboolean result = UNCHECKED()->ExceptionCheck(env); jboolean result = UNCHECKED()->ExceptionCheck(env);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1875,7 +1950,7 @@ JNI_ENTRY_CHECKED(jobject, ...@@ -1875,7 +1950,7 @@ JNI_ENTRY_CHECKED(jobject,
jlong capacity)) jlong capacity))
functionEnter(thr); functionEnter(thr);
jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity); jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1884,7 +1959,7 @@ JNI_ENTRY_CHECKED(void *, ...@@ -1884,7 +1959,7 @@ JNI_ENTRY_CHECKED(void *,
jobject buf)) jobject buf))
functionEnter(thr); functionEnter(thr);
void* result = UNCHECKED()->GetDirectBufferAddress(env, buf); void* result = UNCHECKED()->GetDirectBufferAddress(env, buf);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1893,7 +1968,7 @@ JNI_ENTRY_CHECKED(jlong, ...@@ -1893,7 +1968,7 @@ JNI_ENTRY_CHECKED(jlong,
jobject buf)) jobject buf))
functionEnter(thr); functionEnter(thr);
jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf); jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1906,7 +1981,7 @@ JNI_ENTRY_CHECKED(jobjectRefType, ...@@ -1906,7 +1981,7 @@ JNI_ENTRY_CHECKED(jobjectRefType,
jniCheck::validate_object(thr, obj); jniCheck::validate_object(thr, obj);
) )
jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj); jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
...@@ -1915,7 +1990,7 @@ JNI_ENTRY_CHECKED(jint, ...@@ -1915,7 +1990,7 @@ JNI_ENTRY_CHECKED(jint,
checked_jni_GetVersion(JNIEnv *env)) checked_jni_GetVersion(JNIEnv *env))
functionEnter(thr); functionEnter(thr);
jint result = UNCHECKED()->GetVersion(env); jint result = UNCHECKED()->GetVersion(env);
functionExit(env); functionExit(thr);
return result; return result;
JNI_END JNI_END
......
/* /*
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -296,6 +296,7 @@ JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) { ...@@ -296,6 +296,7 @@ JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) {
block->_top = 0; block->_top = 0;
block->_next = NULL; block->_next = NULL;
block->_pop_frame_link = NULL; block->_pop_frame_link = NULL;
block->_planned_capacity = block_size_in_oops;
// _last, _free_list & _allocate_before_rebuild initialized in allocate_handle // _last, _free_list & _allocate_before_rebuild initialized in allocate_handle
debug_only(block->_last = NULL); debug_only(block->_last = NULL);
debug_only(block->_free_list = NULL); debug_only(block->_free_list = NULL);
...@@ -529,6 +530,12 @@ int JNIHandleBlock::length() const { ...@@ -529,6 +530,12 @@ int JNIHandleBlock::length() const {
return result; return result;
} }
const size_t JNIHandleBlock::get_number_of_live_handles() {
CountHandleClosure counter;
oops_do(&counter);
return counter.count();
}
// This method is not thread-safe, i.e., must be called whule holding a lock on the // This method is not thread-safe, i.e., must be called whule holding a lock on the
// structure. // structure.
long JNIHandleBlock::memory_usage() const { long JNIHandleBlock::memory_usage() const {
......
/* /*
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -112,6 +112,9 @@ class JNIHandleBlock : public CHeapObj<mtInternal> { ...@@ -112,6 +112,9 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
oop* _free_list; // Handle free list oop* _free_list; // Handle free list
int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list
// Check JNI, "planned capacity" for current frame (or push/ensure)
size_t _planned_capacity;
#ifndef PRODUCT #ifndef PRODUCT
JNIHandleBlock* _block_list_link; // Link for list below JNIHandleBlock* _block_list_link; // Link for list below
static JNIHandleBlock* _block_list; // List of all allocated blocks (for debugging only) static JNIHandleBlock* _block_list; // List of all allocated blocks (for debugging only)
...@@ -152,6 +155,11 @@ class JNIHandleBlock : public CHeapObj<mtInternal> { ...@@ -152,6 +155,11 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
// Traversal of weak handles. Unreachable oops are cleared. // Traversal of weak handles. Unreachable oops are cleared.
void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f); void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
// Checked JNI support
void set_planned_capacity(size_t planned_capacity) { _planned_capacity = planned_capacity; }
const size_t get_planned_capacity() { return _planned_capacity; }
const size_t get_number_of_live_handles();
// Debugging // Debugging
bool chain_contains(jobject handle) const; // Does this block or following blocks contain handle bool chain_contains(jobject handle) const; // Does this block or following blocks contain handle
bool contains(jobject handle) const; // Does this block contain handle bool contains(jobject handle) const; // Does this block contain handle
......
/* /*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1465,6 +1465,7 @@ void JavaThread::initialize() { ...@@ -1465,6 +1465,7 @@ void JavaThread::initialize() {
_thread_stat = new ThreadStatistics(); _thread_stat = new ThreadStatistics();
_blocked_on_compilation = false; _blocked_on_compilation = false;
_jni_active_critical = 0; _jni_active_critical = 0;
_pending_jni_exception_check_fn = NULL;
_do_not_unlock_if_synchronized = false; _do_not_unlock_if_synchronized = false;
_cached_monitor_info = NULL; _cached_monitor_info = NULL;
_parker = Parker::Allocate(this) ; _parker = Parker::Allocate(this) ;
......
/* /*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -926,6 +926,9 @@ class JavaThread: public Thread { ...@@ -926,6 +926,9 @@ class JavaThread: public Thread {
// support for JNI critical regions // support for JNI critical regions
jint _jni_active_critical; // count of entries into JNI critical region jint _jni_active_critical; // count of entries into JNI critical region
// Checked JNI: function name requires exception check
char* _pending_jni_exception_check_fn;
// For deadlock detection. // For deadlock detection.
int _depth_first_number; int _depth_first_number;
...@@ -1408,6 +1411,12 @@ class JavaThread: public Thread { ...@@ -1408,6 +1411,12 @@ class JavaThread: public Thread {
assert(_jni_active_critical >= 0, assert(_jni_active_critical >= 0,
"JNI critical nesting problem?"); } "JNI critical nesting problem?"); }
// Checked JNI, is the programmer required to check for exceptions, specify which function name
bool is_pending_jni_exception_check() const { return _pending_jni_exception_check_fn != NULL; }
void clear_pending_jni_exception_check() { _pending_jni_exception_check_fn = NULL; }
const char* get_pending_jni_exception_check() const { return _pending_jni_exception_check_fn; }
void set_pending_jni_exception_check(const char* fn_name) { _pending_jni_exception_check_fn = (char*) fn_name; }
// For deadlock detection // For deadlock detection
int depth_first_number() { return _depth_first_number; } int depth_first_number() { return _depth_first_number; }
void set_depth_first_number(int dfn) { _depth_first_number = dfn; } void set_depth_first_number(int dfn) { _depth_first_number = dfn; }
......
/* /*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,7 +33,9 @@ ...@@ -33,7 +33,9 @@
# include <ctype.h> # include <ctype.h>
#define __USE_LEGACY_PROTOTYPES__
# include <dirent.h> # include <dirent.h>
#undef __USE_LEGACY_PROTOTYPES__
# include <string.h> # include <string.h>
# include <strings.h> // for bsd'isms # include <strings.h> // for bsd'isms
# include <stdarg.h> # include <stdarg.h>
......
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8073956
* @summary Tests C2 EA with allocated object escaping through a call.
* @run main/othervm -XX:CompileCommand=dontinline,TestEscapeThroughInvoke::create TestEscapeThroughInvoke
*/
public class TestEscapeThroughInvoke {
private A a;
public static void main(String[] args) {
TestEscapeThroughInvoke test = new TestEscapeThroughInvoke();
test.a = new A(42);
// Make sure run gets compiled by C2
for (int i = 0; i < 100_000; ++i) {
test.run();
}
}
private void run() {
// Allocate something to trigger EA
new Object();
// Create a new escaping instance of A and
// verify that it is always equal to 'a.saved'.
A escapingA = create(42);
a.check(escapingA);
}
// Create and return a new instance of A that escaped through 'A::saveInto'.
// The 'dummy' parameters are needed to avoid EA skipping the methods.
private A create(Integer dummy) {
A result = new A(dummy);
result.saveInto(a, dummy); // result escapes into 'a' here
return result;
}
}
class A {
private A saved;
public A(Integer dummy) { }
public void saveInto(A other, Integer dummy) {
other.saved = this;
}
public void check(A other) {
if (this.saved != other) {
throw new RuntimeException("TEST FAILED: Objects not equal.");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册