--- a/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -22,6 +22,9 @@
*
*/
+// Disable CRT security warning against strcpy/strcat
+#pragma warning(disable: 4996)
+
// this is source code windbg based SA debugger agent to debug
// Dr. Watson dump files and process snapshots.
--- a/hotspot/agent/src/share/native/sadis.c Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/agent/src/share/native/sadis.c Mon Dec 22 17:40:46 2014 +0000
@@ -33,6 +33,8 @@
*/
#ifdef _WINDOWS
+// Disable CRT security warning against _snprintf
+#pragma warning (disable : 4996)
#define snprintf _snprintf
#define vsnprintf _vsnprintf
@@ -90,12 +92,8 @@
if (errno != 0)
{
/* C runtime error that has no corresponding DOS error code */
- const char *s = strerror(errno);
- size_t n = strlen(s);
- if (n >= len) n = len - 1;
- strncpy(buf, s, n);
- buf[n] = '\0';
- return (int)n;
+ strerror_s(buf, len, errno);
+ return strlen(buf);
}
return 0;
}
@@ -111,16 +109,30 @@
jstring jrepath_s,
jstring libname_s) {
uintptr_t func = 0;
- const char* error_message = NULL;
- jboolean isCopy;
+ const char *error_message = NULL;
+ const char *jrepath = NULL;
+ const char *libname = NULL;
+ char buffer[128];
+
+#ifdef _WINDOWS
+ HINSTANCE hsdis_handle = (HINSTANCE) NULL;
+#else
+ void* hsdis_handle = NULL;
+#endif
- const char * jrepath = (*env)->GetStringUTFChars(env, jrepath_s, &isCopy); // like $JAVA_HOME/jre/lib/sparc/
- const char * libname = (*env)->GetStringUTFChars(env, libname_s, &isCopy);
- char buffer[128];
+ jrepath = (*env)->GetStringUTFChars(env, jrepath_s, NULL); // like $JAVA_HOME/jre/lib/sparc/
+ if (jrepath == NULL || (*env)->ExceptionOccurred(env)) {
+ return 0;
+ }
+
+ libname = (*env)->GetStringUTFChars(env, libname_s, NULL);
+ if (libname == NULL || (*env)->ExceptionOccurred(env)) {
+ (*env)->ReleaseStringUTFChars(env, jrepath_s, jrepath);
+ return 0;
+ }
/* Load the hsdis library */
#ifdef _WINDOWS
- HINSTANCE hsdis_handle;
hsdis_handle = LoadLibrary(libname);
if (hsdis_handle == NULL) {
snprintf(buffer, sizeof(buffer), "%s%s", jrepath, libname);
@@ -134,7 +146,6 @@
error_message = buffer;
}
#else
- void* hsdis_handle;
hsdis_handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL);
if (hsdis_handle == NULL) {
snprintf(buffer, sizeof(buffer), "%s%s", jrepath, libname);
@@ -156,6 +167,11 @@
* platform dependent error message.
*/
jclass eclass = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException");
+ if ((*env)->ExceptionOccurred(env)) {
+ /* Can't throw exception, probably OOM, so silently return 0 */
+ return (jlong) 0;
+ }
+
(*env)->ThrowNew(env, eclass, error_message);
}
return (jlong)func;
@@ -184,16 +200,22 @@
/* event callback binding to Disassembler.handleEvent */
static void* event_to_env(void* env_pv, const char* event, void* arg) {
+ jlong result = 0;
decode_env* denv = (decode_env*)env_pv;
JNIEnv* env = denv->env;
jstring event_string = (*env)->NewStringUTF(env, event);
- jlong result = (*env)->CallLongMethod(env, denv->dis, denv->handle_event, denv->visitor,
- event_string, (jlong) (uintptr_t)arg);
- if ((*env)->ExceptionOccurred(env) != NULL) {
+ if ((*env)->ExceptionOccurred(env)) {
+ return NULL;
+ }
+
+ result = (*env)->CallLongMethod(env, denv->dis, denv->handle_event, denv->visitor,
+ event_string, (jlong) (uintptr_t)arg);
+ if ((*env)->ExceptionOccurred(env)) {
/* ignore exceptions for now */
(*env)->ExceptionClear(env);
- result = 0;
+ return NULL;
}
+
return (void*)(uintptr_t)result;
}
@@ -219,10 +241,13 @@
}
if (raw != NULL) {
jstring output = (*env)->NewStringUTF(env, raw);
- (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output);
- if ((*env)->ExceptionOccurred(env) != NULL) {
+ if (!(*env)->ExceptionOccurred(env)) {
+ /* make sure that UTF allocation doesn't cause OOM */
+ (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output);
+ }
+ if ((*env)->ExceptionOccurred(env)) {
/* ignore exceptions for now */
- (*env)->ExceptionClear(env);
+ (*env)->ExceptionClear(env);
}
return (int) flen;
}
@@ -231,11 +256,16 @@
va_end(ap);
output = (*env)->NewStringUTF(env, denv->buffer);
- (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output);
- if ((*env)->ExceptionOccurred(env) != NULL) {
+ if (!(*env)->ExceptionOccurred(env)) {
+ /* make sure that UTF allocation doesn't cause OOM */
+ (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output);
+ }
+
+ if ((*env)->ExceptionOccurred(env)) {
/* ignore exceptions for now */
(*env)->ExceptionClear(env);
}
+
return cnt;
}
@@ -251,13 +281,24 @@
jbyteArray code,
jstring options_s,
jlong decode_instructions_virtual) {
- jboolean isCopy;
- jbyte* start = (*env)->GetByteArrayElements(env, code, &isCopy);
- jbyte* end = start + (*env)->GetArrayLength(env, code);
- const char * options = (*env)->GetStringUTFChars(env, options_s, &isCopy);
- jclass disclass = (*env)->GetObjectClass(env, dis);
+ jbyte *start = NULL;
+ jbyte *end = NULL;
+ jclass disclass = NULL;
+ const char *options = NULL;
+ decode_env denv;
- decode_env denv;
+ start = (*env)->GetByteArrayElements(env, code, NULL);
+ if ((*env)->ExceptionOccurred(env)) {
+ return;
+ }
+ end = start + (*env)->GetArrayLength(env, code);
+ options = (*env)->GetStringUTFChars(env, options_s, NULL);
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT);
+ return;
+ }
+ disclass = (*env)->GetObjectClass(env, dis);
+
denv.env = env;
denv.dis = dis;
denv.visitor = visitor;
@@ -266,6 +307,8 @@
denv.handle_event = (*env)->GetMethodID(env, disclass, "handleEvent",
"(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;J)J");
if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT);
+ (*env)->ReleaseStringUTFChars(env, options_s, options);
return;
}
@@ -273,11 +316,13 @@
denv.raw_print = (*env)->GetMethodID(env, disclass, "rawPrint",
"(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;)V");
if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT);
+ (*env)->ReleaseStringUTFChars(env, options_s, options);
return;
}
/* decode the buffer */
- (*(decode_func)(uintptr_t)decode_instructions_virtual)(startPc,
+ (*(decode_func)(uintptr_t)decode_instructions_virtual)((uintptr_t) startPc,
startPc + end - start,
(unsigned char*)start,
end - start,
--- a/hotspot/make/aix/makefiles/mapfile-vers-debug Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/aix/makefiles/mapfile-vers-debug Mon Dec 22 17:40:46 2014 +0000
@@ -72,7 +72,6 @@
JVM_FillInStackTrace;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
- JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
JVM_FindLibraryEntry;
JVM_FindLoadedClass;
--- a/hotspot/make/aix/makefiles/mapfile-vers-product Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/aix/makefiles/mapfile-vers-product Mon Dec 22 17:40:46 2014 +0000
@@ -72,7 +72,6 @@
JVM_FillInStackTrace;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
- JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
JVM_FindLibraryEntry;
JVM_FindLoadedClass;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Mon Dec 22 17:40:46 2014 +0000
@@ -70,7 +70,6 @@
_JVM_FillInStackTrace
_JVM_FindClassFromCaller
_JVM_FindClassFromClass
- _JVM_FindClassFromClassLoader
_JVM_FindClassFromBootLoader
_JVM_FindLibraryEntry
_JVM_FindLoadedClass
--- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Mon Dec 22 17:40:46 2014 +0000
@@ -70,7 +70,6 @@
_JVM_FillInStackTrace
_JVM_FindClassFromCaller
_JVM_FindClassFromClass
- _JVM_FindClassFromClassLoader
_JVM_FindClassFromBootLoader
_JVM_FindLibraryEntry
_JVM_FindLoadedClass
--- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Mon Dec 22 17:40:46 2014 +0000
@@ -72,7 +72,6 @@
JVM_FillInStackTrace;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
- JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
JVM_FindLibraryEntry;
JVM_FindLoadedClass;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-product Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Mon Dec 22 17:40:46 2014 +0000
@@ -72,7 +72,6 @@
JVM_FillInStackTrace;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
- JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
JVM_FindLibraryEntry;
JVM_FindLoadedClass;
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Mon Dec 22 17:40:46 2014 +0000
@@ -72,7 +72,6 @@
JVM_FillInStackTrace;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
- JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
JVM_FindLibraryEntry;
JVM_FindLoadedClass;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product Mon Dec 22 17:40:46 2014 +0000
@@ -72,7 +72,6 @@
JVM_FillInStackTrace;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
- JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
JVM_FindLibraryEntry;
JVM_FindLoadedClass;
--- a/hotspot/make/solaris/makefiles/mapfile-vers Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/make/solaris/makefiles/mapfile-vers Mon Dec 22 17:40:46 2014 +0000
@@ -72,7 +72,6 @@
JVM_FillInStackTrace;
JVM_FindClassFromCaller;
JVM_FindClassFromClass;
- JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
JVM_FindLibraryEntry;
JVM_FindLoadedClass;
--- a/hotspot/src/os/aix/vm/osThread_aix.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/aix/vm/osThread_aix.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2013 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -45,7 +45,8 @@
sigemptyset(&_caller_sigmask);
- _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true);
+ _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true,
+ Monitor::_safepoint_check_never);
assert(_startThread_lock !=NULL, "check");
}
--- a/hotspot/src/os/aix/vm/os_aix.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/aix/vm/os_aix.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -5090,6 +5090,9 @@
return 0;
}
+ jio_snprintf(buffer, bufferSize, "%s/core or core.%d",
+ p, current_process_id());
+
return strlen(buffer);
}
--- a/hotspot/src/os/bsd/vm/osThread_bsd.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/bsd/vm/osThread_bsd.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -43,7 +43,8 @@
sigemptyset(&_caller_sigmask);
- _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true);
+ _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true,
+ Monitor::_safepoint_check_never);
assert(_startThread_lock !=NULL, "check");
}
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -4673,7 +4673,7 @@
// Get the default path to the core file
// Returns the length of the string
int os::get_core_path(char* buffer, size_t bufferSize) {
- int n = jio_snprintf(buffer, bufferSize, "/cores");
+ int n = jio_snprintf(buffer, bufferSize, "/cores/core.%d", current_process_id());
// Truncate if theoretical string was longer than bufferSize
n = MIN2(n, (int)bufferSize);
--- a/hotspot/src/os/linux/vm/osThread_linux.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/linux/vm/osThread_linux.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -39,7 +39,8 @@
sigemptyset(&_caller_sigmask);
- _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true);
+ _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true,
+ Monitor::_safepoint_check_never);
assert(_startThread_lock !=NULL, "check");
}
--- a/hotspot/src/os/linux/vm/os_linux.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -5988,13 +5988,70 @@
// Get the default path to the core file
// Returns the length of the string
int os::get_core_path(char* buffer, size_t bufferSize) {
- const char* p = get_current_directory(buffer, bufferSize);
-
- if (p == NULL) {
- assert(p != NULL, "failed to get current directory");
+ /*
+ * Max length of /proc/sys/kernel/core_pattern is 128 characters.
+ * See https://www.kernel.org/doc/Documentation/sysctl/kernel.txt
+ */
+ const int core_pattern_len = 129;
+ char core_pattern[core_pattern_len] = {0};
+
+ int core_pattern_file = ::open("/proc/sys/kernel/core_pattern", O_RDONLY);
+ if (core_pattern_file != -1) {
+ ssize_t ret = ::read(core_pattern_file, core_pattern, core_pattern_len);
+ ::close(core_pattern_file);
+
+ if (ret > 0) {
+ char *last_char = core_pattern + strlen(core_pattern) - 1;
+
+ if (*last_char == '\n') {
+ *last_char = '\0';
+ }
+ }
+ }
+
+ if (strlen(core_pattern) == 0) {
return 0;
}
+ char *pid_pos = strstr(core_pattern, "%p");
+ size_t written;
+
+ if (core_pattern[0] == '/') {
+ written = jio_snprintf(buffer, bufferSize, core_pattern);
+ } else {
+ char cwd[PATH_MAX];
+
+ const char* p = get_current_directory(cwd, PATH_MAX);
+ if (p == NULL) {
+ assert(p != NULL, "failed to get current directory");
+ return 0;
+ }
+
+ if (core_pattern[0] == '|') {
+ written = jio_snprintf(buffer, bufferSize,
+ "\"%s\" (or dumping to %s/core.%d)",
+ &core_pattern[1], p, current_process_id());
+ } else {
+ written = jio_snprintf(buffer, bufferSize, "%s/%s", p, core_pattern);
+ }
+ }
+
+ if ((written >= 0) && (written < bufferSize)
+ && (pid_pos == NULL) && (core_pattern[0] != '|')) {
+ int core_uses_pid_file = ::open("/proc/sys/kernel/core_uses_pid", O_RDONLY);
+
+ if (core_uses_pid_file != -1) {
+ char core_uses_pid = 0;
+ ssize_t ret = ::read(core_uses_pid_file, &core_uses_pid, 1);
+ ::close(core_uses_pid_file);
+
+ if (core_uses_pid == '1'){
+ jio_snprintf(buffer + written, bufferSize - written,
+ ".%d", current_process_id());
+ }
+ }
+ }
+
return strlen(buffer);
}
--- a/hotspot/src/os/posix/vm/os_posix.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -51,15 +51,24 @@
struct rlimit rlim;
bool success;
- n = get_core_path(buffer, bufferSize);
+ char core_path[PATH_MAX];
+ n = get_core_path(core_path, PATH_MAX);
- if (getrlimit(RLIMIT_CORE, &rlim) != 0) {
- jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (may not exist)", current_process_id());
+ if (n <= 0) {
+ jio_snprintf(buffer, bufferSize, "core.%d (may not exist)", current_process_id());
+ success = true;
+#ifdef LINUX
+ } else if (core_path[0] == '"') { // redirect to user process
+ jio_snprintf(buffer, bufferSize, "Core dumps may be processed with %s", core_path);
+ success = true;
+#endif
+ } else if (getrlimit(RLIMIT_CORE, &rlim) != 0) {
+ jio_snprintf(buffer, bufferSize, "%s (may not exist)", core_path);
success = true;
} else {
switch(rlim.rlim_cur) {
case RLIM_INFINITY:
- jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d", current_process_id());
+ jio_snprintf(buffer, bufferSize, "%s", core_path);
success = true;
break;
case 0:
@@ -67,11 +76,12 @@
success = false;
break;
default:
- jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", current_process_id(), (unsigned long)(rlim.rlim_cur >> 10));
+ jio_snprintf(buffer, bufferSize, "%s (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", core_path, (unsigned long)(rlim.rlim_cur >> 10));
success = true;
break;
}
}
+
VMError::report_coredump_status(buffer, success);
}
@@ -89,8 +99,8 @@
} else {
stack[frame_idx ++] = fr.pc();
}
- if (fr.fp() == NULL || os::is_first_C_frame(&fr)
- ||fr.sender_pc() == NULL || fr.cb() != NULL) break;
+ if (fr.fp() == NULL || fr.cb() != NULL ||
+ fr.sender_pc() == NULL || os::is_first_C_frame(&fr)) break;
if (fr.sender_pc() && !os::is_first_C_frame(&fr)) {
fr = os::get_sender_for_C_frame(&fr);
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -5979,6 +5979,9 @@
return 0;
}
+ jio_snprintf(buffer, bufferSize, "%s/core or core.%d",
+ p, current_process_id());
+
return strlen(buffer);
}
--- a/hotspot/src/os/windows/vm/os_windows.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -3768,7 +3768,6 @@
return NULL;
}
-#define MAX_EXIT_HANDLES PRODUCT_ONLY(32) NOT_PRODUCT(128)
#define EXIT_TIMEOUT PRODUCT_ONLY(1000) NOT_PRODUCT(4000) /* 1 sec in product, 4 sec in debug */
static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
@@ -3787,7 +3786,7 @@
// _endthreadex().
// Should be large enough to avoid blocking the exiting thread due to lack of
// a free slot.
- static HANDLE handles[MAX_EXIT_HANDLES];
+ static HANDLE handles[MAXIMUM_WAIT_OBJECTS];
static int handle_count = 0;
static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
@@ -3809,32 +3808,34 @@
if (res == WAIT_TIMEOUT) {
handles[j++] = handles[i];
} else {
- if (res != WAIT_OBJECT_0) {
- warning("WaitForSingleObject failed in %s: %d\n", __FILE__, __LINE__);
- // Don't keep the handle, if we failed waiting for it.
+ if (res == WAIT_FAILED) {
+ warning("WaitForSingleObject failed (%u) in %s: %d\n",
+ GetLastError(), __FILE__, __LINE__);
}
+ // Don't keep the handle, if we failed waiting for it.
CloseHandle(handles[i]);
}
}
// If there's no free slot in the array of the kept handles, we'll have to
// wait until at least one thread completes exiting.
- if ((handle_count = j) == MAX_EXIT_HANDLES) {
+ if ((handle_count = j) == MAXIMUM_WAIT_OBJECTS) {
// Raise the priority of the oldest exiting thread to increase its chances
// to complete sooner.
SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL);
- res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT);
- if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
+ res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT);
+ if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) {
i = (res - WAIT_OBJECT_0);
- handle_count = MAX_EXIT_HANDLES - 1;
+ handle_count = MAXIMUM_WAIT_OBJECTS - 1;
for (; i < handle_count; ++i) {
handles[i] = handles[i + 1];
}
} else {
- warning("WaitForMultipleObjects %s in %s: %d\n",
- (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__);
+ warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
+ (res == WAIT_FAILED ? "failed" : "timed out"),
+ GetLastError(), __FILE__, __LINE__);
// Don't keep handles, if we failed waiting for them.
- for (i = 0; i < MAX_EXIT_HANDLES; ++i) {
+ for (i = 0; i < MAXIMUM_WAIT_OBJECTS; ++i) {
CloseHandle(handles[i]);
}
handle_count = 0;
@@ -3846,7 +3847,8 @@
hthr = GetCurrentThread();
if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],
0, FALSE, DUPLICATE_SAME_ACCESS)) {
- warning("DuplicateHandle failed in %s: %d\n", __FILE__, __LINE__);
+ warning("DuplicateHandle failed (%u) in %s: %d\n",
+ GetLastError(), __FILE__, __LINE__);
} else {
++handle_count;
}
@@ -3869,9 +3871,10 @@
SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL);
}
res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
- if (res < WAIT_OBJECT_0 || res >= (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
- warning("WaitForMultipleObjects %s in %s: %d\n",
- (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__);
+ if (res == WAIT_FAILED || res == WAIT_TIMEOUT) {
+ warning("WaitForMultipleObjects %s (%u) in %s: %d\n",
+ (res == WAIT_FAILED ? "failed" : "timed out"),
+ GetLastError(), __FILE__, __LINE__);
}
for (i = 0; i < handle_count; ++i) {
CloseHandle(handles[i]);
@@ -3909,7 +3912,6 @@
return exit_code;
}
-#undef MAX_EXIT_HANDLES
#undef EXIT_TIMEOUT
void os::win32::setmode_streams() {
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -81,7 +81,8 @@
_metaspace(NULL), _unloading(false), _klasses(NULL),
_claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
_next(NULL), _dependencies(dependencies),
- _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {
+ _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
+ Monitor::_safepoint_check_never)) {
// empty
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -83,9 +83,11 @@
// Note: this requires that CFLspace c'tors
// are called serially in the order in which the locks are
// are acquired in the program text. This is true today.
- _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true),
+ _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true,
+ Monitor::_safepoint_check_sometimes),
_parDictionaryAllocLock(Mutex::leaf - 1, // == rank(ExpandHeap_lock) - 1
- "CompactibleFreeListSpace._dict_par_lock", true),
+ "CompactibleFreeListSpace._dict_par_lock", true,
+ Monitor::_safepoint_check_never),
_rescan_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
CMSRescanMultiple),
_marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
@@ -152,8 +154,7 @@
// Initialize locks for parallel case.
for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
_indexedFreeListParLocks[i] = new Mutex(Mutex::leaf - 1, // == ExpandHeap_lock - 1
- "a freelist par lock",
- true);
+ "a freelist par lock", true, Mutex::_safepoint_check_sometimes);
DEBUG_ONLY(
_indexedFreeList[i].set_protecting_lock(_indexedFreeListParLocks[i]);
)
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -479,7 +479,9 @@
_restart_addr(NULL),
_overflow_list(NULL),
_stats(cmsGen),
- _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true)),
+ _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true,
+ //verify that this lock should be acquired with safepoint check.
+ Monitor::_safepoint_check_sometimes)),
_eden_chunk_array(NULL), // may be set in ctor body
_eden_chunk_capacity(0), // -- ditto --
_eden_chunk_index(0), // -- ditto --
@@ -5946,7 +5948,8 @@
CMSBitMap::CMSBitMap(int shifter, int mutex_rank, const char* mutex_name):
_bm(),
_shifter(shifter),
- _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true) : NULL)
+ _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true,
+ Monitor::_safepoint_check_sometimes) : NULL)
{
_bmStartWord = 0;
_bmWordSize = 0;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Mon Dec 22 17:40:46 2014 +0000
@@ -187,7 +187,8 @@
public:
CMSMarkStack():
- _par_lock(Mutex::event, "CMSMarkStack._par_lock", true),
+ _par_lock(Mutex::event, "CMSMarkStack._par_lock", true,
+ Monitor::_safepoint_check_never),
_hit_limit(0),
_failed_double(0) {}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, 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
@@ -52,7 +52,8 @@
// The 0th worker in notified by mutator threads and has a special monitor.
// The last worker is used for young gen rset size sampling.
if (worker_id > 0) {
- _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true);
+ _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true,
+ Monitor::_safepoint_check_never);
} else {
_monitor = DirtyCardQ_CBL_mon;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -4881,7 +4881,7 @@
}
};
-Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock");
+Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock", false, Monitor::_safepoint_check_never);
class G1KlassCleaningTask : public StackObj {
BoolObjectClosure* _is_alive;
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -805,7 +805,7 @@
HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
HeapRegion* hr)
: _bosa(bosa),
- _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true),
+ _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true, Monitor::_safepoint_check_never),
_code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) {
reset_for_par_iteration();
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -400,7 +400,8 @@
assert(workers() != 0, "no workers");
_monitor = new Monitor(Mutex::barrier, // rank
"GCTaskManager monitor", // name
- Mutex::_allow_vm_block_flag); // allow_vm_block
+ Mutex::_allow_vm_block_flag, // allow_vm_block
+ Monitor::_safepoint_check_never);
// The queue for the GCTaskManager must be a CHeapObj.
GCTaskQueue* unsynchronized_queue = GCTaskQueue::create_on_c_heap();
_queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
@@ -1125,7 +1126,8 @@
} else {
result = new Monitor(Mutex::barrier, // rank
"MonitorSupply monitor", // name
- Mutex::_allow_vm_block_flag); // allow_vm_block
+ Mutex::_allow_vm_block_flag, // allow_vm_block
+ Monitor::_safepoint_check_never);
}
guarantee(result != NULL, "shouldn't return NULL");
assert(!result->is_locked(), "shouldn't be locked");
--- a/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -88,7 +88,8 @@
SurrogateLockerThread::SurrogateLockerThread() :
JavaThread(&_sltLoop),
- _monitor(Mutex::nonleaf, "SLTMonitor"),
+ _monitor(Mutex::nonleaf, "SLTMonitor", false,
+ Monitor::_safepoint_check_sometimes),
_buffer(empty)
{}
--- a/hotspot/src/share/vm/memory/metaspace.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -792,7 +792,8 @@
Mutex* const SpaceManager::_expand_lock =
new Mutex(SpaceManager::_expand_lock_rank,
SpaceManager::_expand_lock_name,
- Mutex::_allow_vm_block_flag);
+ Mutex::_allow_vm_block_flag,
+ Monitor::_safepoint_check_never);
void VirtualSpaceNode::inc_container_count() {
assert_lock_strong(SpaceManager::expand_lock());
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -152,7 +152,7 @@
}
}
-Monitor* SharedHeap::StrongRootsScope::_lock = new Monitor(Mutex::leaf, "StrongRootsScope lock", false);
+Monitor* SharedHeap::StrongRootsScope::_lock = new Monitor(Mutex::leaf, "StrongRootsScope lock", false, Monitor::_safepoint_check_never);
void SharedHeap::StrongRootsScope::mark_worker_done_with_threads(uint n_workers) {
// The Thread work barrier is only needed by G1 Class Unloading.
--- a/hotspot/src/share/vm/prims/jvm.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/prims/jvm.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -700,23 +700,7 @@
// Returns a class loaded by the bootstrap class loader; or null
// if not found. ClassNotFoundException is not thrown.
-//
-// Rationale behind JVM_FindClassFromBootLoader
-// a> JVM_FindClassFromClassLoader was never exported in the export tables.
-// b> because of (a) java.dll has a direct dependecy on the unexported
-// private symbol "_JVM_FindClassFromClassLoader@20".
-// c> the launcher cannot use the private symbol as it dynamically opens
-// the entry point, so if something changes, the launcher will fail
-// unexpectedly at runtime, it is safest for the launcher to dlopen a
-// stable exported interface.
-// d> re-exporting JVM_FindClassFromClassLoader as public, will cause its
-// signature to change from _JVM_FindClassFromClassLoader@20 to
-// JVM_FindClassFromClassLoader and will not be backward compatible
-// with older JDKs.
-// Thus a public/stable exported entry point is the right solution,
-// public here means public in linker semantics, and is exported only
-// to the JDK, and is not intended to be a public API.
-
+// FindClassFromBootLoader is exported to the launcher for windows.
JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env,
const char* name))
JVMWrapper2("JVM_FindClassFromBootLoader %s", name);
@@ -740,33 +724,6 @@
return (jclass) JNIHandles::make_local(env, k->java_mirror());
JVM_END
-// Not used; JVM_FindClassFromCaller replaces this.
-JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
- jboolean init, jobject loader,
- jboolean throwError))
- JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name,
- throwError ? "error" : "exception");
- // Java libraries should ensure that name is never null...
- if (name == NULL || (int)strlen(name) > Symbol::max_length()) {
- // It's impossible to create this class; the name cannot fit
- // into the constant pool.
- if (throwError) {
- THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
- } else {
- THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
- }
- }
- TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);
- Handle h_loader(THREAD, JNIHandles::resolve(loader));
- jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
- Handle(), throwError, THREAD);
-
- if (TraceClassResolution && result != NULL) {
- trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
- }
- return result;
-JVM_END
-
// Find a class with this name in this loader, using the caller's protection domain.
JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name,
jboolean init, jobject loader,
--- a/hotspot/src/share/vm/prims/jvm.h Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/prims/jvm.h Mon Dec 22 17:40:46 2014 +0000
@@ -335,15 +335,6 @@
JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
/*
- * Find a class from a given class loader. Throw ClassNotFoundException
- * or NoClassDefFoundError depending on the value of the last
- * argument.
- */
-JNIEXPORT jclass JNICALL
-JVM_FindClassFromClassLoader(JNIEnv *env, const char *name, jboolean init,
- jobject loader, jboolean throwError);
-
-/*
* Find a class from a boot class loader. Returns NULL if class not found.
*/
JNIEXPORT jclass JNICALL
--- a/hotspot/src/share/vm/prims/whitebox.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -1078,6 +1078,14 @@
return (jlong) MetaspaceGC::capacity_until_GC();
WB_END
+WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean mutexSafepointValue, jboolean attemptedNoSafepointValue))
+ Monitor::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ?
+ Monitor::_safepoint_check_always :
+ Monitor::_safepoint_check_never;
+ MutexLockerEx ml(new Mutex(Mutex::leaf, "SFPT_Test_lock", true, sfpt_check_required),
+ attemptedNoSafepointValue == JNI_TRUE);
+WB_END
+
//Some convenience methods to deal with objects from java
int WhiteBox::offset_for_field(const char* field_name, oop object,
Symbol* signature_symbol) {
@@ -1274,6 +1282,7 @@
{CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob },
{CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize },
{CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize },
+ {CC"assertMatchingSafepointCalls", CC"(ZZ)V", (void*)&WB_AssertMatchingSafepointCalls },
};
#undef CC
--- a/hotspot/src/share/vm/runtime/arguments.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -2980,17 +2980,20 @@
#endif
// -D
} else if (match_option(option, "-D", &tail)) {
- if (match_option(option, "-Djava.endorsed.dirs=", &tail)) {
+ const char* value;
+ if (match_option(option, "-Djava.endorsed.dirs=", &value) &&
+ *value!= '\0' && strcmp(value, "\"\"") != 0) {
// abort if -Djava.endorsed.dirs is set
jio_fprintf(defaultStream::output_stream(),
- "-Djava.endorsed.dirs is not supported. Endorsed standards and standalone APIs\n"
- "in modular form will be supported via the concept of upgradeable modules.\n");
+ "-Djava.endorsed.dirs=%s is not supported. Endorsed standards and standalone APIs\n"
+ "in modular form will be supported via the concept of upgradeable modules.\n", value);
return JNI_EINVAL;
}
- if (match_option(option, "-Djava.ext.dirs=", &tail)) {
+ if (match_option(option, "-Djava.ext.dirs=", &value) &&
+ *value != '\0' && strcmp(value, "\"\"") != 0) {
// abort if -Djava.ext.dirs is set
jio_fprintf(defaultStream::output_stream(),
- "-Djava.ext.dirs is not supported. Use -classpath instead.\n");
+ "-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value);
return JNI_EINVAL;
}
--- a/hotspot/src/share/vm/runtime/globals.hpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/globals.hpp Mon Dec 22 17:40:46 2014 +0000
@@ -1341,7 +1341,7 @@
develop(bool, TraceClassInitialization, false, \
"Trace class initialization") \
\
- develop(bool, TraceExceptions, false, \
+ product(bool, TraceExceptions, false, \
"Trace exceptions") \
\
develop(bool, TraceICs, false, \
--- a/hotspot/src/share/vm/runtime/mutex.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/mutex.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -895,6 +895,11 @@
// of Mutex-Monitor and instead directly address the underlying design flaw.
void Monitor::lock(Thread * Self) {
+ // Ensure that the Monitor requires/allows safepoint checks.
+ assert(_safepoint_check_required != Monitor::_safepoint_check_never,
+ err_msg("This lock should never have a safepoint check: %s",
+ name()));
+
#ifdef CHECK_UNHANDLED_OOPS
// Clear unhandled oops so we get a crash right away. Only clear for non-vm
// or GC threads.
@@ -953,6 +958,10 @@
// thread state set to be in VM, the safepoint synchronization code will deadlock!
void Monitor::lock_without_safepoint_check(Thread * Self) {
+ // Ensure that the Monitor does not require or allow safepoint checks.
+ assert(_safepoint_check_required != Monitor::_safepoint_check_always,
+ err_msg("This lock should always have a safepoint check: %s",
+ name()));
assert(_owner != Self, "invariant");
ILock(Self);
assert(_owner == NULL, "invariant");
@@ -1082,6 +1091,12 @@
bool Monitor::wait(bool no_safepoint_check, long timeout,
bool as_suspend_equivalent) {
+ // Make sure safepoint checking is used properly.
+ assert(!(_safepoint_check_required == Monitor::_safepoint_check_never && no_safepoint_check == false),
+ err_msg("This lock should never have a safepoint check: %s", name()));
+ assert(!(_safepoint_check_required == Monitor::_safepoint_check_always && no_safepoint_check == true),
+ err_msg("This lock should always have a safepoint check: %s", name()));
+
Thread * const Self = Thread::current();
assert(_owner == Self, "invariant");
assert(ILocked(), "invariant");
@@ -1168,11 +1183,13 @@
Monitor::Monitor() { ClearMonitor(this); }
-Monitor::Monitor(int Rank, const char * name, bool allow_vm_block) {
+Monitor::Monitor(int Rank, const char * name, bool allow_vm_block,
+ SafepointCheckRequired safepoint_check_required) {
ClearMonitor(this, name);
#ifdef ASSERT
_allow_vm_block = allow_vm_block;
_rank = Rank;
+ NOT_PRODUCT(_safepoint_check_required = safepoint_check_required;)
#endif
}
@@ -1180,11 +1197,13 @@
assert((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "");
}
-Mutex::Mutex(int Rank, const char * name, bool allow_vm_block) {
+Mutex::Mutex(int Rank, const char * name, bool allow_vm_block,
+ SafepointCheckRequired safepoint_check_required) {
ClearMonitor((Monitor *) this, name);
#ifdef ASSERT
_allow_vm_block = allow_vm_block;
_rank = Rank;
+ NOT_PRODUCT(_safepoint_check_required = safepoint_check_required;)
#endif
}
--- a/hotspot/src/share/vm/runtime/mutex.hpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/mutex.hpp Mon Dec 22 17:40:46 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, 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
@@ -154,6 +154,24 @@
_as_suspend_equivalent_flag = true
};
+ // Locks can be acquired with or without safepoint check.
+ // Monitor::lock and Monitor::lock_without_safepoint_check
+ // checks these flags when acquiring a lock to ensure
+ // consistent checking for each lock.
+ // A few existing locks will sometimes have a safepoint check and
+ // sometimes not, but these locks are set up in such a way to avoid deadlocks.
+ enum SafepointCheckRequired {
+ _safepoint_check_never, // Monitors with this value will cause errors
+ // when acquired with a safepoint check.
+ _safepoint_check_sometimes, // Certain locks are called sometimes with and
+ // sometimes without safepoint checks. These
+ // locks will not produce errors when locked.
+ _safepoint_check_always // Causes error if locked without a safepoint
+ // check.
+ };
+
+ NOT_PRODUCT(SafepointCheckRequired _safepoint_check_required;)
+
enum WaitResults {
CONDVAR_EVENT, // Wait returned because of condition variable notification
INTERRUPT_EVENT, // Wait returned because waiting thread was interrupted
@@ -175,7 +193,8 @@
Monitor() ;
public:
- Monitor(int rank, const char *name, bool allow_vm_block=false);
+ Monitor(int rank, const char *name, bool allow_vm_block = false,
+ SafepointCheckRequired safepoint_check_required = _safepoint_check_always);
~Monitor();
// Wait until monitor is notified (or times out).
@@ -261,7 +280,8 @@
class Mutex : public Monitor { // degenerate Monitor
public:
- Mutex (int rank, const char *name, bool allow_vm_block=false);
+ Mutex(int rank, const char *name, bool allow_vm_block = false,
+ SafepointCheckRequired safepoint_check_required = _safepoint_check_always);
~Mutex () ;
private:
bool notify () { ShouldNotReachHere(); return false; }
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -167,131 +167,133 @@
}
#endif
-#define def(var, type, pri, vm_block) { \
- var = new type(Mutex::pri, #var, vm_block); \
- assert(_num_mutex < MAX_NUM_MUTEX, \
- "increase MAX_NUM_MUTEX"); \
- _mutex_array[_num_mutex++] = var; \
+#define def(var, type, pri, vm_block, safepoint_check_allowed ) { \
+ var = new type(Mutex::pri, #var, vm_block, safepoint_check_allowed); \
+ assert(_num_mutex < MAX_NUM_MUTEX, "increase MAX_NUM_MUTEX"); \
+ _mutex_array[_num_mutex] = var; \
}
void mutex_init() {
- def(tty_lock , Mutex , event, true ); // allow to lock in VM
+ def(tty_lock , Mutex , event, true, Monitor::_safepoint_check_never); // allow to lock in VM
- def(CGC_lock , Monitor, special, true ); // coordinate between fore- and background GC
- def(STS_lock , Monitor, leaf, true );
+ def(CGC_lock , Monitor, special, true, Monitor::_safepoint_check_never); // coordinate between fore- and background GC
+ def(STS_lock , Monitor, leaf, true, Monitor::_safepoint_check_never);
+
if (UseConcMarkSweepGC || UseG1GC) {
- def(FullGCCount_lock , Monitor, leaf, true ); // in support of ExplicitGCInvokesConcurrent
+ def(FullGCCount_lock , Monitor, leaf, true, Monitor::_safepoint_check_never); // in support of ExplicitGCInvokesConcurrent
}
if (UseG1GC) {
- def(CMark_lock , Monitor, nonleaf, true ); // coordinate concurrent mark thread
- def(CMRegionStack_lock , Mutex, leaf, true );
- def(SATB_Q_FL_lock , Mutex , special, true );
- def(SATB_Q_CBL_mon , Monitor, nonleaf, true );
- def(Shared_SATB_Q_lock , Mutex, nonleaf, true );
- def(DirtyCardQ_FL_lock , Mutex , special, true );
- def(DirtyCardQ_CBL_mon , Monitor, nonleaf, true );
- def(Shared_DirtyCardQ_lock , Mutex, nonleaf, true );
+ def(CMark_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_never); // coordinate concurrent mark thread
+ def(CMRegionStack_lock , Mutex, leaf, true, Monitor::_safepoint_check_never);
+ def(SATB_Q_FL_lock , Mutex , special, true, Monitor::_safepoint_check_never);
+ def(SATB_Q_CBL_mon , Monitor, nonleaf, true, Monitor::_safepoint_check_never);
+ def(Shared_SATB_Q_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never);
+
+ def(DirtyCardQ_FL_lock , Mutex , special, true, Monitor::_safepoint_check_never);
+ def(DirtyCardQ_CBL_mon , Monitor, nonleaf, true, Monitor::_safepoint_check_never);
+ def(Shared_DirtyCardQ_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never);
- def(FreeList_lock , Mutex, leaf , true );
- def(SecondaryFreeList_lock , Monitor, leaf , true );
- def(OldSets_lock , Mutex , leaf , true );
- def(RootRegionScan_lock , Monitor, leaf , true );
- def(MMUTracker_lock , Mutex , leaf , true );
- def(HotCardCache_lock , Mutex , special , true );
- def(EvacFailureStack_lock , Mutex , nonleaf , true );
+ def(FreeList_lock , Mutex, leaf , true, Monitor::_safepoint_check_never);
+ def(SecondaryFreeList_lock , Monitor, leaf , true, Monitor::_safepoint_check_never);
+ def(OldSets_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
+ def(RootRegionScan_lock , Monitor, leaf , true, Monitor::_safepoint_check_never);
+ def(MMUTracker_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
+ def(HotCardCache_lock , Mutex , special , true, Monitor::_safepoint_check_never);
+ def(EvacFailureStack_lock , Mutex , nonleaf , true, Monitor::_safepoint_check_never);
- def(StringDedupQueue_lock , Monitor, leaf, true );
- def(StringDedupTable_lock , Mutex , leaf, true );
+ def(StringDedupQueue_lock , Monitor, leaf, true, Monitor::_safepoint_check_never);
+ def(StringDedupTable_lock , Mutex , leaf, true, Monitor::_safepoint_check_never);
}
- def(ParGCRareEvent_lock , Mutex , leaf , true );
- def(DerivedPointerTableGC_lock , Mutex, leaf, true );
- def(CodeCache_lock , Monitor, special, true );
- def(Interrupt_lock , Monitor, special, true ); // used for interrupt processing
- def(RawMonitor_lock , Mutex, special, true );
- def(OopMapCacheAlloc_lock , Mutex, leaf, true ); // used for oop_map_cache allocation.
+ def(ParGCRareEvent_lock , Mutex , leaf , true, Monitor::_safepoint_check_sometimes);
+ def(DerivedPointerTableGC_lock , Mutex, leaf, true, Monitor::_safepoint_check_never);
+ def(CodeCache_lock , Mutex , special, true, Monitor::_safepoint_check_never);
+ def(Interrupt_lock , Monitor, special, true, Monitor::_safepoint_check_never); // used for interrupt processing
+ def(RawMonitor_lock , Mutex, special, true, Monitor::_safepoint_check_never);
+ def(OopMapCacheAlloc_lock , Mutex, leaf, true, Monitor::_safepoint_check_always); // used for oop_map_cache allocation.
- def(Patching_lock , Mutex , special, true ); // used for safepointing and code patching.
- def(ObjAllocPost_lock , Monitor, special, false);
- def(Service_lock , Monitor, special, true ); // used for service thread operations
- def(JmethodIdCreation_lock , Mutex , leaf, true ); // used for creating jmethodIDs.
+ def(Patching_lock , Mutex , special, true, Monitor::_safepoint_check_never); // used for safepointing and code patching.
+ def(ObjAllocPost_lock , Monitor, special, false, Monitor::_safepoint_check_never);
+ def(Service_lock , Monitor, special, true, Monitor::_safepoint_check_never); // used for service thread operations
+ def(JmethodIdCreation_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for creating jmethodIDs.
- def(SystemDictionary_lock , Monitor, leaf, true ); // lookups done by VM thread
- def(PackageTable_lock , Mutex , leaf, false);
- def(InlineCacheBuffer_lock , Mutex , leaf, true );
- def(VMStatistic_lock , Mutex , leaf, false);
- def(ExpandHeap_lock , Mutex , leaf, true ); // Used during compilation by VM thread
- def(JNIHandleBlockFreeList_lock , Mutex , leaf, true ); // handles are used by VM thread
- def(SignatureHandlerLibrary_lock , Mutex , leaf, false);
- def(SymbolTable_lock , Mutex , leaf+2, true );
- def(StringTable_lock , Mutex , leaf, true );
- def(ProfilePrint_lock , Mutex , leaf, false); // serial profile printing
- def(ExceptionCache_lock , Mutex , leaf, false); // serial profile printing
- def(OsrList_lock , Mutex , leaf, true );
- def(Debug1_lock , Mutex , leaf, true );
+ def(SystemDictionary_lock , Monitor, leaf, true, Monitor::_safepoint_check_always); // lookups done by VM thread
+ def(PackageTable_lock , Mutex , leaf, false, Monitor::_safepoint_check_always);
+ def(InlineCacheBuffer_lock , Mutex , leaf, true, Monitor::_safepoint_check_always);
+ def(VMStatistic_lock , Mutex , leaf, false, Monitor::_safepoint_check_always);
+ def(ExpandHeap_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // Used during compilation by VM thread
+ def(JNIHandleBlockFreeList_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); // handles are used by VM thread
+ def(SignatureHandlerLibrary_lock , Mutex , leaf, false, Monitor::_safepoint_check_always);
+ def(SymbolTable_lock , Mutex , leaf+2, true, Monitor::_safepoint_check_always);
+ def(StringTable_lock , Mutex , leaf, true, Monitor::_safepoint_check_always);
+ def(ProfilePrint_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing
+ def(ExceptionCache_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing
+ def(OsrList_lock , Mutex , leaf, true, Monitor::_safepoint_check_never);
+ def(Debug1_lock , Mutex , leaf, true, Monitor::_safepoint_check_never);
#ifndef PRODUCT
- def(FullGCALot_lock , Mutex , leaf, false); // a lock to make FullGCALot MT safe
+ def(FullGCALot_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // a lock to make FullGCALot MT safe
#endif
- def(BeforeExit_lock , Monitor, leaf, true );
- def(PerfDataMemAlloc_lock , Mutex , leaf, true ); // used for allocating PerfData memory for performance data
- def(PerfDataManager_lock , Mutex , leaf, true ); // used for synchronized access to PerfDataManager resources
+ def(BeforeExit_lock , Monitor, leaf, true, Monitor::_safepoint_check_always);
+ def(PerfDataMemAlloc_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for allocating PerfData memory for performance data
+ def(PerfDataManager_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for synchronized access to PerfDataManager resources
// CMS_modUnionTable_lock leaf
- // CMS_bitMap_lock leaf + 1
- // CMS_freeList_lock leaf + 2
+ // CMS_bitMap_lock leaf 1
+ // CMS_freeList_lock leaf 2
- def(Safepoint_lock , Monitor, safepoint, true ); // locks SnippetCache_lock/Threads_lock
+ def(Safepoint_lock , Monitor, safepoint, true, Monitor::_safepoint_check_sometimes); // locks SnippetCache_lock/Threads_lock
- def(Threads_lock , Monitor, barrier, true );
+ def(Threads_lock , Monitor, barrier, true, Monitor::_safepoint_check_sometimes);
- def(VMOperationQueue_lock , Monitor, nonleaf, true ); // VM_thread allowed to block on these
- def(VMOperationRequest_lock , Monitor, nonleaf, true );
- def(RetData_lock , Mutex , nonleaf, false);
- def(Terminator_lock , Monitor, nonleaf, true );
- def(VtableStubs_lock , Mutex , nonleaf, true );
- def(Notify_lock , Monitor, nonleaf, true );
- def(JNIGlobalHandle_lock , Mutex , nonleaf, true ); // locks JNIHandleBlockFreeList_lock
- def(JNICritical_lock , Monitor, nonleaf, true ); // used for JNI critical regions
- def(AdapterHandlerLibrary_lock , Mutex , nonleaf, true);
+ def(VMOperationQueue_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes); // VM_thread allowed to block on these
+ def(VMOperationRequest_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes);
+ def(RetData_lock , Mutex , nonleaf, false, Monitor::_safepoint_check_always);
+ def(Terminator_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes);
+ def(VtableStubs_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always);
+ def(Notify_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_always);
+ def(JNIGlobalHandle_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always); // locks JNIHandleBlockFreeList_lock
+ def(JNICritical_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_always); // used for JNI critical regions
+ def(AdapterHandlerLibrary_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always);
if (UseConcMarkSweepGC) {
- def(SLT_lock , Monitor, nonleaf, false );
- // used in CMS GC for locking PLL lock
+ def(SLT_lock , Monitor, nonleaf, false, Monitor::_safepoint_check_never); // used in CMS GC for locking PLL lock
}
- def(Heap_lock , Monitor, nonleaf+1, false);
- def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation
- def(MemberNameTable_lock , Mutex , nonleaf+1, false); // Used to protect MemberNameTable
+
+ def(Heap_lock , Monitor, nonleaf+1, false, Monitor::_safepoint_check_sometimes);
+ def(JfieldIdCreation_lock , Mutex , nonleaf+1, true, Monitor::_safepoint_check_always); // jfieldID, Used in VM_Operation
+ def(MemberNameTable_lock , Mutex , nonleaf+1, false, Monitor::_safepoint_check_always); // Used to protect MemberNameTable
- def(CompiledIC_lock , Mutex , nonleaf+2, false); // locks VtableStubs_lock, InlineCacheBuffer_lock
- def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true );
- def(CompileStatistics_lock , Mutex , nonleaf+2, false);
- def(MultiArray_lock , Mutex , nonleaf+2, false); // locks SymbolTable_lock
+ def(CompiledIC_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks VtableStubs_lock, InlineCacheBuffer_lock
+ def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true, Monitor::_safepoint_check_always);
+ def(CompileStatistics_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always);
+ def(MultiArray_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks SymbolTable_lock
- def(JvmtiThreadState_lock , Mutex , nonleaf+2, false); // Used by JvmtiThreadState/JvmtiEventController
- def(JvmtiPendingEvent_lock , Monitor, nonleaf, false); // Used by JvmtiCodeBlobEvents
- def(Management_lock , Mutex , nonleaf+2, false); // used for JVM management
+ def(JvmtiThreadState_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController
+ def(JvmtiPendingEvent_lock , Monitor, nonleaf, false, Monitor::_safepoint_check_never); // Used by JvmtiCodeBlobEvents
+ def(Management_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // used for JVM management
- def(Compile_lock , Mutex , nonleaf+3, true );
- def(MethodData_lock , Mutex , nonleaf+3, false);
+ def(Compile_lock , Mutex , nonleaf+3, true, Monitor::_safepoint_check_sometimes);
+ def(MethodData_lock , Mutex , nonleaf+3, false, Monitor::_safepoint_check_always);
- def(MethodCompileQueue_lock , Monitor, nonleaf+4, true );
- def(Debug2_lock , Mutex , nonleaf+4, true );
- def(Debug3_lock , Mutex , nonleaf+4, true );
- def(ProfileVM_lock , Monitor, special, false); // used for profiling of the VMThread
- def(CompileThread_lock , Monitor, nonleaf+5, false );
- def(PeriodicTask_lock , Monitor, nonleaf+5, true);
+ def(MethodCompileQueue_lock , Monitor, nonleaf+4, true, Monitor::_safepoint_check_always);
+ def(Debug2_lock , Mutex , nonleaf+4, true, Monitor::_safepoint_check_never);
+ def(Debug3_lock , Mutex , nonleaf+4, true, Monitor::_safepoint_check_never);
+ def(ProfileVM_lock , Monitor, special, false, Monitor::_safepoint_check_never); // used for profiling of the VMThread
+ def(CompileThread_lock , Monitor, nonleaf+5, false, Monitor::_safepoint_check_always);
+ def(PeriodicTask_lock , Monitor, nonleaf+5, true, Monitor::_safepoint_check_sometimes);
if (WhiteBoxAPI) {
- def(Compilation_lock , Monitor, leaf, false );
+ def(Compilation_lock , Monitor, leaf, false, Monitor::_safepoint_check_never);
}
+
#ifdef INCLUDE_TRACE
- def(JfrMsg_lock , Monitor, leaf, true);
- def(JfrBuffer_lock , Mutex, leaf, true);
- def(JfrThreadGroups_lock , Mutex, leaf, true);
- def(JfrStream_lock , Mutex, nonleaf, true);
- def(JfrStacktrace_lock , Mutex, special, true);
+ def(JfrMsg_lock , Monitor, leaf, true, Monitor::_safepoint_check_always);
+ def(JfrBuffer_lock , Mutex, leaf, true, Monitor::_safepoint_check_never);
+ def(JfrThreadGroups_lock , Mutex, leaf, true, Monitor::_safepoint_check_always);
+ def(JfrStream_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never);
+ def(JfrStacktrace_lock , Mutex, special, true, Monitor::_safepoint_check_sometimes);
#endif
#ifndef SUPPORTS_NATIVE_CX8
- def(UnsafeJlong_lock , Mutex, special, false);
+ def(UnsafeJlong_lock , Mutex, special, false, Monitor::_safepoint_check_never);
#endif
}
--- a/hotspot/src/share/vm/runtime/sweeper.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -158,7 +158,7 @@
Tickspan NMethodSweeper::_peak_sweep_time; // Peak time for a full sweep
Tickspan NMethodSweeper::_peak_sweep_fraction_time; // Peak time sweeping one fraction
-Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, "Sweeper::Statistics", true);
+Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, "Sweeper::Statistics", true, Monitor::_safepoint_check_sometimes);
class MarkActivationClosure: public CodeBlobClosure {
public:
--- a/hotspot/src/share/vm/runtime/thread.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/thread.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -230,7 +230,8 @@
_visited_for_critical_count = false;
#endif
- _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true);
+ _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true,
+ Monitor::_safepoint_check_sometimes);
_suspend_flags = 0;
// thread-specific hashCode stream generator state - Marsaglia shift-xor form
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -214,7 +214,8 @@
_vm_queue = new VMOperationQueue();
guarantee(_vm_queue != NULL, "just checking");
- _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true);
+ _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true,
+ Monitor::_safepoint_check_never);
if (UsePerfData) {
// jvmstat performance counters
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -391,7 +391,8 @@
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
Thread * thr_cur = ThreadLocalStorage::get_thread_slow();
- Monitor timer(Mutex::leaf, "VM_Exit timer", true);
+ Monitor timer(Mutex::leaf, "VM_Exit timer", true,
+ Monitor::_safepoint_check_never);
// Compiler threads need longer wait because they can access VM data directly
// while in native. If they are active and some structures being used are
--- a/hotspot/src/share/vm/services/diagnosticFramework.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/services/diagnosticFramework.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -487,7 +487,7 @@
}
}
-Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);
+Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true, Monitor::_safepoint_check_never);
bool DCmdFactory::_send_jmx_notification = false;
DCmdFactory* DCmdFactory::factory(DCmdSource source, const char* name, size_t len) {
--- a/hotspot/src/share/vm/services/memoryManager.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/services/memoryManager.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -198,7 +198,8 @@
GCMemoryManager::GCMemoryManager() : MemoryManager() {
_num_collections = 0;
_last_gc_stat = NULL;
- _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true);
+ _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true,
+ Monitor::_safepoint_check_never);
_current_gc_stat = NULL;
_num_gc_threads = 1;
_notification_enabled = false;
--- a/hotspot/src/share/vm/utilities/decoder.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/utilities/decoder.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -42,7 +42,9 @@
AbstractDecoder* Decoder::_error_handler_decoder = NULL;
NullDecoder Decoder::_do_nothing_decoder;
Mutex* Decoder::_shared_decoder_lock = new Mutex(Mutex::native,
- "SharedDecoderLock");
+ "SharedDecoderLock",
+ false,
+ Monitor::_safepoint_check_never);
AbstractDecoder* Decoder::get_shared_instance() {
assert(_shared_decoder_lock != NULL && _shared_decoder_lock->owned_by_self(),
--- a/hotspot/src/share/vm/utilities/events.hpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/utilities/events.hpp Mon Dec 22 17:40:46 2014 +0000
@@ -90,7 +90,7 @@
_length(length),
_count(0),
_index(0),
- _mutex(Mutex::event, name) {
+ _mutex(Mutex::event, name, false, Monitor::_safepoint_check_never) {
_records = new EventRecord<T>[length];
}
--- a/hotspot/src/share/vm/utilities/workgroup.cpp Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/src/share/vm/utilities/workgroup.cpp Mon Dec 22 17:40:46 2014 +0000
@@ -46,7 +46,8 @@
// Other initialization.
_monitor = new Monitor(/* priority */ Mutex::leaf,
/* name */ "WorkGroup monitor",
- /* allow_vm_block */ are_GC_task_threads);
+ /* allow_vm_block */ are_GC_task_threads,
+ Monitor::_safepoint_check_sometimes);
assert(monitor() != NULL, "Failed to allocate monitor");
_terminate = false;
_task = NULL;
@@ -378,12 +379,13 @@
// *** WorkGangBarrierSync
WorkGangBarrierSync::WorkGangBarrierSync()
- : _monitor(Mutex::safepoint, "work gang barrier sync", true),
+ : _monitor(Mutex::safepoint, "work gang barrier sync", true,
+ Monitor::_safepoint_check_never),
_n_workers(0), _n_completed(0), _should_reset(false), _aborted(false) {
}
WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name)
- : _monitor(Mutex::safepoint, name, true),
+ : _monitor(Mutex::safepoint, name, true, Monitor::_safepoint_check_never),
_n_workers(n_workers), _n_completed(0), _should_reset(false), _aborted(false) {
}
--- a/hotspot/test/TEST.groups Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/test/TEST.groups Mon Dec 22 17:40:46 2014 +0000
@@ -50,6 +50,9 @@
# runs those tests that only require compact1 and compact2 API's.
#
+hotspot_all = \
+ /
+
# Full JDK can run all tests
#
jdk = \
@@ -435,13 +438,15 @@
sanity/ExecuteInternalVMTests.java \
serviceability/dcmd/compiler
-hotspot_all = \
+hotspot_jprt = \
+ :hotspot_wbapitest \
:hotspot_compiler_1 \
:hotspot_compiler_2 \
:hotspot_compiler_3 \
:hotspot_compiler_closed \
:hotspot_gc \
:hotspot_runtime \
+ :hotspot_runtime_closed \
:hotspot_serviceability
#All tests that depends on nashorn extension.
--- a/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java Mon Dec 22 17:40:46 2014 +0000
@@ -33,11 +33,6 @@
public class TraceExceptionsTest {
public static void main(String[] args) throws Exception {
- if (!Platform.isDebugBuild()) {
- System.out.println("Skip the test on product builds since XX:+TraceExceptions is not available on product builds");
- return;
- }
-
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+TraceExceptions", "NoClassFound");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java Mon Dec 22 17:40:46 2014 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 8047290
+ * @summary Ensure that a Monitor::lock_without_safepoint_check fires an assert when it incorrectly acquires a lock which must always have safepoint checks.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build AssertSafepointCheckConsistency1
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main AssertSafepointCheckConsistency1
+ */
+
+import com.oracle.java.testlibrary.*;
+
+import sun.hotspot.WhiteBox;
+
+public class AssertSafepointCheckConsistency1 {
+ public static void main(String args[]) throws Exception {
+ if (args.length > 0) {
+ WhiteBox.getWhiteBox().assertMatchingSafepointCalls(true, true);
+ }
+ if (Platform.isDebugBuild()){
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-Xbootclasspath/a:.",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+WhiteBoxAPI",
+ "-XX:-TransmitErrorReport",
+ "-Xmx32m",
+ "AssertSafepointCheckConsistency1",
+ "test");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("assert").shouldContain("always");
+ }
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java Mon Dec 22 17:40:46 2014 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, 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 8047290
+ * @summary Ensure that a Monitor::lock fires an assert when it incorrectly acquires a lock which must never have safepoint checks.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build AssertSafepointCheckConsistency2
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main AssertSafepointCheckConsistency2
+ */
+
+import com.oracle.java.testlibrary.*;
+
+import sun.hotspot.WhiteBox;
+
+public class AssertSafepointCheckConsistency2 {
+ public static void main(String args[]) throws Exception {
+ if (args.length > 0) {
+ WhiteBox.getWhiteBox().assertMatchingSafepointCalls(false, false);
+ }
+ if (Platform.isDebugBuild()){
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-Xbootclasspath/a:.",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+WhiteBoxAPI",
+ "-XX:-TransmitErrorReport",
+ "-Xmx32m",
+ "AssertSafepointCheckConsistency2",
+ "test");
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("assert").shouldContain("never");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java Mon Dec 22 17:40:46 2014 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 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 8047290
+ * @summary Ensure that Monitor::lock_without_safepoint_check does not assert when it correctly acquires a lock which must never have safepoint checks.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build AssertSafepointCheckConsistency3
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main AssertSafepointCheckConsistency3
+ */
+
+import com.oracle.java.testlibrary.*;
+
+import sun.hotspot.WhiteBox;
+
+public class AssertSafepointCheckConsistency3 {
+ public static void main(String args[]) throws Exception {
+ if (args.length > 0) {
+ WhiteBox.getWhiteBox().assertMatchingSafepointCalls(false, true);
+ }
+ if (Platform.isDebugBuild()){
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-Xbootclasspath/a:.",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+WhiteBoxAPI",
+ "-XX:-TransmitErrorReport",
+ "-Xmx32m",
+ "AssertSafepointCheckConsistency3",
+ "test");
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("assert");
+ output.shouldNotContain("never");
+ output.shouldNotContain("always");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java Mon Dec 22 17:40:46 2014 +0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014, 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 8047290
+ * @summary Ensure that Monitor::lock does not assert when it correctly acquires a lock which must always have safepoint checks.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build AssertSafepointCheckConsistency4
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main AssertSafepointCheckConsistency4
+ */
+
+import com.oracle.java.testlibrary.*;
+
+import sun.hotspot.WhiteBox;
+
+public class AssertSafepointCheckConsistency4 {
+ public static void main(String args[]) throws Exception {
+ if (args.length > 0) {
+ WhiteBox.getWhiteBox().assertMatchingSafepointCalls(true, false);
+ }
+ if (Platform.isDebugBuild()){
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-Xbootclasspath/a:.",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+WhiteBoxAPI",
+ "-XX:-TransmitErrorReport",
+ "-Xmx32m",
+ "AssertSafepointCheckConsistency4",
+ "test");
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("assert");
+ output.shouldNotContain("never");
+ output.shouldNotContain("always");
+ }
+ }
+}
+
+
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Mon Dec 22 16:49:24 2014 +0100
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Mon Dec 22 17:40:46 2014 +0000
@@ -248,4 +248,6 @@
return offset;
}
+ // Safepoint Checking
+ public native void assertMatchingSafepointCalls(boolean mutexSafepointValue, boolean attemptedNoSafepointValue);
}