--- a/.hgtags Thu Jul 25 11:07:23 2013 -0700
+++ b/.hgtags Fri Jul 26 13:34:22 2013 -0700
@@ -221,3 +221,4 @@
0a85476a0b9cb876d5666d45097dac68bef3fce1 jdk8-b97
711eb4aa87de68de78250e0549980936bab53d54 jdk8-b98
2d3875b0d18b3ad1c2bebf385a697e309e4005a4 jdk8-b99
+3d34036aae4ea90b2ca59712d5a69db3221f0875 jdk8-b100
--- a/.hgtags-top-repo Thu Jul 25 11:07:23 2013 -0700
+++ b/.hgtags-top-repo Fri Jul 26 13:34:22 2013 -0700
@@ -221,3 +221,4 @@
a1c1e8bf71f354f3aec0214cf13d6668811e021d jdk8-b97
0d0c983a817bbe8518a5ff201306334a8de267f2 jdk8-b98
59dc9da813794c924a0383c2a6241af94defdfed jdk8-b99
+d2dcb110e9dbaf9903c05b211df800e78e4b394e jdk8-b100
--- a/corba/.hgtags Thu Jul 25 11:07:23 2013 -0700
+++ b/corba/.hgtags Fri Jul 26 13:34:22 2013 -0700
@@ -221,3 +221,4 @@
469995a8e97424f450c880606d689bf345277b19 jdk8-b97
3370fb6146e47a6cc05a213fc213e12fc0a38d07 jdk8-b98
3f67804ab61303782df57e54989ef5e0e4629beb jdk8-b99
+8d492f1dfd1b131a4c7886ee6b59528609f7e4fe jdk8-b100
--- a/hotspot/.hgtags Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/.hgtags Fri Jul 26 13:34:22 2013 -0700
@@ -361,3 +361,5 @@
2b9946e10587f74ef75ae8145bea484df4a2738b hs25-b41
81b6cb70717c66375846b78bb174594ec3aa998e jdk8-b99
9f71e36a471ae4a668e08827d33035963ed10c08 hs25-b42
+5787fac72e760c6a5fd9efa113b0c75caf554136 jdk8-b100
+46487ba40ff225654d0c51787ed3839bafcbd9f3 hs25-b43
--- a/hotspot/make/hotspot_version Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/make/hotspot_version Fri Jul 26 13:34:22 2013 -0700
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=43
+HS_BUILD_NUMBER=44
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/linux/makefiles/vm.make Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/make/linux/makefiles/vm.make Fri Jul 26 13:34:22 2013 -0700
@@ -212,6 +212,12 @@
Src_Files_EXCLUDE += \*x86_32\*
endif
+# Alternate vm.make
+# This has to be included here to allow changes to the source
+# directories and excluded files before they are expanded
+# by the definition of Src_Files.
+-include $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/vm.make
+
# Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
define findsrc
$(notdir $(shell find $(1)/. ! -name . -prune \
@@ -381,4 +387,4 @@
install: install_jvm install_jsig install_saproc
-.PHONY: default build install install_jvm $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/$(BUILDARCH).make
+.PHONY: default build install install_jvm $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/$(BUILDARCH).make $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/vm.make
--- a/hotspot/make/windows/makefiles/compile.make Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/make/windows/makefiles/compile.make Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2013, 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
@@ -110,6 +110,7 @@
# 1400 is for VS2005
# 1500 is for VS2008
# 1600 is for VS2010
+# 1700 is for VS2012
# Do not confuse this MSC_VER with the predefined macro _MSC_VER that the
# compiler provides, when MSC_VER==1399, _MSC_VER will be 1400.
# Normally they are the same, but a pre-release of the VS2005 compilers
@@ -142,6 +143,9 @@
!if "$(MSC_VER)" == "1600"
COMPILER_NAME=VS2010
!endif
+!if "$(MSC_VER)" == "1700"
+COMPILER_NAME=VS2012
+!endif
!endif
# By default, we do not want to use the debug version of the msvcrt.dll file
@@ -151,9 +155,13 @@
MS_RUNTIME_OPTION = /MTd /D "_DEBUG"
!endif
+# VS2012 and later won't work with:
+# /D _STATIC_CPPLIB /D _DISABLE_DEPRECATE_STATIC_CPPLIB
+!if "$(MSC_VER)" < "1700"
# Always add the _STATIC_CPPLIB flag
STATIC_CPPLIB_OPTION = /D _STATIC_CPPLIB /D _DISABLE_DEPRECATE_STATIC_CPPLIB
MS_RUNTIME_OPTION = $(MS_RUNTIME_OPTION) $(STATIC_CPPLIB_OPTION)
+!endif
CXX_FLAGS=$(CXX_FLAGS) $(MS_RUNTIME_OPTION)
# How /GX option is spelled
@@ -221,6 +229,22 @@
!endif
!endif
+!if "$(COMPILER_NAME)" == "VS2012"
+PRODUCT_OPT_OPTION = /O2 /Oy-
+FASTDEBUG_OPT_OPTION = /O2 /Oy-
+DEBUG_OPT_OPTION = /Od
+GX_OPTION = /EHsc
+LD_FLAGS = /manifest $(LD_FLAGS)
+# Manifest Tool - used in VS2005 and later to adjust manifests stored
+# as resources inside build artifacts.
+!if "x$(MT)" == "x"
+MT=mt.exe
+!endif
+!if "$(BUILDARCH)" == "i486"
+LD_FLAGS = /SAFESEH $(LD_FLAGS)
+!endif
+!endif
+
# If NO_OPTIMIZATIONS is defined in the environment, turn everything off
!ifdef NO_OPTIMIZATIONS
PRODUCT_OPT_OPTION = $(DEBUG_OPT_OPTION)
--- a/hotspot/make/windows/makefiles/sanity.make Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/make/windows/makefiles/sanity.make Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2013, 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
@@ -27,9 +27,9 @@
all: checkCL checkLink
checkCL:
- @ if "$(MSC_VER)" NEQ "1310" if "$(MSC_VER)" NEQ "1399" if "$(MSC_VER)" NEQ "1400" if "$(MSC_VER)" NEQ "1500" if "$(MSC_VER)" NEQ "1600" \
+ @ if "$(MSC_VER)" NEQ "1310" if "$(MSC_VER)" NEQ "1399" if "$(MSC_VER)" NEQ "1400" if "$(MSC_VER)" NEQ "1500" if "$(MSC_VER)" NEQ "1600" if "$(MSC_VER)" NEQ "1700" \
echo *** WARNING *** unrecognized cl.exe version $(MSC_VER) ($(RAW_MSC_VER)). Use FORCE_MSC_VER to override automatic detection.
checkLink:
- @ if "$(LD_VER)" NEQ "710" if "$(LD_VER)" NEQ "800" if "$(LD_VER)" NEQ "900" if "$(LD_VER)" NEQ "1000" \
+ @ if "$(LD_VER)" NEQ "710" if "$(LD_VER)" NEQ "800" if "$(LD_VER)" NEQ "900" if "$(LD_VER)" NEQ "1000" if "$(LD_VER)" NEQ "1100" \
echo *** WARNING *** unrecognized link.exe version $(LD_VER) ($(RAW_LD_VER)). Use FORCE_LD_VER to override automatic detection.
--- a/hotspot/make/windows/makefiles/vm.make Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/make/windows/makefiles/vm.make Fri Jul 26 13:34:22 2013 -0700
@@ -132,6 +132,10 @@
!if "$(USE_PRECOMPILED_HEADER)" != "0"
CXX_USE_PCH=/Fp"vm.pch" /Yu"precompiled.hpp"
+!if "$(COMPILER_NAME)" == "VS2012"
+# VS2012 requires this object file to be listed:
+LD_FLAGS=$(LD_FLAGS) _build_pch_file.obj
+!endif
!else
CXX_USE_PCH=$(CXX_DONT_USE_PCH)
!endif
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -240,10 +240,10 @@
#endif // CC_INTERP
-inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
+inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
// note: adjust this code if the link argument in StubGenerator::call_stub() changes!
const Argument link = Argument(0, false);
- return (JavaCallWrapper*)sp()[link.as_in().as_register()->sp_offset_in_saved_window()];
+ return (JavaCallWrapper**)&sp()[link.as_in().as_register()->sp_offset_in_saved_window()];
}
--- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -272,11 +272,10 @@
// Entry frames
-inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
- return (JavaCallWrapper*)at(entry_frame_call_wrapper_offset);
+inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
+ return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset);
}
-
// Compiled frames
inline int frame::local_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors) {
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -279,7 +279,7 @@
__ stmxcsr(mxcsr_save);
__ movl(rax, mxcsr_save);
__ andl(rax, MXCSR_MASK); // Only check control and mask bits
- ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std());
+ ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
__ cmp32(rax, mxcsr_std);
__ jcc(Assembler::equal, skip_ldmx);
__ ldmxcsr(mxcsr_std);
@@ -729,17 +729,18 @@
if (CheckJNICalls) {
Label ok_ret;
+ ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
__ push(rax);
__ subptr(rsp, wordSize); // allocate a temp location
__ stmxcsr(mxcsr_save);
__ movl(rax, mxcsr_save);
__ andl(rax, MXCSR_MASK); // Only check control and mask bits
- __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std()));
+ __ cmp32(rax, mxcsr_std);
__ jcc(Assembler::equal, ok_ret);
__ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
- __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std()));
+ __ ldmxcsr(mxcsr_std);
__ bind(ok_ret);
__ addptr(rsp, wordSize);
@@ -3767,12 +3768,35 @@
return stub->entry_point();
}
+ void create_control_words() {
+ // Round to nearest, 53-bit mode, exceptions masked
+ StubRoutines::_fpu_cntrl_wrd_std = 0x027F;
+ // Round to zero, 53-bit mode, exception mased
+ StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F;
+ // Round to nearest, 24-bit mode, exceptions masked
+ StubRoutines::_fpu_cntrl_wrd_24 = 0x007F;
+ // Round to nearest, 64-bit mode, exceptions masked
+ StubRoutines::_fpu_cntrl_wrd_64 = 0x037F;
+ // Round to nearest, 64-bit mode, exceptions masked
+ StubRoutines::_mxcsr_std = 0x1F80;
+ // Note: the following two constants are 80-bit values
+ // layout is critical for correct loading by FPU.
+ // Bias for strict fp multiply/divide
+ StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
+ StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000;
+ StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff;
+ // Un-Bias for strict fp multiply/divide
+ StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
+ StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000;
+ StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff;
+ }
+
// Initialization
void generate_initial() {
// Generates all stubs and initializes the entry points
- // This platform-specific stub is needed by generate_call_stub()
- StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80);
+ // This platform-specific settings are needed by generate_call_stub()
+ create_control_words();
// entry points that exist in all platforms Note: This is code
// that could be shared among different platforms - however the
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -42,4 +42,3 @@
address StubRoutines::x86::_float_sign_flip = NULL;
address StubRoutines::x86::_double_sign_mask = NULL;
address StubRoutines::x86::_double_sign_flip = NULL;
-address StubRoutines::x86::_mxcsr_std = NULL;
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -52,7 +52,6 @@
static address _float_sign_flip;
static address _double_sign_mask;
static address _double_sign_flip;
- static address _mxcsr_std;
public:
@@ -106,11 +105,6 @@
return _double_sign_flip;
}
- static address mxcsr_std()
- {
- return _mxcsr_std;
- }
-
# include "stubRoutines_x86.hpp"
};
--- a/hotspot/src/os/bsd/vm/attachListener_bsd.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/bsd/vm/attachListener_bsd.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -437,6 +437,30 @@
return op;
}
+
+// Performs initialization at vm startup
+// For BSD we remove any stale .java_pid file which could cause
+// an attaching process to think we are ready to receive on the
+// domain socket before we are properly initialized
+
+void AttachListener::vm_start() {
+ char fn[UNIX_PATH_MAX];
+ struct stat64 st;
+ int ret;
+
+ int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d",
+ os::get_temp_directory(), os::current_process_id());
+ assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow");
+
+ RESTARTABLE(::stat64(fn, &st), ret);
+ if (ret == 0) {
+ ret = ::unlink(fn);
+ if (ret == -1) {
+ debug_only(warning("failed to remove stale attach pid file at %s", fn));
+ }
+ }
+}
+
int AttachListener::pd_init() {
JavaThread* thread = JavaThread::current();
ThreadBlockInVM tbivm(thread);
--- a/hotspot/src/os/linux/vm/attachListener_linux.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -432,6 +432,30 @@
return op;
}
+
+// Performs initialization at vm startup
+// For Linux we remove any stale .java_pid file which could cause
+// an attaching process to think we are ready to receive on the
+// domain socket before we are properly initialized
+
+void AttachListener::vm_start() {
+ char fn[UNIX_PATH_MAX];
+ struct stat64 st;
+ int ret;
+
+ int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d",
+ os::get_temp_directory(), os::current_process_id());
+ assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow");
+
+ RESTARTABLE(::stat64(fn, &st), ret);
+ if (ret == 0) {
+ ret = ::unlink(fn);
+ if (ret == -1) {
+ debug_only(warning("failed to remove stale attach pid file at %s", fn));
+ }
+ }
+}
+
int AttachListener::pd_init() {
JavaThread* thread = JavaThread::current();
ThreadBlockInVM tbivm(thread);
--- a/hotspot/src/os/linux/vm/jsig.c Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/linux/vm/jsig.c Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, 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
@@ -107,7 +107,7 @@
signal_lock();
- sigused = (MASK(sig) & jvmsigs) != 0;
+ sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0);
if (jvm_signal_installed && sigused) {
/* jvm has installed its signal handler for this signal. */
/* Save the handler. Don't really install it. */
@@ -116,7 +116,7 @@
signal_unlock();
return oldhandler;
- } else if (jvm_signal_installing) {
+ } else if (sig < MAXSIGNUM && jvm_signal_installing) {
/* jvm is installing its signal handlers. Install the new
* handlers and save the old ones. jvm uses sigaction().
* Leave the piece here just in case. */
@@ -165,7 +165,7 @@
signal_lock();
- sigused = (MASK(sig) & jvmsigs) != 0;
+ sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0);
if (jvm_signal_installed && sigused) {
/* jvm has installed its signal handler for this signal. */
/* Save the handler. Don't really install it. */
@@ -178,7 +178,7 @@
signal_unlock();
return 0;
- } else if (jvm_signal_installing) {
+ } else if (sig < MAXSIGNUM && jvm_signal_installing) {
/* jvm is installing its signal handlers. Install the new
* handlers and save the old ones. */
res = call_os_sigaction(sig, act, &oldAct);
--- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -259,3 +259,52 @@
FILE* os::open(int fd, const char* mode) {
return ::fdopen(fd, mode);
}
+
+os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
+ assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
+}
+
+/*
+ * See the caveats for this class in os_posix.hpp
+ * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
+ * method and returns false. If none of the signals are raised, returns true.
+ * The callback is supposed to provide the method that should be protected.
+ */
+bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
+ assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
+ assert(!WatcherThread::watcher_thread()->has_crash_protection(),
+ "crash_protection already set?");
+
+ if (sigsetjmp(_jmpbuf, 1) == 0) {
+ // make sure we can see in the signal handler that we have crash protection
+ // installed
+ WatcherThread::watcher_thread()->set_crash_protection(this);
+ cb.call();
+ // and clear the crash protection
+ WatcherThread::watcher_thread()->set_crash_protection(NULL);
+ return true;
+ }
+ // this happens when we siglongjmp() back
+ WatcherThread::watcher_thread()->set_crash_protection(NULL);
+ return false;
+}
+
+void os::WatcherThreadCrashProtection::restore() {
+ assert(WatcherThread::watcher_thread()->has_crash_protection(),
+ "must have crash protection");
+
+ siglongjmp(_jmpbuf, 1);
+}
+
+void os::WatcherThreadCrashProtection::check_crash_protection(int sig,
+ Thread* thread) {
+
+ if (thread != NULL &&
+ thread->is_Watcher_thread() &&
+ WatcherThread::watcher_thread()->has_crash_protection()) {
+
+ if (sig == SIGSEGV || sig == SIGBUS) {
+ WatcherThread::watcher_thread()->crash_protection()->restore();
+ }
+ }
+}
--- a/hotspot/src/os/posix/vm/os_posix.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -37,5 +37,24 @@
};
+/*
+ * Crash protection for the watcher thread. Wrap the callback
+ * with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp
+ * back.
+ * To be able to use this - don't take locks, don't rely on destructors,
+ * don't make OS library calls, don't allocate memory, don't print,
+ * don't call code that could leave the heap / memory in an inconsistent state,
+ * or anything else where we are not in control if we suddenly jump out.
+ */
+class WatcherThreadCrashProtection : public StackObj {
+public:
+ WatcherThreadCrashProtection();
+ bool call(os::CrashProtectionCallback& cb);
+
+ static void check_crash_protection(int signal, Thread* thread);
+private:
+ void restore();
+ sigjmp_buf _jmpbuf;
+};
#endif
--- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -576,6 +576,30 @@
return op;
}
+
+// Performs initialization at vm startup
+// For Solaris we remove any stale .java_pid file which could cause
+// an attaching process to think we are ready to receive a door_call
+// before we are properly initialized
+
+void AttachListener::vm_start() {
+ char fn[PATH_MAX+1];
+ struct stat64 st;
+ int ret;
+
+ int n = snprintf(fn, sizeof(fn), "%s/.java_pid%d",
+ os::get_temp_directory(), os::current_process_id());
+ assert(n < sizeof(fn), "java_pid file name buffer overflow");
+
+ RESTARTABLE(::stat64(fn, &st), ret);
+ if (ret == 0) {
+ ret = ::unlink(fn);
+ if (ret == -1) {
+ debug_only(warning("failed to remove stale attach pid file at %s", fn));
+ }
+ }
+}
+
int AttachListener::pd_init() {
JavaThread* thread = JavaThread::current();
ThreadBlockInVM tbivm(thread);
--- a/hotspot/src/os/windows/vm/attachListener_windows.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/windows/vm/attachListener_windows.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -358,6 +358,10 @@
return op;
}
+void AttachListener::vm_start() {
+ // nothing to do
+}
+
int AttachListener::pd_init() {
return Win32AttachListener::init();
}
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -4689,6 +4689,34 @@
}
}
+os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
+ assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
+}
+
+/*
+ * See the caveats for this class in os_windows.hpp
+ * Protects the callback call so that raised OS EXCEPTIONS causes a jump back
+ * into this method and returns false. If no OS EXCEPTION was raised, returns
+ * true.
+ * The callback is supposed to provide the method that should be protected.
+ */
+bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
+ assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
+ assert(!WatcherThread::watcher_thread()->has_crash_protection(),
+ "crash_protection already set?");
+
+ bool success = true;
+ __try {
+ WatcherThread::watcher_thread()->set_crash_protection(this);
+ cb.call();
+ } __except(EXCEPTION_EXECUTE_HANDLER) {
+ // only for protection, nothing to do
+ success = false;
+ }
+ WatcherThread::watcher_thread()->set_crash_protection(NULL);
+ return success;
+}
+
// An Event wraps a win32 "CreateEvent" kernel handle.
//
// We have a number of choices regarding "CreateEvent" win32 handle leakage:
--- a/hotspot/src/os/windows/vm/os_windows.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -102,6 +102,20 @@
static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
};
+/*
+ * Crash protection for the watcher thread. Wrap the callback
+ * with a __try { call() }
+ * To be able to use this - don't take locks, don't rely on destructors,
+ * don't make OS library calls, don't allocate memory, don't print,
+ * don't call code that could leave the heap / memory in an inconsistent state,
+ * or anything else where we are not in control if we suddenly jump out.
+ */
+class WatcherThreadCrashProtection : public StackObj {
+public:
+ WatcherThreadCrashProtection();
+ bool call(os::CrashProtectionCallback& cb);
+};
+
class PlatformEvent : public CHeapObj<mtInternal> {
private:
double CachePad [4] ; // increase odds that _Event is sole occupant of cache line
--- a/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -72,7 +72,7 @@
inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; }
inline julong OrderAccess::load_acquire(volatile julong* p) { return Atomic::load((volatile jlong*)p); }
inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; }
-inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; }
+inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return jdouble_cast(Atomic::load((volatile jlong*)p)); }
inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; }
inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; }
@@ -87,7 +87,7 @@
inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; }
inline void OrderAccess::release_store(volatile julong* p, julong v) { Atomic::store((jlong)v, (volatile jlong*)p); }
inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; }
-inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; }
+inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { release_store((volatile jlong*)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; }
inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; }
@@ -190,7 +190,7 @@
inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store_fence((volatile jlong*)p, (jlong)v); }
inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store_fence((volatile jlong*)p, jdouble_cast(v)); }
inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) {
#ifdef AMD64
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -394,6 +394,10 @@
Thread* t = ThreadLocalStorage::get_thread_slow();
+ // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+ // (no destructors can be run)
+ os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
SignalHandlerMark shm(t);
// Note: it's not uncommon that JNI code uses signal/sigset to install
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -544,6 +544,10 @@
Thread* t = ThreadLocalStorage::get_thread_slow();
+ // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+ // (no destructors can be run)
+ os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
SignalHandlerMark shm(t);
// Note: it's not uncommon that JNI code uses signal/sigset to install
--- a/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -72,7 +72,7 @@
inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; }
inline julong OrderAccess::load_acquire(volatile julong* p) { return Atomic::load((volatile jlong*)p); }
inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; }
-inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; }
+inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return jdouble_cast(Atomic::load((volatile jlong*)p)); }
inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; }
inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; }
@@ -87,7 +87,7 @@
inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; }
inline void OrderAccess::release_store(volatile julong* p, julong v) { Atomic::store((jlong)v, (volatile jlong*)p); }
inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; }
-inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; }
+inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { release_store((volatile jlong *)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; }
inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; }
@@ -129,7 +129,7 @@
inline void OrderAccess::store_fence(juint* p, juint v) { store_fence((jint*)p, (jint)v); }
inline void OrderAccess::store_fence(julong* p, julong v) { store_fence((jlong*)p, (jlong)v); }
inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); }
-inline void OrderAccess::store_fence(jdouble* p, jdouble v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jdouble* p, jdouble v) { store_fence((jlong*)p, jlong_cast(v)); }
inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) {
#ifdef AMD64
@@ -190,7 +190,7 @@
inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store_fence((volatile jlong*)p, (jlong)v); }
inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store_fence((volatile jlong*)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) {
#ifdef AMD64
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -218,6 +218,10 @@
Thread* t = ThreadLocalStorage::get_thread_slow();
+ // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+ // (no destructors can be run)
+ os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
SignalHandlerMark shm(t);
// Note: it's not uncommon that JNI code uses signal/sigset to install
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -310,6 +310,10 @@
Thread* t = ThreadLocalStorage::get_thread_slow();
+ // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+ // (no destructors can be run)
+ os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
SignalHandlerMark shm(t);
if(sig == SIGPIPE || sig == SIGXFSZ) {
--- a/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -88,7 +88,7 @@
inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; }
inline julong OrderAccess::load_acquire(volatile julong* p) { return Atomic::load((volatile jlong*)p); }
inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; }
-inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; }
+inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return jdouble_cast(Atomic::load((volatile jlong*)p)); }
inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; }
inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; }
@@ -103,7 +103,7 @@
inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; }
inline void OrderAccess::release_store(volatile julong* p, julong v) { Atomic::store((jlong)v, (volatile jlong*)p); }
inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; }
-inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; }
+inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { release_store((volatile jlong*)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; }
inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; }
@@ -129,9 +129,9 @@
inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { *p = v; fence(); }
inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { *p = v; fence(); }
inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store((jlong *)p, (jlong)v); fence(); }
inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store_fence((volatile jlong*)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { *p = v; fence(); }
inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { *(void* volatile *)p = v; fence(); }
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -367,6 +367,10 @@
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
+ // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
+ // (no destructors can be run)
+ os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
+
SignalHandlerMark shm(t);
if(sig == SIGPIPE || sig == SIGXFSZ) {
--- a/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -71,7 +71,7 @@
inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; }
inline julong OrderAccess::load_acquire(volatile julong* p) { return Atomic::load((volatile jlong*)p); }
inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; }
-inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; }
+inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return jdouble_cast(Atomic::load((volatile jlong*)p)); }
inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; }
inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; }
@@ -86,7 +86,7 @@
inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; }
inline void OrderAccess::release_store(volatile julong* p, julong v) { Atomic::store((jlong)v, (volatile jlong*)p); }
inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; }
-inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; }
+inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { release_store((volatile jlong*)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; }
inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; }
@@ -195,7 +195,7 @@
inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store_fence((volatile jint*)p, (jint)v); }
inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store_fence((volatile jlong*)p, (jlong)v); }
inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store_fence((volatile jlong*)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) {
#ifdef AMD64
--- a/hotspot/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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
@@ -29,10 +29,15 @@
#ifdef AMD64
typedef unsigned char UBYTE;
+#if _MSC_VER < 1700
+
+/* Not needed for VS2012 compiler, comes from winnt.h. */
#define UNW_FLAG_EHANDLER 0x01
#define UNW_FLAG_UHANDLER 0x02
#define UNW_FLAG_CHAININFO 0x04
+#endif
+
// This structure is used to define an UNWIND_INFO that
// only has an ExceptionHandler. There are no UnwindCodes
// declared.
@@ -59,6 +64,9 @@
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
*/
+#if _MSC_VER < 1700
+
+/* Not needed for VS2012 compiler, comes from winnt.h. */
typedef struct _DISPATCHER_CONTEXT {
ULONG64 ControlPc;
ULONG64 ImageBase;
@@ -71,6 +79,8 @@
PVOID HandlerData;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
+#endif
+
#if _MSC_VER < 1500
/* Not needed for VS2008 compiler, comes from winnt.h. */
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -138,6 +138,16 @@
return false;
}
+// return true if all argument elements of vars are returned
+bool BCEscapeAnalyzer::returns_all(ArgumentMap vars) {
+ for (int i = 0; i < _arg_size; i++) {
+ if (vars.contains(i) && !_arg_returned.test(i)) {
+ return false;
+ }
+ }
+ return true;
+}
+
void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) {
for (int i = 0; i < _arg_size; i++) {
if (vars.contains(i)) {
@@ -166,6 +176,11 @@
if (vars.contains_unknown() || vars.contains_vars()) {
_return_allocated = false;
}
+ if (_return_local && vars.contains_vars() && !returns_all(vars)) {
+ // Return result should be invalidated if args in new
+ // state are not recorded in return state.
+ _return_local = false;
+ }
}
}
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -80,6 +80,7 @@
void set_returned(ArgumentMap vars);
bool is_argument(ArgumentMap vars);
bool is_arg_stack(ArgumentMap vars);
+ bool returns_all(ArgumentMap vars);
void clear_bits(ArgumentMap vars, VectorSet &bs);
void set_method_escape(ArgumentMap vars);
void set_global_escape(ArgumentMap vars, bool merge = false);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -3647,8 +3647,7 @@
// If RedefineClasses() was used before the retransformable
// agent attached, then the cached class bytes may not be the
// original class bytes.
- unsigned char *cached_class_file_bytes = NULL;
- jint cached_class_file_length;
+ JvmtiCachedClassFileData *cached_class_file = NULL;
Handle class_loader(THREAD, loader_data->class_loader());
bool has_default_methods = false;
ResourceMark rm(THREAD);
@@ -3680,10 +3679,7 @@
if (h_class_being_redefined != NULL) {
instanceKlassHandle ikh_class_being_redefined =
instanceKlassHandle(THREAD, (*h_class_being_redefined)());
- cached_class_file_bytes =
- ikh_class_being_redefined->get_cached_class_file_bytes();
- cached_class_file_length =
- ikh_class_being_redefined->get_cached_class_file_len();
+ cached_class_file = ikh_class_being_redefined->get_cached_class_file();
}
}
@@ -3691,9 +3687,7 @@
unsigned char* end_ptr = cfs->buffer() + cfs->length();
JvmtiExport::post_class_file_load_hook(name, class_loader(), protection_domain,
- &ptr, &end_ptr,
- &cached_class_file_bytes,
- &cached_class_file_length);
+ &ptr, &end_ptr, &cached_class_file);
if (ptr != cfs->buffer()) {
// JVMTI agent has modified class file data.
@@ -4011,10 +4005,9 @@
}
}
- if (cached_class_file_bytes != NULL) {
+ if (cached_class_file != NULL) {
// JVMTI: we have an InstanceKlass now, tell it about the cached bytes
- this_klass->set_cached_class_file(cached_class_file_bytes,
- cached_class_file_length);
+ this_klass->set_cached_class_file(cached_class_file);
}
// Fill in field values obtained by parse_classfile_attributes
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -53,8 +53,6 @@
template(java_lang_Object, "java/lang/Object") \
template(java_lang_Class, "java/lang/Class") \
template(java_lang_String, "java/lang/String") \
- template(java_lang_StringValue, "java/lang/StringValue") \
- template(java_lang_StringCache, "java/lang/StringValue$StringCache") \
template(java_lang_Thread, "java/lang/Thread") \
template(java_lang_ThreadGroup, "java/lang/ThreadGroup") \
template(java_lang_Cloneable, "java/lang/Cloneable") \
@@ -106,7 +104,6 @@
template(java_util_Vector, "java/util/Vector") \
template(java_util_AbstractList, "java/util/AbstractList") \
template(java_util_Hashtable, "java/util/Hashtable") \
- template(java_util_HashMap, "java/util/HashMap") \
template(java_lang_Compiler, "java/lang/Compiler") \
template(sun_misc_Signal, "sun/misc/Signal") \
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
@@ -367,8 +364,6 @@
template(offset_name, "offset") \
template(count_name, "count") \
template(hash_name, "hash") \
- template(frontCacheEnabled_name, "frontCacheEnabled") \
- template(stringCacheEnabled_name, "stringCacheEnabled") \
template(numberOfLeadingZeros_name, "numberOfLeadingZeros") \
template(numberOfTrailingZeros_name, "numberOfTrailingZeros") \
template(bitCount_name, "bitCount") \
--- a/hotspot/src/share/vm/memory/resourceArea.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/memory/resourceArea.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -83,6 +83,10 @@
Chunk *_chunk; // saved arena chunk
char *_hwm, *_max;
size_t _size_in_bytes;
+#ifdef ASSERT
+ Thread* _thread;
+ ResourceMark* _previous_resource_mark;
+#endif //ASSERT
void initialize(Thread *thread) {
_area = thread->resource_area();
@@ -92,6 +96,11 @@
_size_in_bytes = _area->size_in_bytes();
debug_only(_area->_nesting++;)
assert( _area->_nesting > 0, "must stack allocate RMs" );
+#ifdef ASSERT
+ _thread = thread;
+ _previous_resource_mark = thread->current_resource_mark();
+ thread->set_current_resource_mark(this);
+#endif // ASSERT
}
public:
@@ -111,6 +120,17 @@
_size_in_bytes = r->_size_in_bytes;
debug_only(_area->_nesting++;)
assert( _area->_nesting > 0, "must stack allocate RMs" );
+#ifdef ASSERT
+ Thread* thread = ThreadLocalStorage::thread();
+ if (thread != NULL) {
+ _thread = thread;
+ _previous_resource_mark = thread->current_resource_mark();
+ thread->set_current_resource_mark(this);
+ } else {
+ _thread = NULL;
+ _previous_resource_mark = NULL;
+ }
+#endif // ASSERT
}
void reset_to_mark() {
@@ -137,6 +157,11 @@
assert( _area->_nesting > 0, "must stack allocate RMs" );
debug_only(_area->_nesting--;)
reset_to_mark();
+#ifdef ASSERT
+ if (_thread != NULL) {
+ _thread->set_current_resource_mark(_previous_resource_mark);
+ }
+#endif // ASSERT
}
--- a/hotspot/src/share/vm/oops/cpCache.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -140,8 +140,15 @@
_f1 = f1;
}
void release_set_f1(Metadata* f1);
- void set_f2(intx f2) { assert(_f2 == 0 || _f2 == f2, "illegal field change"); _f2 = f2; }
- void set_f2_as_vfinal_method(Method* f2) { assert(_f2 == 0 || _f2 == (intptr_t) f2, "illegal field change"); assert(is_vfinal(), "flags must be set"); _f2 = (intptr_t) f2; }
+ void set_f2(intx f2) {
+ intx existing_f2 = _f2; // read once
+ assert(existing_f2 == 0 || existing_f2 == f2, "illegal field change");
+ _f2 = f2;
+ }
+ void set_f2_as_vfinal_method(Method* f2) {
+ assert(is_vfinal(), "flags must be set");
+ set_f2((intx)f2);
+ }
int make_flags(TosState state, int option_bits, int field_index_or_method_params);
void set_flags(intx flags) { _flags = flags; }
bool init_flags_atomic(intx flags);
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -48,6 +48,7 @@
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
+#include "prims/jvmtiRedefineClasses.hpp"
#include "prims/methodComparator.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
@@ -291,7 +292,7 @@
set_initial_method_idnum(0);
_dependencies = NULL;
set_jvmti_cached_class_field_map(NULL);
- set_cached_class_file(NULL, 0);
+ set_cached_class_file(NULL);
set_initial_method_idnum(0);
set_minor_version(0);
set_major_version(0);
@@ -2357,10 +2358,9 @@
}
// deallocate the cached class file
- if (_cached_class_file_bytes != NULL) {
- os::free(_cached_class_file_bytes, mtClass);
- _cached_class_file_bytes = NULL;
- _cached_class_file_len = 0;
+ if (_cached_class_file != NULL) {
+ os::free(_cached_class_file, mtClass);
+ _cached_class_file = NULL;
}
// Decrement symbol reference counts associated with the unloaded class.
@@ -3530,6 +3530,14 @@
return m;
}
+jint InstanceKlass::get_cached_class_file_len() {
+ return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file);
+}
+
+unsigned char * InstanceKlass::get_cached_class_file_bytes() {
+ return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
+}
+
// Construct a PreviousVersionNode entry for the array hung off
// the InstanceKlass.
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -133,6 +133,8 @@
uint _count;
};
+struct JvmtiCachedClassFileData;
+
class InstanceKlass: public Klass {
friend class VMStructs;
friend class ClassFileParser;
@@ -249,8 +251,8 @@
// InstanceKlass. See PreviousVersionWalker below.
GrowableArray<PreviousVersionNode *>* _previous_versions;
// JVMTI fields can be moved to their own structure - see 6315920
- unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH
- jint _cached_class_file_len; // JVMTI: length of above
+ // JVMTI: cached class file, before retransformable agent modified it in CFLH
+ JvmtiCachedClassFileData* _cached_class_file;
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
@@ -615,11 +617,12 @@
static void purge_previous_versions(InstanceKlass* ik);
// JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation
- void set_cached_class_file(unsigned char *class_file_bytes,
- jint class_file_len) { _cached_class_file_len = class_file_len;
- _cached_class_file_bytes = class_file_bytes; }
- jint get_cached_class_file_len() { return _cached_class_file_len; }
- unsigned char * get_cached_class_file_bytes() { return _cached_class_file_bytes; }
+ void set_cached_class_file(JvmtiCachedClassFileData *data) {
+ _cached_class_file = data;
+ }
+ JvmtiCachedClassFileData * get_cached_class_file() { return _cached_class_file; }
+ jint get_cached_class_file_len();
+ unsigned char * get_cached_class_file_bytes();
// JVMTI: Support for caching of field indices, types, and offsets
void set_jvmti_cached_class_field_map(JvmtiCachedClassFieldMap* descriptor) {
--- a/hotspot/src/share/vm/oops/method.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -1163,6 +1163,7 @@
newm->constMethod()->set_constMethod_size(new_const_method_size);
newm->set_method_size(new_method_size);
assert(newm->code_size() == new_code_length, "check");
+ assert(newm->method_parameters_length() == method_parameters_len, "check");
assert(newm->checked_exceptions_length() == checked_exceptions_len, "check");
assert(newm->exception_table_length() == exception_table_len, "check");
assert(newm->localvariable_table_length() == localvariable_len, "check");
@@ -1174,6 +1175,12 @@
new_compressed_linenumber_table,
new_compressed_linenumber_size);
}
+ // Copy method_parameters
+ if (method_parameters_len > 0) {
+ memcpy(newm->method_parameters_start(),
+ m->method_parameters_start(),
+ method_parameters_len * sizeof(MethodParametersElement));
+ }
// Copy checked_exceptions
if (checked_exceptions_len > 0) {
memcpy(newm->checked_exceptions_start(),
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -297,15 +297,6 @@
}
}
- if (UseStringCache) {
- // Do not inline StringCache::profile() method used only at the beginning.
- if (callee_method->name() == ciSymbol::profile_name() &&
- callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
- set_msg("profiling method");
- return true;
- }
- }
-
// use frequency-based objections only for non-trivial methods
if (callee_method->code_size() <= MaxTrivialSize) {
return false;
--- a/hotspot/src/share/vm/opto/matcher.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/opto/matcher.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -2305,26 +2305,26 @@
// atomic instruction acting as a store_load barrier without any
// intervening volatile load, and thus we don't need a barrier here.
// We retain the Node to act as a compiler ordering barrier.
-bool Matcher::post_store_load_barrier(const Node *vmb) {
- Compile *C = Compile::current();
- assert( vmb->is_MemBar(), "" );
- assert( vmb->Opcode() != Op_MemBarAcquire, "" );
- const MemBarNode *mem = (const MemBarNode*)vmb;
+bool Matcher::post_store_load_barrier(const Node* vmb) {
+ Compile* C = Compile::current();
+ assert(vmb->is_MemBar(), "");
+ assert(vmb->Opcode() != Op_MemBarAcquire, "");
+ const MemBarNode* membar = vmb->as_MemBar();
- // Get the Proj node, ctrl, that can be used to iterate forward
- Node *ctrl = NULL;
- DUIterator_Fast imax, i = mem->fast_outs(imax);
- while( true ) {
- ctrl = mem->fast_out(i); // Throw out-of-bounds if proj not found
- assert( ctrl->is_Proj(), "only projections here" );
- ProjNode *proj = (ProjNode*)ctrl;
- if( proj->_con == TypeFunc::Control &&
- !C->node_arena()->contains(ctrl) ) // Unmatched old-space only
+ // Get the Ideal Proj node, ctrl, that can be used to iterate forward
+ Node* ctrl = NULL;
+ for (DUIterator_Fast imax, i = membar->fast_outs(imax); i < imax; i++) {
+ Node* p = membar->fast_out(i);
+ assert(p->is_Proj(), "only projections here");
+ if ((p->as_Proj()->_con == TypeFunc::Control) &&
+ !C->node_arena()->contains(p)) { // Unmatched old-space only
+ ctrl = p;
break;
- i++;
+ }
}
+ assert((ctrl != NULL), "missing control projection");
- for( DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++ ) {
+ for (DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++) {
Node *x = ctrl->fast_out(j);
int xop = x->Opcode();
@@ -2336,37 +2336,36 @@
// that a monitor exit operation contains a serializing instruction.
if (xop == Op_MemBarVolatile ||
- xop == Op_FastLock ||
xop == Op_CompareAndSwapL ||
xop == Op_CompareAndSwapP ||
xop == Op_CompareAndSwapN ||
- xop == Op_CompareAndSwapI)
+ xop == Op_CompareAndSwapI) {
return true;
+ }
+
+ // Op_FastLock previously appeared in the Op_* list above.
+ // With biased locking we're no longer guaranteed that a monitor
+ // enter operation contains a serializing instruction.
+ if ((xop == Op_FastLock) && !UseBiasedLocking) {
+ return true;
+ }
if (x->is_MemBar()) {
// We must retain this membar if there is an upcoming volatile
- // load, which will be preceded by acquire membar.
- if (xop == Op_MemBarAcquire)
+ // load, which will be followed by acquire membar.
+ if (xop == Op_MemBarAcquire) {
return false;
- // For other kinds of barriers, check by pretending we
- // are them, and seeing if we can be removed.
- else
- return post_store_load_barrier((const MemBarNode*)x);
+ } else {
+ // For other kinds of barriers, check by pretending we
+ // are them, and seeing if we can be removed.
+ return post_store_load_barrier(x->as_MemBar());
+ }
}
- // Delicate code to detect case of an upcoming fastlock block
- if( x->is_If() && x->req() > 1 &&
- !C->node_arena()->contains(x) ) { // Unmatched old-space only
- Node *iff = x;
- Node *bol = iff->in(1);
- // The iff might be some random subclass of If or bol might be Con-Top
- if (!bol->is_Bool()) return false;
- assert( bol->req() > 1, "" );
- return (bol->in(1)->Opcode() == Op_FastUnlock);
+ // probably not necessary to check for these
+ if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) {
+ return false;
}
- // probably not necessary to check for these
- if (x->is_Call() || x->is_SafePoint() || x->is_block_proj())
- return false;
}
return false;
}
--- a/hotspot/src/share/vm/opto/parse3.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/opto/parse3.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -294,25 +294,7 @@
// If reference is volatile, prevent following volatiles ops from
// floating up before the volatile write.
if (is_vol) {
- // First place the specific membar for THIS volatile index. This first
- // membar is dependent on the store, keeping any other membars generated
- // below from floating up past the store.
- int adr_idx = C->get_alias_index(adr_type);
- insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx, store);
-
- // Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed
- // volatile alias indices. Skip this if the membar is redundant.
- if (adr_idx != Compile::AliasIdxBot) {
- insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot, store);
- }
-
- // Finally, place alias-index-specific membars for each volatile index
- // that isn't the adr_idx membar. Typically there's only 1 or 2.
- for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) {
- if (i != adr_idx && C->alias_type(i)->is_volatile()) {
- insert_mem_bar_volatile(Op_MemBarVolatile, i, store);
- }
- }
+ insert_mem_bar(Op_MemBarVolatile); // Use fat membar
}
// If the field is final, the rules of Java say we are in <init> or <clinit>.
--- a/hotspot/src/share/vm/prims/forte.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/prims/forte.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -31,6 +31,7 @@
#include "oops/oop.inline.hpp"
#include "oops/oop.inline2.hpp"
#include "prims/forte.hpp"
+#include "runtime/javaCalls.hpp"
#include "runtime/thread.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vframeArray.hpp"
@@ -308,10 +309,14 @@
for (loop_count = 0; loop_count < loop_max; loop_count++) {
- if (candidate.is_first_frame()) {
+ if (candidate.is_entry_frame()) {
+ // jcw is NULL if the java call wrapper couldn't be found
+ JavaCallWrapper *jcw = candidate.entry_frame_call_wrapper_if_safe(thread);
// If initial frame is frame from StubGenerator and there is no
// previous anchor, there are no java frames associated with a method
- return false;
+ if (jcw == NULL || jcw->is_first_frame()) {
+ return false;
+ }
}
if (candidate.is_interpreted_frame()) {
--- a/hotspot/src/share/vm/prims/jniCheck.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -126,6 +126,7 @@
static const char * fatal_non_weak_method = "non-weak methodID passed to JNI call";
static const char * fatal_unknown_array_object = "Unknown array object passed to JNI array operations";
static const char * fatal_object_array_expected = "Object array expected but not received for JNI array operation";
+static const char * fatal_prim_type_array_expected = "Primitive type array expected but not received for JNI array operation";
static const char * fatal_non_array = "Non-array passed to JNI array operations";
static const char * fatal_element_type_mismatch = "Array element type mismatch in JNI";
static const char * fatal_should_be_static = "Non-static field ID passed to JNI";
@@ -278,30 +279,49 @@
ReportJNIFatalError(thr, fatal_non_string);
}
-static inline void
-checkArray(JavaThread* thr, jarray jArray, int elementType)
+static inline arrayOop
+check_is_array(JavaThread* thr, jarray jArray)
{
ASSERT_OOPS_ALLOWED;
arrayOop aOop;
aOop = (arrayOop)jniCheck::validate_object(thr, jArray);
- if (aOop == NULL || !aOop->is_array())
+ if (aOop == NULL || !aOop->is_array()) {
ReportJNIFatalError(thr, fatal_non_array);
+ }
+ return aOop;
+}
+
+static inline arrayOop
+check_is_primitive_array(JavaThread* thr, jarray jArray) {
+ arrayOop aOop = check_is_array(thr, jArray);
- if (elementType != -1) {
- if (aOop->is_typeArray()) {
- BasicType array_type = TypeArrayKlass::cast(aOop->klass())->element_type();
- if (array_type != elementType)
- ReportJNIFatalError(thr, fatal_element_type_mismatch);
- } else if (aOop->is_objArray()) {
- if ( T_OBJECT != elementType)
- ReportJNIFatalError(thr, fatal_object_array_expected);
- } else {
- ReportJNIFatalError(thr, fatal_unknown_array_object);
- }
+ if (!aOop->is_typeArray()) {
+ ReportJNIFatalError(thr, fatal_prim_type_array_expected);
+ }
+ return aOop;
+}
+
+static inline void
+check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType)
+{
+ BasicType array_type;
+ arrayOop aOop;
+
+ aOop = check_is_primitive_array(thr, jArray);
+ array_type = TypeArrayKlass::cast(aOop->klass())->element_type();
+ if (array_type != elementType) {
+ ReportJNIFatalError(thr, fatal_element_type_mismatch);
}
}
+static inline void
+check_is_obj_array(JavaThread* thr, jarray jArray) {
+ arrayOop aOop = check_is_array(thr, jArray);
+ if (!aOop->is_objArray()) {
+ ReportJNIFatalError(thr, fatal_object_array_expected);
+ }
+}
oop jniCheck::validate_handle(JavaThread* thr, jobject obj) {
if (JNIHandles::is_frame_handle(thr, obj) ||
@@ -1417,7 +1437,7 @@
jarray array))
functionEnter(thr);
IN_VM(
- checkArray(thr, array, -1);
+ check_is_array(thr, array);
)
jsize result = UNCHECKED()->GetArrayLength(env,array);
functionExit(env);
@@ -1441,7 +1461,7 @@
jsize index))
functionEnter(thr);
IN_VM(
- checkArray(thr, array, T_OBJECT);
+ check_is_obj_array(thr, array);
)
jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
functionExit(env);
@@ -1455,7 +1475,7 @@
jobject val))
functionEnter(thr);
IN_VM(
- checkArray(thr, array, T_OBJECT);
+ check_is_obj_array(thr, array);
)
UNCHECKED()->SetObjectArrayElement(env,array,index,val);
functionExit(env);
@@ -1487,7 +1507,7 @@
jboolean *isCopy)) \
functionEnter(thr); \
IN_VM( \
- checkArray(thr, array, ElementTag); \
+ check_primitive_array_type(thr, array, ElementTag); \
) \
ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \
array, \
@@ -1513,7 +1533,7 @@
jint mode)) \
functionEnterExceptionAllowed(thr); \
IN_VM( \
- checkArray(thr, array, ElementTag); \
+ check_primitive_array_type(thr, array, ElementTag); \
ASSERT_OOPS_ALLOWED; \
typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
/* cannot check validity of copy, unless every request is logged by
@@ -1543,7 +1563,7 @@
ElementType *buf)) \
functionEnter(thr); \
IN_VM( \
- checkArray(thr, array, ElementTag); \
+ check_primitive_array_type(thr, array, ElementTag); \
) \
UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \
functionExit(env); \
@@ -1567,7 +1587,7 @@
const ElementType *buf)) \
functionEnter(thr); \
IN_VM( \
- checkArray(thr, array, ElementTag); \
+ check_primitive_array_type(thr, array, ElementTag); \
) \
UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \
functionExit(env); \
@@ -1669,7 +1689,7 @@
jboolean *isCopy))
functionEnterCritical(thr);
IN_VM(
- checkArray(thr, array, -1);
+ check_is_primitive_array(thr, array);
)
void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy);
functionExit(env);
@@ -1683,7 +1703,7 @@
jint mode))
functionEnterCriticalExceptionAllowed(thr);
IN_VM(
- checkArray(thr, array, -1);
+ check_is_primitive_array(thr, array);
)
/* The Hotspot JNI code does not use the parameters, so just check the
* array parameter as a minor sanity check
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -41,6 +41,7 @@
#include "prims/jvmtiRawMonitor.hpp"
#include "prims/jvmtiTagMap.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
+#include "prims/jvmtiRedefineClasses.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -516,8 +517,7 @@
jint _curr_len;
unsigned char * _curr_data;
JvmtiEnv * _curr_env;
- jint * _cached_length_ptr;
- unsigned char ** _cached_data_ptr;
+ JvmtiCachedClassFileData ** _cached_class_file_ptr;
JvmtiThreadState * _state;
KlassHandle * _h_class_being_redefined;
JvmtiClassLoadKind _load_kind;
@@ -526,8 +526,7 @@
inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader,
Handle h_protection_domain,
unsigned char **data_ptr, unsigned char **end_ptr,
- unsigned char **cached_data_ptr,
- jint *cached_length_ptr) {
+ JvmtiCachedClassFileData **cache_ptr) {
_h_name = h_name;
_class_loader = class_loader;
_h_protection_domain = h_protection_domain;
@@ -537,8 +536,7 @@
_curr_len = *end_ptr - *data_ptr;
_curr_data = *data_ptr;
_curr_env = NULL;
- _cached_length_ptr = cached_length_ptr;
- _cached_data_ptr = cached_data_ptr;
+ _cached_class_file_ptr = cache_ptr;
_state = _thread->jvmti_thread_state();
if (_state != NULL) {
@@ -615,15 +613,20 @@
}
if (new_data != NULL) {
// this agent has modified class data.
- if (caching_needed && *_cached_data_ptr == NULL) {
+ if (caching_needed && *_cached_class_file_ptr == NULL) {
// data has been changed by the new retransformable agent
// and it hasn't already been cached, cache it
- *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len, mtInternal);
- if (*_cached_data_ptr == NULL) {
- vm_exit_out_of_memory(_curr_len, OOM_MALLOC_ERROR, "unable to allocate cached copy of original class bytes");
+ JvmtiCachedClassFileData *p;
+ p = (JvmtiCachedClassFileData *)os::malloc(
+ offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal);
+ if (p == NULL) {
+ vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len,
+ OOM_MALLOC_ERROR,
+ "unable to allocate cached copy of original class bytes");
}
- memcpy(*_cached_data_ptr, _curr_data, _curr_len);
- *_cached_length_ptr = _curr_len;
+ p->length = _curr_len;
+ memcpy(p->data, _curr_data, _curr_len);
+ *_cached_class_file_ptr = p;
}
if (_curr_data != *_data_ptr) {
@@ -662,13 +665,11 @@
Handle h_protection_domain,
unsigned char **data_ptr,
unsigned char **end_ptr,
- unsigned char **cached_data_ptr,
- jint *cached_length_ptr) {
+ JvmtiCachedClassFileData **cache_ptr) {
JvmtiClassFileLoadHookPoster poster(h_name, class_loader,
h_protection_domain,
data_ptr, end_ptr,
- cached_data_ptr,
- cached_length_ptr);
+ cache_ptr);
poster.post();
}
--- a/hotspot/src/share/vm/prims/jvmtiExport.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -323,8 +323,7 @@
static void post_class_file_load_hook(Symbol* h_name, Handle class_loader,
Handle h_protection_domain,
unsigned char **data_ptr, unsigned char **end_ptr,
- unsigned char **cached_data_ptr,
- jint *cached_length_ptr) NOT_JVMTI_RETURN;
+ JvmtiCachedClassFileData **cache_ptr) NOT_JVMTI_RETURN;
static void post_native_method_bind(Method* method, address* function_ptr) NOT_JVMTI_RETURN;
static void post_compiled_method_load(nmethod *nm) NOT_JVMTI_RETURN;
static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN;
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -3342,9 +3342,7 @@
// should get cleared in the_class too.
if (the_class->get_cached_class_file_bytes() == 0) {
// the_class doesn't have a cache yet so copy it
- the_class->set_cached_class_file(
- scratch_class->get_cached_class_file_bytes(),
- scratch_class->get_cached_class_file_len());
+ the_class->set_cached_class_file(scratch_class->get_cached_class_file());
}
#ifndef PRODUCT
else {
@@ -3357,7 +3355,7 @@
// NULL out in scratch class to not delete twice. The class to be redefined
// always owns these bytes.
- scratch_class->set_cached_class_file(NULL, 0);
+ scratch_class->set_cached_class_file(NULL);
// Replace inner_classes
Array<u2>* old_inner_classes = the_class->inner_classes();
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -331,6 +331,11 @@
// coordinate a cleanup of these constants with Runtime.
//
+struct JvmtiCachedClassFileData {
+ jint length;
+ unsigned char data[1];
+};
+
class VM_RedefineClasses: public VM_Operation {
private:
// These static fields are needed by ClassLoaderDataGraph::classes_do()
@@ -509,5 +514,12 @@
// Modifiable test must be shared between IsModifiableClass query
// and redefine implementation
static bool is_modifiable_class(oop klass_mirror);
+
+ static jint get_cached_class_file_len(JvmtiCachedClassFileData *cache) {
+ return cache == NULL ? 0 : cache->length;
+ }
+ static unsigned char * get_cached_class_file_bytes(JvmtiCachedClassFileData *cache) {
+ return cache == NULL ? NULL : cache->data;
+ }
};
#endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES_HPP
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -263,6 +263,7 @@
{ "UseISM", JDK_Version::jdk(8), JDK_Version::jdk(9) },
{ "UsePermISM", JDK_Version::jdk(8), JDK_Version::jdk(9) },
{ "UseMPSS", JDK_Version::jdk(8), JDK_Version::jdk(9) },
+ { "UseStringCache", JDK_Version::jdk(8), JDK_Version::jdk(9) },
#ifdef PRODUCT
{ "DesiredMethodLimit",
JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
--- a/hotspot/src/share/vm/runtime/frame.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/frame.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -221,9 +221,20 @@
bool frame::entry_frame_is_first() const {
- return entry_frame_call_wrapper()->anchor()->last_Java_sp() == NULL;
+ return entry_frame_call_wrapper()->is_first_frame();
}
+JavaCallWrapper* frame::entry_frame_call_wrapper_if_safe(JavaThread* thread) const {
+ JavaCallWrapper** jcw = entry_frame_call_wrapper_addr();
+ address addr = (address) jcw;
+
+ // addr must be within the usable part of the stack
+ if (thread->is_in_usable_stack(addr)) {
+ return *jcw;
+ }
+
+ return NULL;
+}
bool frame::should_be_deoptimized() const {
if (_deopt_state == is_deoptimized ||
--- a/hotspot/src/share/vm/runtime/frame.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/frame.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -353,7 +353,9 @@
public:
// Entry frames
- JavaCallWrapper* entry_frame_call_wrapper() const;
+ JavaCallWrapper* entry_frame_call_wrapper() const { return *entry_frame_call_wrapper_addr(); }
+ JavaCallWrapper* entry_frame_call_wrapper_if_safe(JavaThread* thread) const;
+ JavaCallWrapper** entry_frame_call_wrapper_addr() const;
intptr_t* entry_frame_argument_at(int offset) const;
// tells whether there is another chunk of Delta stack above
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -2600,9 +2600,6 @@
product(bool, AggressiveOpts, false, \
"Enable aggressive optimizations - see arguments.cpp") \
\
- product(bool, UseStringCache, false, \
- "Enable String cache capabilities on String.java") \
- \
/* statistics */ \
develop(bool, CountCompiledCalls, false, \
"counts method invocations") \
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -80,6 +80,8 @@
oop receiver() { return _receiver; }
void oops_do(OopClosure* f);
+ bool is_first_frame() const { return _anchor.last_Java_sp() == NULL; }
+
};
--- a/hotspot/src/share/vm/runtime/mutex.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/mutex.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -1370,6 +1370,10 @@
debug_only(if (rank() != Mutex::special) \
thread->check_for_valid_safepoint_state(false);)
}
+ if (thread->is_Watcher_thread()) {
+ assert(!WatcherThread::watcher_thread()->has_crash_protection(),
+ "locking not allowed when crash protection is set");
+ }
}
void Monitor::check_block_state(Thread *thread) {
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -595,6 +595,22 @@
NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
+#ifdef ASSERT
+ // checking for the WatcherThread and crash_protection first
+ // since os::malloc can be called when the libjvm.{dll,so} is
+ // first loaded and we don't have a thread yet.
+ // try to find the thread after we see that the watcher thread
+ // exists and has crash protection.
+ WatcherThread *wt = WatcherThread::watcher_thread();
+ if (wt != NULL && wt->has_crash_protection()) {
+ Thread* thread = ThreadLocalStorage::get_thread_slow();
+ if (thread == wt) {
+ assert(!wt->has_crash_protection(),
+ "Can't malloc with crash protection from WatcherThread");
+ }
+ }
+#endif
+
if (size == 0) {
// return a valid pointer if size is zero
// if NULL is returned the calling functions assume out of memory.
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -32,15 +32,18 @@
#include "utilities/top.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "jvm_linux.h"
+# include <setjmp.h>
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "jvm_solaris.h"
+# include <setjmp.h>
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "jvm_windows.h"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "jvm_bsd.h"
+# include <setjmp.h>
#endif
// os defines the interface to operating system; this includes traditional
@@ -730,6 +733,10 @@
#include "runtime/os_ext.hpp"
public:
+ class CrashProtectionCallback : public StackObj {
+ public:
+ virtual void call() = 0;
+ };
// Platform dependent stuff
#ifdef TARGET_OS_FAMILY_linux
@@ -908,6 +915,7 @@
char pathSep);
static bool set_boot_path(char fileSep, char pathSep);
static char** split_path(const char* path, int* n);
+
};
// Note that "PAUSE" is almost always used with synchronization
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -218,6 +218,7 @@
// allocated data structures
set_osthread(NULL);
set_resource_area(new (mtThread)ResourceArea());
+ DEBUG_ONLY(_current_resource_mark = NULL;)
set_handle_area(new (mtThread) HandleArea(NULL));
set_metadata_handles(new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(30, true));
set_active_handles(NULL);
@@ -953,6 +954,14 @@
}
+bool Thread::is_in_usable_stack(address adr) const {
+ size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
+ size_t usable_stack_size = _stack_size - stack_guard_size;
+
+ return ((adr < stack_base()) && (adr >= stack_base() - usable_stack_size));
+}
+
+
// We had to move these methods here, because vm threads get into ObjectSynchronizer::enter
// However, there is a note in JavaThread::is_lock_owned() about the VM threads not being
// used for compilation in the future. If that change is made, the need for these methods
@@ -1217,7 +1226,7 @@
bool WatcherThread::_startable = false;
volatile bool WatcherThread::_should_terminate = false;
-WatcherThread::WatcherThread() : Thread() {
+WatcherThread::WatcherThread() : Thread(), _crash_protection(NULL) {
assert(watcher_thread() == NULL, "we can only allocate one WatcherThread");
if (os::create_thread(this, os::watcher_thread)) {
_watcher_thread = this;
@@ -3481,44 +3490,6 @@
initialize_class(vmSymbols::java_lang_String(), CHECK_0);
- if (AggressiveOpts) {
- {
- // Forcibly initialize java/util/HashMap and mutate the private
- // static final "frontCacheEnabled" field before we start creating instances
-#ifdef ASSERT
- Klass* tmp_k = SystemDictionary::find(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0);
- assert(tmp_k == NULL, "java/util/HashMap should not be loaded yet");
-#endif
- Klass* k_o = SystemDictionary::resolve_or_null(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0);
- KlassHandle k = KlassHandle(THREAD, k_o);
- guarantee(k.not_null(), "Must find java/util/HashMap");
- instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
- ik->initialize(CHECK_0);
- fieldDescriptor fd;
- // Possible we might not find this field; if so, don't break
- if (ik->find_local_field(vmSymbols::frontCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
- k()->java_mirror()->bool_field_put(fd.offset(), true);
- }
- }
-
- if (UseStringCache) {
- // Forcibly initialize java/lang/StringValue and mutate the private
- // static final "stringCacheEnabled" field before we start creating instances
- Klass* k_o = SystemDictionary::resolve_or_null(vmSymbols::java_lang_StringValue(), Handle(), Handle(), CHECK_0);
- // Possible that StringValue isn't present: if so, silently don't break
- if (k_o != NULL) {
- KlassHandle k = KlassHandle(THREAD, k_o);
- instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
- ik->initialize(CHECK_0);
- fieldDescriptor fd;
- // Possible we might not find this field: if so, silently don't break
- if (ik->find_local_field(vmSymbols::stringCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
- k()->java_mirror()->bool_field_put(fd.offset(), true);
- }
- }
- }
- }
-
// Initialize java_lang.System (needed before creating the thread)
initialize_class(vmSymbols::java_lang_System(), CHECK_0);
initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
@@ -3636,6 +3607,7 @@
// Start Attach Listener if +StartAttachListener or it can't be started lazily
if (!DisableAttachMechanism) {
+ AttachListener::vm_start();
if (StartAttachListener || AttachListener::init_at_startup()) {
AttachListener::init();
}
--- a/hotspot/src/share/vm/runtime/thread.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -86,6 +86,8 @@
class ThreadClosure;
class IdealGraphPrinter;
+DEBUG_ONLY(class ResourceMark;)
+
class WorkerThread;
// Class hierarchy
@@ -519,6 +521,9 @@
// Check if address is in the stack of the thread (not just for locks).
// Warning: the method can only be used on the running thread
bool is_in_stack(address adr) const;
+ // Check if address is in the usable part of the stack (excludes protected
+ // guard pages)
+ bool is_in_usable_stack(address adr) const;
// Sets this thread as starting thread. Returns failure if thread
// creation fails due to lack of memory, too many threads etc.
@@ -531,6 +536,8 @@
// Thread local resource area for temporary allocation within the VM
ResourceArea* _resource_area;
+ DEBUG_ONLY(ResourceMark* _current_resource_mark;)
+
// Thread local handle area for allocation of handles within the VM
HandleArea* _handle_area;
GrowableArray<Metadata*>* _metadata_handles;
@@ -585,6 +592,8 @@
// Deadlock detection
bool allow_allocation() { return _allow_allocation_count == 0; }
+ ResourceMark* current_resource_mark() { return _current_resource_mark; }
+ void set_current_resource_mark(ResourceMark* rm) { _current_resource_mark = rm; }
#endif
void check_for_valid_safepoint_state(bool potential_vm_operation) PRODUCT_RETURN;
@@ -724,6 +733,8 @@
static bool _startable;
volatile static bool _should_terminate; // updated without holding lock
+
+ os::WatcherThreadCrashProtection* _crash_protection;
public:
enum SomeConstants {
delay_interval = 10 // interrupt delay in milliseconds
@@ -751,6 +762,14 @@
// Otherwise the first task to enroll will trigger the start
static void make_startable();
+ void set_crash_protection(os::WatcherThreadCrashProtection* crash_protection) {
+ assert(Thread::current()->is_Watcher_thread(), "Can only be set by WatcherThread");
+ _crash_protection = crash_protection;
+ }
+
+ bool has_crash_protection() const { return _crash_protection != NULL; }
+ os::WatcherThreadCrashProtection* crash_protection() const { return _crash_protection; }
+
private:
int sleep() const;
};
--- a/hotspot/src/share/vm/services/attachListener.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/services/attachListener.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -50,6 +50,7 @@
class AttachListener: AllStatic {
public:
+ static void vm_start() NOT_SERVICES_RETURN;
static void init() NOT_SERVICES_RETURN;
static void abort() NOT_SERVICES_RETURN;
--- a/hotspot/src/share/vm/services/memTracker.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/services/memTracker.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -385,6 +385,7 @@
#define SAFE_SEQUENCE_THRESHOLD 30
#define HIGH_GENERATION_THRESHOLD 60
#define MAX_RECORDER_THREAD_RATIO 30
+#define MAX_RECORDER_PER_THREAD 100
void MemTracker::sync() {
assert(_tracking_level > NMT_off, "NMT is not enabled");
@@ -437,6 +438,11 @@
// means that worker thread is lagging behind in processing them.
if (!AutoShutdownNMT) {
_slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count);
+ } else {
+ // If auto shutdown is on, enforce MAX_RECORDER_PER_THREAD threshold to prevent OOM
+ if (MemRecorder::_instance_count >= _thread_count * MAX_RECORDER_PER_THREAD) {
+ shutdown(NMT_out_of_memory);
+ }
}
// check _worker_thread with lock to avoid racing condition
--- a/hotspot/src/share/vm/trace/traceDataTypes.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/trace/traceDataTypes.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -63,5 +63,7 @@
typedef u8 methodid;
typedef u8 fieldid;
+class TraceUnicodeString;
+
#endif // SHARE_VM_TRACE_TRACEDATATYPES_HPP
--- a/hotspot/src/share/vm/trace/tracetypes.xml Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/trace/tracetypes.xml Fri Jul 26 13:34:22 2013 -0700
@@ -55,18 +55,6 @@
type="u8" sizeop="sizeof(u1)"/>
Now we can use the content + data type in declaring event fields.
-Remember however, that for us to be able to resolve the value later we must also add
-creating the constant pool data in VM_JFRCheckpoint::write_checkpoint
-
- ...
- //CGMODE
- w->be_uint(CONTENT_TYPE_GCMODE);
- w->be_uint(MM_GC_MODE_UNINITIALIZED);
- for (i = 0; i < MM_GC_MODE_UNINITIALIZED; i++) {
- w->uchar(i);
- w->write_utf8(gcModeGetName(i));
- }
-
-->
<types>
@@ -81,10 +69,6 @@
<value type="OSTHREAD" field="thread" label="VM Thread"/>
</content_type>
- <!-- The first argument ("JavaThread") is misleading, it's really a
- java.lang.Thread id (long), but Mission Control depends on the name
- being "JavaThread" so it shouldn't be changed.
- -->
<content_type id="JavaThread" hr_name="Java thread"
type="U8" builtin_type="JAVALANGTHREAD">
<value type="OSTHREAD" field="thread" label="OS Thread ID"/>
@@ -285,6 +269,10 @@
<primary_type symbol="UTF8" datatype="UTF8" contenttype="NONE"
type="const char *" sizeop="sizeof_utf(%)"/>
+ <!-- UTF-16 encoded (Unicode) string, max length maxjuint -->
+ <primary_type symbol="STRING" datatype="STRING" contenttype="NONE"
+ type="TraceUnicodeString*" sizeop="sizeof_unicode(%)"/>
+
<!-- Symbol* constant. Note that this may currently ONLY be used by
classes, methods fields. This restriction might be lifted. -->
<primary_type symbol="SYMBOL" datatype="U8" contenttype="SYMBOL"
--- a/hotspot/src/share/vm/trace/xinclude.mod Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/trace/xinclude.mod Fri Jul 26 13:34:22 2013 -0700
@@ -22,30 +22,6 @@
questions.
-->
-
-<!--
- Copyright (c) 2012, 2013, 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.
-
--->
<!ELEMENT xi:include (xi:fallback?) >
<!ATTLIST xi:include
xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude"
--- a/hotspot/src/share/vm/utilities/ostream.cpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Fri Jul 26 13:34:22 2013 -0700
@@ -296,6 +296,7 @@
buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
buffer_pos = 0;
buffer_fixed = false;
+ DEBUG_ONLY(rm = Thread::current()->current_resource_mark();)
}
// useful for output to fixed chunks of memory, such as performance counters
@@ -321,6 +322,8 @@
end = buffer_length * 2;
}
char* oldbuf = buffer;
+ assert(rm == NULL || Thread::current()->current_resource_mark() == rm,
+ "stringStream is re-allocated with a different ResourceMark");
buffer = NEW_RESOURCE_ARRAY(char, end);
strncpy(buffer, oldbuf, buffer_pos);
buffer_length = end;
--- a/hotspot/src/share/vm/utilities/ostream.hpp Thu Jul 25 11:07:23 2013 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.hpp Fri Jul 26 13:34:22 2013 -0700
@@ -28,6 +28,8 @@
#include "memory/allocation.hpp"
#include "runtime/timer.hpp"
+DEBUG_ONLY(class ResourceMark;)
+
// Output streams for printing
//
// Printing guidelines:
@@ -177,6 +179,7 @@
size_t buffer_pos;
size_t buffer_length;
bool buffer_fixed;
+ DEBUG_ONLY(ResourceMark* rm;)
public:
stringStream(size_t initial_bufsize = 256);
stringStream(char* fixed_buffer, size_t fixed_buffer_size);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/EscapeAnalysis/Test8020215.java Fri Jul 26 13:34:22 2013 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 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 8020215
+ * @summary Different execution plan when using JIT vs interpreter
+ * @run main Test8020215
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Test8020215 {
+ public static class NamedObject {
+ public int id;
+ public String name;
+ public NamedObject(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+ }
+
+ public static class NamedObjectList {
+ public List<NamedObject> namedObjectList = new ArrayList<NamedObject>();
+
+ public NamedObject getBest(int id) {
+ NamedObject bestObject = null;
+ for (NamedObject o : namedObjectList) {
+ bestObject = id==o.id ? getBetter(bestObject, o) : bestObject;
+ }
+ return (bestObject != null) ? bestObject : null;
+ }
+
+ private static NamedObject getBetter(NamedObject p1, NamedObject p2) {
+ return (p1 == null) ? p2 : (p2 == null) ? p1 : (p2.name.compareTo(p1.name) >= 0) ? p2 : p1;
+ }
+ }
+
+ static void test(NamedObjectList b, int i) {
+ NamedObject x = b.getBest(2);
+ // test
+ if (x == null) {
+ throw new RuntimeException("x should never be null here! (i=" + i + ")");
+ }
+ }
+
+ public static void main(String[] args) {
+ // setup
+ NamedObjectList b = new NamedObjectList();
+ for (int i = 0; i < 10000; i++) {
+ b.namedObjectList.add(new NamedObject(1, "2012-12-31"));
+ }
+ b.namedObjectList.add(new NamedObject(2, "2013-12-31"));
+
+ // execution
+ for (int i = 0; i < 12000; i++) {
+ test(b, i);
+ }
+ System.out.println("PASSED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/cpuflags/RestoreMXCSR.java Fri Jul 26 13:34:22 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, 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 8020433
+ * @summary Crash when using -XX:+RestoreMXCSROnJNICalls
+ * @library /testlibrary
+ *
+ */
+import com.oracle.java.testlibrary.*;
+
+public class RestoreMXCSR {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb;
+ OutputAnalyzer out;
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+RestoreMXCSROnJNICalls", "-version");
+ out = new OutputAnalyzer(pb.start());
+ out.shouldHaveExitValue(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/membars/DekkerTest.java Fri Jul 26 13:34:22 2013 -0700
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2013 SAP AG. 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 8007898
+ * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @author Martin Doerr martin DOT doerr AT sap DOT com
+ *
+ * Run 3 times since the failure is intermittent.
+ */
+
+public class DekkerTest {
+
+ /*
+ Read After Write Test (basically a simple Dekker test with volatile variables)
+ Derived from the original jcstress test, available at:
+ http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/
+ tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java
+ */
+
+ static final int ITERATIONS = 1000000;
+
+ static class TestData {
+ public volatile int a;
+ public volatile int b;
+ }
+
+ static class ResultData {
+ public int a;
+ public int b;
+ }
+
+ TestData[] testDataArray;
+ ResultData[] results;
+
+ volatile boolean start;
+
+ public DekkerTest() {
+ testDataArray = new TestData[ITERATIONS];
+ results = new ResultData[ITERATIONS];
+ for (int i = 0; i < ITERATIONS; ++i) {
+ testDataArray[i] = new TestData();
+ results[i] = new ResultData();
+ }
+ start = false;
+ }
+
+ public void reset() {
+ for (int i = 0; i < ITERATIONS; ++i) {
+ testDataArray[i].a = 0;
+ testDataArray[i].b = 0;
+ results[i].a = 0;
+ results[i].b = 0;
+ }
+ start = false;
+ }
+
+ int actor1(TestData t) {
+ t.a = 1;
+ return t.b;
+ }
+
+ int actor2(TestData t) {
+ t.b = 1;
+ return t.a;
+ }
+
+ class Runner1 extends Thread {
+ public void run() {
+ do {} while (!start);
+ for (int i = 0; i < ITERATIONS; ++i) {
+ results[i].a = actor1(testDataArray[i]);
+ }
+ }
+ }
+
+ class Runner2 extends Thread {
+ public void run() {
+ do {} while (!start);
+ for (int i = 0; i < ITERATIONS; ++i) {
+ results[i].b = actor2(testDataArray[i]);
+ }
+ }
+ }
+
+ void testRunner() {
+ Thread thread1 = new Runner1();
+ Thread thread2 = new Runner2();
+ thread1.start();
+ thread2.start();
+ do {} while (!thread1.isAlive());
+ do {} while (!thread2.isAlive());
+ start = true;
+ Thread.yield();
+ try {
+ thread1.join();
+ thread2.join();
+ } catch (InterruptedException e) {
+ System.out.println("interrupted!");
+ System.exit(1);
+ }
+ }
+
+ boolean printResult() {
+ int[] count = new int[4];
+ for (int i = 0; i < ITERATIONS; ++i) {
+ int event_kind = (results[i].a << 1) + results[i].b;
+ ++count[event_kind];
+ }
+ if (count[0] == 0 && count[3] == 0) {
+ System.out.println("[not interesting]");
+ return false; // not interesting
+ }
+ String error = (count[0] == 0) ? " ok" : " disallowed!";
+ System.out.println("[0,0] " + count[0] + error);
+ System.out.println("[0,1] " + count[1]);
+ System.out.println("[1,0] " + count[2]);
+ System.out.println("[1,1] " + count[3]);
+ return (count[0] != 0);
+ }
+
+ public static void main(String args[]) {
+ DekkerTest test = new DekkerTest();
+ final int runs = 30;
+ int failed = 0;
+ for (int c = 0; c < runs; ++c) {
+ test.testRunner();
+ if (test.printResult()) {
+ failed++;
+ }
+ test.reset();
+ }
+ if (failed > 0) {
+ throw new InternalError("FAILED. Got " + failed + " failed ITERATIONS");
+ }
+ System.out.println("PASSED.");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jsig/Test8017498.sh Fri Jul 26 13:34:22 2013 -0700
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2013, 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 Test8017498.sh
+## @bug 8017498
+## @bug 8020791
+## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX
+## @run shell/timeout=30 Test8017498.sh
+##
+
+if [ "${TESTSRC}" = "" ]
+then
+ TESTSRC=${PWD}
+ echo "TESTSRC not set. Using "${TESTSRC}" as default"
+fi
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Linux)
+ echo "Testing on Linux"
+ if [ "$VM_BITS" = "64" ]
+ then
+ MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}amd64${FS}libjsig.so
+ else
+ MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}i386${FS}libjsig.so
+ fi
+ echo MY_LD_PRELOAD = ${MY_LD_PRELOAD}
+ ;;
+ *)
+ echo "Test passed; only valid for Linux"
+ exit 0;
+ ;;
+esac
+
+THIS_DIR=.
+
+cp ${TESTSRC}${FS}*.java ${THIS_DIR}
+${TESTJAVA}${FS}bin${FS}javac *.java
+
+gcc -DLINUX -fPIC -shared \
+ -o ${TESTSRC}${FS}libTestJNI.so \
+ -I${TESTJAVA}${FS}include \
+ -I${TESTJAVA}${FS}include${FS}linux \
+ ${TESTSRC}${FS}TestJNI.c
+if [ $? != 0 ]
+then
+ echo "WARNING: the gcc command failed." 2>&1
+fi
+
+# run the java test in the background
+cmd="LD_PRELOAD=$MY_LD_PRELOAD \
+ ${TESTJAVA}${FS}bin${FS}java \
+ -Djava.library.path=${TESTSRC}${FS} -server TestJNI 100"
+echo "$cmd > test.out 2>&1"
+eval $cmd > test.out 2>&1
+
+grep "old handler" test.out > ${NULL}
+if [ $? = 0 ]
+then
+ echo "Test Passed"
+ exit 0
+fi
+
+echo "Test Failed"
+exit 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jsig/TestJNI.c Fri Jul 26 13:34:22 2013 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+#define _GNU_SOURCE // for the definition of REG_RIP in ucontext.h
+#include <stdio.h>
+#include <jni.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sig_handler(int sig, siginfo_t *info, ucontext_t *context) {
+ int thrNum;
+
+ printf( " HANDLER (1) " );
+ // Move forward RIP to skip failing instruction
+ context->uc_mcontext.gregs[REG_RIP] += 6;
+}
+
+JNIEXPORT void JNICALL Java_TestJNI_doSomething(JNIEnv *env, jclass klass, jint val) {
+ struct sigaction act;
+ struct sigaction oact;
+
+ act.sa_flags = SA_ONSTACK|SA_RESTART|SA_SIGINFO;
+ sigfillset(&act.sa_mask);
+ act.sa_handler = SIG_DFL;
+ act.sa_sigaction = (void (*)())sig_handler;
+ sigaction(0x20+val, &act, &oact);
+
+ printf( " doSomething(%d) " , val);
+ printf( " old handler = %p " , oact.sa_handler);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jsig/TestJNI.java Fri Jul 26 13:34:22 2013 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+public class TestJNI {
+ static {
+ System.loadLibrary("TestJNI");
+ }
+ public static native void doSomething(int val);
+ public static void main(String[] args) {
+ int intArg = 43;
+ if (args.length > 0) {
+ try {
+ intArg = Integer.parseInt(args[0]);
+ } catch (NumberFormatException e) {
+ System.err.println("arg " + args[0] + " must be an integer");
+ System.exit(1);
+ }
+ }
+ TestJNI.doSomething(intArg);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/attach/AttachWithStalePidFile.java Fri Jul 26 13:34:22 2013 -0700
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2013, 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 7162400
+ * @key regression
+ * @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues
+ * @library /testlibrary
+ * @compile AttachWithStalePidFileTarget.java
+ * @run main AttachWithStalePidFile
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.sun.tools.attach.VirtualMachine;
+import sun.tools.attach.HotSpotVirtualMachine;
+import java.lang.reflect.Field;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.*;
+
+public class AttachWithStalePidFile {
+ public static void main(String... args) throws Exception {
+
+ // this test is only valid on non-Windows platforms
+ if(Platform.isWindows()) {
+ System.out.println("This test is only valid on non-Windows platforms.");
+ return;
+ }
+
+ // Since there might be stale pid-files owned by different
+ // users on the system we may need to retry the test in case we
+ // are unable to remove the existing file.
+ int retries = 5;
+ while(!runTest() && --retries > 0);
+
+ if(retries == 0) {
+ throw new RuntimeException("Test failed after 5 retries. " +
+ "Remove any /tmp/.java_pid* files and retry.");
+ }
+ }
+
+ public static boolean runTest() throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions", "-XX:+PauseAtStartup", "AttachWithStalePidFileTarget");
+ Process target = pb.start();
+ Path pidFile = null;
+
+ try {
+ int pid = getUnixProcessId(target);
+
+ // create the stale .java_pid file. use hard-coded /tmp path as in th VM
+ pidFile = createJavaPidFile(pid);
+ if(pidFile == null) {
+ return false;
+ }
+
+ // wait for vm.paused file to be created and delete it once we find it.
+ waitForAndResumeVM(pid);
+
+ // unfortunately there's no reliable way to know the VM is ready to receive the
+ // attach request so we have to do an arbitrary sleep.
+ Thread.sleep(5000);
+
+ HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(((Integer)pid).toString());
+ BufferedReader remoteDataReader = new BufferedReader(new InputStreamReader(vm.remoteDataDump()));
+ String line = null;
+ while((line = remoteDataReader.readLine()) != null);
+
+ vm.detach();
+ return true;
+ }
+ finally {
+ target.destroy();
+ target.waitFor();
+
+ if(pidFile != null && Files.exists(pidFile)) {
+ Files.delete(pidFile);
+ }
+ }
+ }
+
+ private static Path createJavaPidFile(int pid) throws Exception {
+ Path pidFile = Paths.get("/tmp/.java_pid" + pid);
+ if(Files.exists(pidFile)) {
+ try {
+ Files.delete(pidFile);
+ }
+ catch(FileSystemException e) {
+ if(e.getReason().equals("Operation not permitted")) {
+ System.out.println("Unable to remove exisiting stale PID file" + pidFile);
+ return null;
+ }
+ throw e;
+ }
+ }
+ return Files.createFile(pidFile,
+ PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------")));
+ }
+
+ private static void waitForAndResumeVM(int pid) throws Exception {
+ Path pauseFile = Paths.get("vm.paused." + pid);
+ int retries = 60;
+ while(!Files.exists(pauseFile) && --retries > 0) {
+ Thread.sleep(1000);
+ }
+ if(retries == 0) {
+ throw new RuntimeException("Timeout waiting for VM to start. " +
+ "vm.paused file not created within 60 seconds.");
+ }
+ Files.delete(pauseFile);
+ }
+
+ private static int getUnixProcessId(Process unixProcess) throws Exception {
+ Field pidField = unixProcess.getClass().getDeclaredField("pid");
+ pidField.setAccessible(true);
+ return (Integer)pidField.get(unixProcess);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/attach/AttachWithStalePidFileTarget.java Fri Jul 26 13:34:22 2013 -0700
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+public class AttachWithStalePidFileTarget {
+ public static void main(String... args) throws Exception {
+ Thread.sleep(2*60*1000);
+ }
+}
--- a/jaxp/.hgtags Thu Jul 25 11:07:23 2013 -0700
+++ b/jaxp/.hgtags Fri Jul 26 13:34:22 2013 -0700
@@ -221,3 +221,4 @@
6c830db28d21108f32af990ecf4d80a75887980d jdk8-b97
15e5bb51bc0cd89304dc2f7f29b4c8002e632353 jdk8-b98
adf49c3ef83c160d53ece623049b2cdccaf78fc7 jdk8-b99
+5d1974c1d7b9a86431bc253dc5a6a52d4586622e jdk8-b100
--- a/jaxws/.hgtags Thu Jul 25 11:07:23 2013 -0700
+++ b/jaxws/.hgtags Fri Jul 26 13:34:22 2013 -0700
@@ -221,3 +221,4 @@
dcde7f049111353ad23175f54985a4f6bfea720c jdk8-b97
b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98
8ef83d4b23c933935e28f59b282cea920b1b1f5f jdk8-b99
+4fd722afae5c02f00bbd44c3a34425ee474afb1c jdk8-b100
--- a/jdk/.hgtags Thu Jul 25 11:07:23 2013 -0700
+++ b/jdk/.hgtags Fri Jul 26 13:34:22 2013 -0700
@@ -221,3 +221,4 @@
978a95239044f26dcc8a6d59246be07ad6ca6be2 jdk8-b97
c4908732fef5235f1b98cafe0ce507771ef7892c jdk8-b98
6a099a36589bd933957272ba63e5263bede29971 jdk8-b99
+5be9c5bfcfe9b2a40412b4fb364377d49de014eb jdk8-b100
--- a/langtools/.hgtags Thu Jul 25 11:07:23 2013 -0700
+++ b/langtools/.hgtags Fri Jul 26 13:34:22 2013 -0700
@@ -221,3 +221,4 @@
6a11a81a8824c17f6cd2ec8f8492e1229b694e96 jdk8-b97
ce5a90df517bdceb2739d7dd3e6764b070def802 jdk8-b98
6d85acab769eb79bc058f5640fa86a6ef096a583 jdk8-b99
+82f68da70e471ee5640016e3f38c014347a5c785 jdk8-b100
--- a/nashorn/.hgtags Thu Jul 25 11:07:23 2013 -0700
+++ b/nashorn/.hgtags Fri Jul 26 13:34:22 2013 -0700
@@ -209,3 +209,4 @@
1bf1d6ce30427e1f9dc1ada18db409d1f14d99fe jdk8-b97
542b7803f0389a91fab58608a0f46fac0e15d759 jdk8-b98
10a1ab9e20a42d278aa1a89698f2a4cf5883d00d jdk8-b99
+598321c438b52d9408a2671fb3fc2b2947d0f654 jdk8-b100