This commit is contained in:
Lana Steuck 2013-07-26 14:01:00 -07:00
commit 6c3d986602
1045 changed files with 73140 additions and 38675 deletions

View File

@ -220,3 +220,5 @@ b72ae39e1329fefae50d4690db4fde43f3841a95 jdk8-b93
ea73f01b9053e7165e7ba80f242bafecbc6af712 jdk8-b96
0a85476a0b9cb876d5666d45097dac68bef3fce1 jdk8-b97
711eb4aa87de68de78250e0549980936bab53d54 jdk8-b98
2d3875b0d18b3ad1c2bebf385a697e309e4005a4 jdk8-b99
3d34036aae4ea90b2ca59712d5a69db3221f0875 jdk8-b100

View File

@ -220,3 +220,5 @@ cb51fb4789ac0b8be4056482077ddfb8f3bd3805 jdk8-b91
c156084add486f941c12d886a0b1b2854795d557 jdk8-b96
a1c1e8bf71f354f3aec0214cf13d6668811e021d jdk8-b97
0d0c983a817bbe8518a5ff201306334a8de267f2 jdk8-b98
59dc9da813794c924a0383c2a6241af94defdfed jdk8-b99
d2dcb110e9dbaf9903c05b211df800e78e4b394e jdk8-b100

View File

@ -220,3 +220,5 @@ c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90
3357c2776431d51a8de326a85e0f41420e40774f jdk8-b96
469995a8e97424f450c880606d689bf345277b19 jdk8-b97
3370fb6146e47a6cc05a213fc213e12fc0a38d07 jdk8-b98
3f67804ab61303782df57e54989ef5e0e4629beb jdk8-b99
8d492f1dfd1b131a4c7886ee6b59528609f7e4fe jdk8-b100

View File

@ -359,3 +359,7 @@ d197d377ab2e016d024e8c86cb06a57bd7eae590 jdk8-b97
c9dd82da51ed34a28f7c6b3245163ee962e94572 hs25-b40
30b5b75c42ac5174b640fbef8aa87527668e8400 jdk8-b98
2b9946e10587f74ef75ae8145bea484df4a2738b hs25-b41
81b6cb70717c66375846b78bb174594ec3aa998e jdk8-b99
9f71e36a471ae4a668e08827d33035963ed10c08 hs25-b42
5787fac72e760c6a5fd9efa113b0c75caf554136 jdk8-b100
46487ba40ff225654d0c51787ed3839bafcbd9f3 hs25-b43

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=41
HS_BUILD_NUMBER=43
JDK_MAJOR_VER=1
JDK_MINOR_VER=8

View File

@ -46,6 +46,7 @@ ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
include $(MAKEFILES_DIR)/zeroshark.make
else
include $(MAKEFILES_DIR)/$(BUILDARCH).make
-include $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/$(BUILDARCH).make
endif
# set VPATH so make knows where to look for source files
@ -211,6 +212,12 @@ ifeq ($(Platform_arch_model), x86_64)
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 \
@ -380,4 +387,4 @@ build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) dtraceChe
install: install_jvm install_jsig install_saproc
.PHONY: default build install install_jvm
.PHONY: default build install install_jvm $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/$(BUILDARCH).make $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/vm.make

View File

@ -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 @@ CXX_FLAGS=$(CXX_FLAGS) /D TARGET_COMPILER_visCPP
# 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 @@ COMPILER_NAME=VS2008
!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 = /MD
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 @@ LD_FLAGS = /SAFESEH $(LD_FLAGS)
!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)

View File

@ -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.

View File

@ -132,6 +132,10 @@ CXX_DONT_USE_PCH=/D DONT_USE_PRECOMPILED_HEADER
!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

View File

@ -240,10 +240,10 @@ inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const {
#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()];
}

View File

@ -410,6 +410,51 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
// Safefetch stubs.
void generate_safefetch(const char* name, int size, address* entry,
address* fault_pc, address* continuation_pc) {
// safefetch signatures:
// int SafeFetch32(int* adr, int errValue);
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
//
// arguments:
// o0 = adr
// o1 = errValue
//
// result:
// o0 = *adr or errValue
StubCodeMark mark(this, "StubRoutines", name);
// Entry point, pc or function descriptor.
__ align(CodeEntryAlignment);
*entry = __ pc();
__ mov(O0, G1); // g1 = o0
__ mov(O1, O0); // o0 = o1
// Load *adr into c_rarg1, may fault.
*fault_pc = __ pc();
switch (size) {
case 4:
// int32_t
__ ldsw(G1, 0, O0); // o0 = [g1]
break;
case 8:
// int64_t
__ ldx(G1, 0, O0); // o0 = [g1]
break;
default:
ShouldNotReachHere();
}
// return errValue or *adr
*continuation_pc = __ pc();
// By convention with the trap handler we ensure there is a non-CTI
// instruction in the trap shadow.
__ nop();
__ retl();
__ delayed()->nop();
}
//------------------------------------------------------------------------------------------------------------------------
// Continuation point for throwing of implicit exceptions that are not handled in
@ -3315,6 +3360,14 @@ class StubGenerator: public StubCodeGenerator {
// Don't initialize the platform math functions since sparc
// doesn't have intrinsics for these operations.
// Safefetch stubs.
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
&StubRoutines::_safefetch32_fault_pc,
&StubRoutines::_safefetch32_continuation_pc);
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
&StubRoutines::_safefetchN_fault_pc,
&StubRoutines::_safefetchN_continuation_pc);
}

View File

@ -272,11 +272,10 @@ inline jint frame::interpreter_frame_expression_stack_direction() { return -1; }
// 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) {

View File

@ -2766,6 +2766,39 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
// Safefetch stubs.
void generate_safefetch(const char* name, int size, address* entry,
address* fault_pc, address* continuation_pc) {
// safefetch signatures:
// int SafeFetch32(int* adr, int errValue);
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
StubCodeMark mark(this, "StubRoutines", name);
// Entry point, pc or function descriptor.
*entry = __ pc();
__ movl(rax, Address(rsp, 0x8));
__ movl(rcx, Address(rsp, 0x4));
// Load *adr into eax, may fault.
*fault_pc = __ pc();
switch (size) {
case 4:
// int32_t
__ movl(rax, Address(rcx, 0));
break;
case 8:
// int64_t
Unimplemented();
break;
default:
ShouldNotReachHere();
}
// Return errValue or *adr.
*continuation_pc = __ pc();
__ ret(0);
}
public:
// Information about frame layout at time of blocking runtime call.
@ -2978,6 +3011,14 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
}
// Safefetch stubs.
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
&StubRoutines::_safefetch32_fault_pc,
&StubRoutines::_safefetch32_continuation_pc);
StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry;
StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc;
StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc;
}

View File

@ -279,7 +279,7 @@ class StubGenerator: public StubCodeGenerator {
__ 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 @@ class StubGenerator: public StubCodeGenerator {
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);
@ -3357,7 +3358,45 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
// Safefetch stubs.
void generate_safefetch(const char* name, int size, address* entry,
address* fault_pc, address* continuation_pc) {
// safefetch signatures:
// int SafeFetch32(int* adr, int errValue);
// intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
//
// arguments:
// c_rarg0 = adr
// c_rarg1 = errValue
//
// result:
// PPC_RET = *adr or errValue
StubCodeMark mark(this, "StubRoutines", name);
// Entry point, pc or function descriptor.
*entry = __ pc();
// Load *adr into c_rarg1, may fault.
*fault_pc = __ pc();
switch (size) {
case 4:
// int32_t
__ movl(c_rarg1, Address(c_rarg0, 0));
break;
case 8:
// int64_t
__ movq(c_rarg1, Address(c_rarg0, 0));
break;
default:
ShouldNotReachHere();
}
// return errValue or *adr
*continuation_pc = __ pc();
__ movq(rax, c_rarg1);
__ ret(0);
}
// This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time
// to hide instruction latency
@ -3729,12 +3768,35 @@ class StubGenerator: public StubCodeGenerator {
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
@ -3833,6 +3895,14 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
}
// Safefetch stubs.
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
&StubRoutines::_safefetch32_fault_pc,
&StubRoutines::_safefetch32_continuation_pc);
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
&StubRoutines::_safefetchN_fault_pc,
&StubRoutines::_safefetchN_continuation_pc);
}
public:

View File

@ -42,4 +42,3 @@ address StubRoutines::x86::_float_sign_mask = NULL;
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;

View File

@ -52,7 +52,6 @@ class x86 {
static address _float_sign_flip;
static address _double_sign_mask;
static address _double_sign_flip;
static address _mxcsr_std;
public:
@ -106,11 +105,6 @@ class x86 {
return _double_sign_flip;
}
static address mxcsr_std()
{
return _mxcsr_std;
}
# include "stubRoutines_x86.hpp"
};

View File

@ -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 @@ AttachOperation* AttachListener::dequeue() {
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);

View File

@ -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 @@ AttachOperation* AttachListener::dequeue() {
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);

View File

@ -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 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
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 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
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 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
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 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
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);

View File

@ -259,3 +259,52 @@ const char* os::get_current_directory(char *buf, size_t buflen) {
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();
}
}
}

View File

@ -37,5 +37,24 @@ protected:
};
/*
* 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

View File

@ -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 @@ AttachOperation* AttachListener::dequeue() {
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);

View File

@ -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 @@ AttachOperation* AttachListener::dequeue() {
return op;
}
void AttachListener::vm_start() {
// nothing to do
}
int AttachListener::pd_init() {
return Win32AttachListener::init();
}

View File

@ -2323,6 +2323,11 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
#endif
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
// Handle SafeFetch32 and SafeFetchN exceptions.
if (StubRoutines::is_safefetch_fault(pc)) {
return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc));
}
#ifndef _WIN64
// Execution protection violation - win32 running on AMD64 only
// Handled first to avoid misdiagnosis as a "normal" access violation;
@ -4684,6 +4689,34 @@ void os::pause() {
}
}
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:

View File

@ -102,6 +102,20 @@ class win32 {
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

View File

@ -63,24 +63,6 @@ SYMBOL(fixcw):
popl %eax
ret
.globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume)
.globl SYMBOL(SafeFetchN)
## TODO: avoid exposing Fetch32PFI and Fetch32Resume.
## Instead, the signal handler would call a new SafeFetchTriage(FaultingEIP)
## routine to vet the address. If the address is the faulting LD then
## SafeFetchTriage() would return the resume-at EIP, otherwise null.
ELF_TYPE(SafeFetch32,@function)
.p2align 4,,15
SYMBOL(SafeFetch32):
SYMBOL(SafeFetchN):
movl 0x8(%esp), %eax
movl 0x4(%esp), %ecx
SYMBOL(Fetch32PFI):
movl (%ecx), %eax
SYMBOL(Fetch32Resume):
ret
.globl SYMBOL(SpinPause)
ELF_TYPE(SpinPause,@function)
.p2align 4,,15

View File

@ -46,28 +46,6 @@
.text
.globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume)
.p2align 4,,15
ELF_TYPE(SafeFetch32,@function)
// Prototype: int SafeFetch32 (int * Adr, int ErrValue)
SYMBOL(SafeFetch32):
movl %esi, %eax
SYMBOL(Fetch32PFI):
movl (%rdi), %eax
SYMBOL(Fetch32Resume):
ret
.globl SYMBOL(SafeFetchN), SYMBOL(FetchNPFI), SYMBOL(FetchNResume)
.p2align 4,,15
ELF_TYPE(SafeFetchN,@function)
// Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue)
SYMBOL(SafeFetchN):
movq %rsi, %rax
SYMBOL(FetchNPFI):
movq (%rdi), %rax
SYMBOL(FetchNResume):
ret
.globl SYMBOL(SpinPause)
.p2align 4,,15
ELF_TYPE(SpinPause,@function)

View File

@ -72,7 +72,7 @@ inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; }
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 jushort* p, jushort v) { *p
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 juint* p, juint 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, jdouble_cast(v)); }
inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) {
#ifdef AMD64

View File

@ -385,13 +385,6 @@ enum {
trap_page_fault = 0xE
};
extern "C" void Fetch32PFI () ;
extern "C" void Fetch32Resume () ;
#ifdef AMD64
extern "C" void FetchNPFI () ;
extern "C" void FetchNResume () ;
#endif // AMD64
extern "C" JNIEXPORT int
JVM_handle_bsd_signal(int sig,
siginfo_t* info,
@ -401,6 +394,10 @@ JVM_handle_bsd_signal(int sig,
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
@ -454,16 +451,10 @@ JVM_handle_bsd_signal(int sig,
if (info != NULL && uc != NULL && thread != NULL) {
pc = (address) os::Bsd::ucontext_get_pc(uc);
if (pc == (address) Fetch32PFI) {
uc->context_pc = intptr_t(Fetch32Resume) ;
return 1 ;
if (StubRoutines::is_safefetch_fault(pc)) {
uc->context_pc = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
return 1;
}
#ifdef AMD64
if (pc == (address) FetchNPFI) {
uc->context_pc = intptr_t (FetchNResume) ;
return 1 ;
}
#endif // AMD64
// Handle ALL stack overflow variations here
if (sig == SIGSEGV || sig == SIGBUS) {

View File

@ -21,42 +21,6 @@
# questions.
#
# Prototype: int SafeFetch32 (int * adr, int ErrValue)
# The "ld" at Fetch32 is potentially faulting instruction.
# If the instruction traps the trap handler will arrange
# for control to resume at Fetch32Resume.
# By convention with the trap handler we ensure there is a non-CTI
# instruction in the trap shadow.
.globl SafeFetch32, Fetch32PFI, Fetch32Resume
.globl SafeFetchN
.align 32
.type SafeFetch32,@function
SafeFetch32:
mov %o0, %g1
mov %o1, %o0
Fetch32PFI:
# <-- Potentially faulting instruction
ld [%g1], %o0
Fetch32Resume:
nop
retl
nop
.globl SafeFetchN, FetchNPFI, FetchNResume
.type SafeFetchN,@function
.align 32
SafeFetchN:
mov %o0, %g1
mov %o1, %o0
FetchNPFI:
ldn [%g1], %o0
FetchNResume:
nop
retl
nop
# Possibilities:
# -- membar
# -- CAS (SP + BIAS, G0, G0)

View File

@ -366,18 +366,9 @@ intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) {
// Utility functions
extern "C" void Fetch32PFI();
extern "C" void Fetch32Resume();
extern "C" void FetchNPFI();
extern "C" void FetchNResume();
inline static bool checkPrefetch(sigcontext* uc, address pc) {
if (pc == (address) Fetch32PFI) {
set_cont_address(uc, address(Fetch32Resume));
return true;
}
if (pc == (address) FetchNPFI) {
set_cont_address(uc, address(FetchNResume));
if (StubRoutines::is_safefetch_fault(pc)) {
set_cont_address(uc, address(StubRoutines::continuation_for_safefetch_fault(pc)));
return true;
}
return false;
@ -553,6 +544,10 @@ JVM_handle_linux_signal(int sig,
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

View File

@ -42,24 +42,6 @@
.text
.globl SafeFetch32, Fetch32PFI, Fetch32Resume
.globl SafeFetchN
## TODO: avoid exposing Fetch32PFI and Fetch32Resume.
## Instead, the signal handler would call a new SafeFetchTriage(FaultingEIP)
## routine to vet the address. If the address is the faulting LD then
## SafeFetchTriage() would return the resume-at EIP, otherwise null.
.type SafeFetch32,@function
.p2align 4,,15
SafeFetch32:
SafeFetchN:
movl 0x8(%esp), %eax
movl 0x4(%esp), %ecx
Fetch32PFI:
movl (%ecx), %eax
Fetch32Resume:
ret
.globl SpinPause
.type SpinPause,@function
.p2align 4,,15

View File

@ -38,28 +38,6 @@
.text
.globl SafeFetch32, Fetch32PFI, Fetch32Resume
.align 16
.type SafeFetch32,@function
// Prototype: int SafeFetch32 (int * Adr, int ErrValue)
SafeFetch32:
movl %esi, %eax
Fetch32PFI:
movl (%rdi), %eax
Fetch32Resume:
ret
.globl SafeFetchN, FetchNPFI, FetchNResume
.align 16
.type SafeFetchN,@function
// Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue)
SafeFetchN:
movq %rsi, %rax
FetchNPFI:
movq (%rdi), %rax
FetchNResume:
ret
.globl SpinPause
.align 16
.type SpinPause,@function

View File

@ -72,7 +72,7 @@ inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; }
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 jushort* p, jushort v) { *p
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(jushort* p, jushort v) { store_fence((j
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 juint* p, juint 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

View File

@ -209,13 +209,6 @@ enum {
trap_page_fault = 0xE
};
extern "C" void Fetch32PFI () ;
extern "C" void Fetch32Resume () ;
#ifdef AMD64
extern "C" void FetchNPFI () ;
extern "C" void FetchNResume () ;
#endif // AMD64
extern "C" JNIEXPORT int
JVM_handle_linux_signal(int sig,
siginfo_t* info,
@ -225,6 +218,10 @@ JVM_handle_linux_signal(int sig,
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
@ -278,16 +275,10 @@ JVM_handle_linux_signal(int sig,
if (info != NULL && uc != NULL && thread != NULL) {
pc = (address) os::Linux::ucontext_get_pc(uc);
if (pc == (address) Fetch32PFI) {
uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ;
return 1 ;
if (StubRoutines::is_safefetch_fault(pc)) {
uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
return 1;
}
#ifdef AMD64
if (pc == (address) FetchNPFI) {
uc->uc_mcontext.gregs[REG_PC] = intptr_t (FetchNResume) ;
return 1 ;
}
#endif // AMD64
#ifndef AMD64
// Halt if SI_KERNEL before more crashes get misdiagnosed as Java bugs

View File

@ -303,11 +303,6 @@ bool os::is_allocatable(size_t bytes) {
#endif
}
extern "C" void Fetch32PFI () ;
extern "C" void Fetch32Resume () ;
extern "C" void FetchNPFI () ;
extern "C" void FetchNResume () ;
extern "C" JNIEXPORT int
JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
int abort_if_unrecognized) {
@ -315,6 +310,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
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) {
@ -379,17 +378,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
npc = (address) uc->uc_mcontext.gregs[REG_nPC];
// SafeFetch() support
// Implemented with either a fixed set of addresses such
// as Fetch32*, or with Thread._OnTrap.
if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(Fetch32PFI)) {
uc->uc_mcontext.gregs [REG_PC] = intptr_t(Fetch32Resume) ;
uc->uc_mcontext.gregs [REG_nPC] = intptr_t(Fetch32Resume) + 4 ;
return true ;
}
if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(FetchNPFI)) {
uc->uc_mcontext.gregs [REG_PC] = intptr_t(FetchNResume) ;
uc->uc_mcontext.gregs [REG_nPC] = intptr_t(FetchNResume) + 4 ;
return true ;
if (StubRoutines::is_safefetch_fault(pc)) {
uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
uc->uc_mcontext.gregs[REG_nPC] = uc->uc_mcontext.gregs[REG_PC] + 4;
return 1;
}
// Handle ALL stack overflow variations here

View File

@ -21,47 +21,6 @@
!! questions.
!!
!! Prototype: int SafeFetch32 (int * adr, int ErrValue)
!! The "ld" at Fetch32 is potentially faulting instruction.
!! If the instruction traps the trap handler will arrange
!! for control to resume at Fetch32Resume.
!! By convention with the trap handler we ensure there is a non-CTI
!! instruction in the trap shadow.
!!
!! The reader might be tempted to move this service to .il.
!! Don't. Sun's CC back-end reads and optimize code emitted
!! by the .il "call", in some cases optimizing the code, completely eliding it,
!! or by moving the code from the "call site".
!! ASM better know we may use G6 for our own purposes
.register %g6, #ignore
.globl SafeFetch32
.align 32
.global Fetch32PFI, Fetch32Resume
SafeFetch32:
mov %o0, %g1
mov %o1, %o0
Fetch32PFI:
ld [%g1], %o0 !! <-- Potentially faulting instruction
Fetch32Resume:
nop
retl
nop
.globl SafeFetchN
.align 32
.globl FetchNPFI, FetchNResume
SafeFetchN:
mov %o0, %g1
mov %o1, %o0
FetchNPFI:
ldn [%g1], %o0
FetchNResume:
nop
retl
nop
!! Possibilities:
!! -- membar
!! -- CAS (SP + BIAS, G0, G0)

View File

@ -88,7 +88,7 @@ inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; }
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 jushort* p, jushort v) { *p
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 jlong* p, jlong v)
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(); }

View File

@ -352,13 +352,6 @@ bool os::is_allocatable(size_t bytes) {
}
extern "C" void Fetch32PFI () ;
extern "C" void Fetch32Resume () ;
#ifdef AMD64
extern "C" void FetchNPFI () ;
extern "C" void FetchNResume () ;
#endif // AMD64
extern "C" JNIEXPORT int
JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
int abort_if_unrecognized) {
@ -374,6 +367,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
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) {
@ -436,17 +433,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
// factor me: getPCfromContext
pc = (address) uc->uc_mcontext.gregs[REG_PC];
// SafeFetch32() support
if (pc == (address) Fetch32PFI) {
uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ;
return true ;
if (StubRoutines::is_safefetch_fault(pc)) {
uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
return true;
}
#ifdef AMD64
if (pc == (address) FetchNPFI) {
uc->uc_mcontext.gregs [REG_PC] = intptr_t(FetchNResume) ;
return true ;
}
#endif // AMD64
// Handle ALL stack overflow variations here
if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {

View File

@ -54,20 +54,6 @@ fixcw:
popl %eax
ret
.align 16
.globl SafeFetch32
.globl SafeFetchN
.globl Fetch32PFI, Fetch32Resume
SafeFetch32:
SafeFetchN:
movl 0x8(%esp), %eax
movl 0x4(%esp), %ecx
Fetch32PFI:
movl (%ecx), %eax
Fetch32Resume:
ret
.align 16
.globl SpinPause
SpinPause:

View File

@ -21,54 +21,34 @@
/ questions.
/
.globl fs_load
.globl fs_thread
.globl fs_load
.globl fs_thread
// NOTE WELL! The _Copy functions are called directly
// from server-compiler-generated code via CallLeafNoFP,
// which means that they *must* either not use floating
// point or use it in the same manner as does the server
// compiler.
// from server-compiler-generated code via CallLeafNoFP,
// which means that they *must* either not use floating
// point or use it in the same manner as does the server
// compiler.
.globl _Copy_arrayof_conjoint_bytes
.globl _Copy_conjoint_jshorts_atomic
.globl _Copy_arrayof_conjoint_jshorts
.globl _Copy_arrayof_conjoint_jshorts
.globl _Copy_conjoint_jints_atomic
.globl _Copy_arrayof_conjoint_jints
.globl _Copy_conjoint_jlongs_atomic
.globl _Copy_conjoint_jlongs_atomic
.globl _Copy_arrayof_conjoint_jlongs
.section .text,"ax"
.section .text,"ax"
/ Fast thread accessors, used by threadLS_solaris_amd64.cpp
.align 16
.align 16
fs_load:
movq %fs:(%rdi),%rax
ret
.align 16
fs_thread:
movq %fs:0x0,%rax
ret
.globl SafeFetch32, Fetch32PFI, Fetch32Resume
.align 16
// Prototype: int SafeFetch32 (int * Adr, int ErrValue)
SafeFetch32:
movl %esi, %eax
Fetch32PFI:
movl (%rdi), %eax
Fetch32Resume:
movq %fs:(%rdi),%rax
ret
.globl SafeFetchN, FetchNPFI, FetchNResume
.align 16
// Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue)
SafeFetchN:
movq %rsi, %rax
FetchNPFI:
movq (%rdi), %rax
FetchNResume:
.align 16
fs_thread:
movq %fs:0x0,%rax
ret
.globl SpinPause
@ -78,7 +58,7 @@ SpinPause:
nop
movq $1, %rax
ret
/ Support for void Copy::arrayof_conjoint_bytes(void* from,
/ void* to,
@ -340,7 +320,7 @@ aci_CopyLeft:
addq $4,%rdx
jg 1b
ret
/ Support for void Copy::arrayof_conjoint_jlongs(jlong* from,
/ jlong* to,
/ size_t count)

View File

@ -71,7 +71,7 @@ inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; }
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 jushort* p, jushort v) { *p
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 jushort* p, jushort v)
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

View File

@ -518,24 +518,6 @@ void os::print_register_info(outputStream *st, void *context) {
st->cr();
}
extern "C" int SafeFetch32 (int * adr, int Err) {
int rv = Err ;
_try {
rv = *((volatile int *) adr) ;
} __except(EXCEPTION_EXECUTE_HANDLER) {
}
return rv ;
}
extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t Err) {
intptr_t rv = Err ;
_try {
rv = *((volatile intptr_t *) adr) ;
} __except(EXCEPTION_EXECUTE_HANDLER) {
}
return rv ;
}
extern "C" int SpinPause () {
#ifdef AMD64
return 0 ;

View File

@ -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 @@ typedef struct _RUNTIME_FUNCTION {
} 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 @@ typedef struct _DISPATCHER_CONTEXT {
PVOID HandlerData;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
#endif
#if _MSC_VER < 1500
/* Not needed for VS2008 compiler, comes from winnt.h. */

View File

@ -138,6 +138,16 @@ bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){
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 @@ void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) {
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;
}
}
}

View File

@ -80,6 +80,7 @@ class BCEscapeAnalyzer : public ResourceObj {
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);

View File

@ -3647,8 +3647,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// 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 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
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 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
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 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
}
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

View File

@ -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") \

View File

@ -873,7 +873,7 @@ bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc
size_t alloc_byte_size = alloc_word_size * HeapWordSize;
if ((cur_used_bytes + alloc_byte_size) > marking_initiating_used_threshold) {
if (gcs_are_young()) {
if (gcs_are_young() && !_last_young_gc) {
ergo_verbose5(ErgoConcCycles,
"request concurrent cycle initiation",
ergo_format_reason("occupancy higher than threshold")
@ -931,7 +931,7 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, Evacua
last_pause_included_initial_mark = during_initial_mark_pause();
if (last_pause_included_initial_mark) {
record_concurrent_mark_init_end(0.0);
} else if (!_last_young_gc && need_to_start_conc_mark("end of GC")) {
} else if (need_to_start_conc_mark("end of GC")) {
// Note: this might have already been set, if during the last
// pause we decided to start a cycle but at the beginning of
// this pause we decided to postpone it. That's OK.

View File

@ -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 @@ protected:
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 @@ protected:
_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 @@ protected:
_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 @@ protected:
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
}

View File

@ -140,8 +140,15 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
_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);

View File

@ -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 @@ InstanceKlass::InstanceKlass(int vtable_len,
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 @@ void InstanceKlass::release_C_heap_structures() {
}
// 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 @@ Method* InstanceKlass::method_with_idnum(int idnum) {
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.

View File

@ -133,6 +133,8 @@ class OopMapBlock VALUE_OBJ_CLASS_SPEC {
uint _count;
};
struct JvmtiCachedClassFileData;
class InstanceKlass: public Klass {
friend class VMStructs;
friend class ClassFileParser;
@ -249,8 +251,8 @@ class InstanceKlass: public Klass {
// 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 @@ class InstanceKlass: public Klass {
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) {

View File

@ -1163,6 +1163,7 @@ methodHandle Method::clone_with_new_data(methodHandle m, u_char* new_code, int n
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 @@ methodHandle Method::clone_with_new_data(methodHandle m, u_char* new_code, int n
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(),

View File

@ -297,15 +297,6 @@ bool InlineTree::should_not_inline(ciMethod *callee_method,
}
}
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;

View File

@ -2305,26 +2305,26 @@ void Matcher::validate_null_checks( ) {
// 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 @@ bool Matcher::post_store_load_barrier(const Node *vmb) {
// 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())
if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) {
return false;
}
}
return false;
}

View File

@ -294,25 +294,7 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
// 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>.

View File

@ -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 @@ static bool find_initial_Java_frame(JavaThread* thread,
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()) {

View File

@ -126,6 +126,7 @@ static const char * fatal_wrong_class_or_method = "Wrong object class or methodI
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 @@ checkString(JavaThread* thr, jstring js)
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;
}
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);
}
static inline arrayOop
check_is_primitive_array(JavaThread* thr, jarray jArray) {
arrayOop aOop = check_is_array(thr, jArray);
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 @@ JNI_ENTRY_CHECKED(jsize,
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 @@ JNI_ENTRY_CHECKED(jobject,
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 @@ JNI_ENTRY_CHECKED(void,
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 @@ JNI_ENTRY_CHECKED(ElementType *, \
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 @@ JNI_ENTRY_CHECKED(void, \
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 @@ JNI_ENTRY_CHECKED(void, \
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 @@ JNI_ENTRY_CHECKED(void, \
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 @@ JNI_ENTRY_CHECKED(void *,
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 @@ JNI_ENTRY_CHECKED(void,
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

View File

@ -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 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
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 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
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 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
_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 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
}
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 @@ void JvmtiExport::post_class_file_load_hook(Symbol* h_name,
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();
}

View File

@ -323,8 +323,7 @@ class JvmtiExport : public AllStatic {
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;

View File

@ -3342,9 +3342,7 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// 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 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// 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();

View File

@ -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 @@ class VM_RedefineClasses: public VM_Operation {
// 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

View File

@ -263,6 +263,7 @@ static ObsoleteFlag obsolete_jvm_flags[] = {
{ "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) },

View File

@ -221,9 +221,20 @@ bool frame::is_first_java_frame() const {
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 ||

View File

@ -353,7 +353,9 @@ class frame VALUE_OBJ_CLASS_SPEC {
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

View File

@ -2589,9 +2589,6 @@ class CommandLineFlags {
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") \

View File

@ -80,6 +80,8 @@ class JavaCallWrapper: StackObj {
oop receiver() { return _receiver; }
void oops_do(OopClosure* f);
bool is_first_frame() const { return _anchor.last_Java_sp() == NULL; }
};

View File

@ -1370,6 +1370,10 @@ void Monitor::check_prelock_state(Thread *thread) {
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) {

View File

@ -595,6 +595,22 @@ void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
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.

View File

@ -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 @@ class os: AllStatic {
#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 @@ class os: AllStatic {
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
@ -915,8 +923,6 @@ class os: AllStatic {
// of the global SpinPause() with C linkage.
// It'd also be eligible for inlining on many platforms.
extern "C" int SpinPause () ;
extern "C" int SafeFetch32 (int * adr, int errValue) ;
extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t errValue) ;
extern "C" int SpinPause();
#endif // SHARE_VM_RUNTIME_OS_HPP

View File

@ -136,6 +136,13 @@ double (* StubRoutines::_intrinsic_sin )(double) = NULL;
double (* StubRoutines::_intrinsic_cos )(double) = NULL;
double (* StubRoutines::_intrinsic_tan )(double) = NULL;
address StubRoutines::_safefetch32_entry = NULL;
address StubRoutines::_safefetch32_fault_pc = NULL;
address StubRoutines::_safefetch32_continuation_pc = NULL;
address StubRoutines::_safefetchN_entry = NULL;
address StubRoutines::_safefetchN_fault_pc = NULL;
address StubRoutines::_safefetchN_continuation_pc = NULL;
// Initialization
//
// Note: to break cycle with universe initialization, stubs are generated in two phases.

View File

@ -221,6 +221,14 @@ class StubRoutines: AllStatic {
static double (*_intrinsic_cos)(double);
static double (*_intrinsic_tan)(double);
// Safefetch stubs.
static address _safefetch32_entry;
static address _safefetch32_fault_pc;
static address _safefetch32_continuation_pc;
static address _safefetchN_entry;
static address _safefetchN_fault_pc;
static address _safefetchN_continuation_pc;
public:
// Initialization/Testing
static void initialize1(); // must happen before universe::genesis
@ -381,6 +389,34 @@ class StubRoutines: AllStatic {
return _intrinsic_tan(d);
}
//
// Safefetch stub support
//
typedef int (*SafeFetch32Stub)(int* adr, int errValue);
typedef intptr_t (*SafeFetchNStub) (intptr_t* adr, intptr_t errValue);
static SafeFetch32Stub SafeFetch32_stub() { return CAST_TO_FN_PTR(SafeFetch32Stub, _safefetch32_entry); }
static SafeFetchNStub SafeFetchN_stub() { return CAST_TO_FN_PTR(SafeFetchNStub, _safefetchN_entry); }
static bool is_safefetch_fault(address pc) {
return pc != NULL &&
(pc == _safefetch32_fault_pc ||
pc == _safefetchN_fault_pc);
}
static address continuation_for_safefetch_fault(address pc) {
assert(_safefetch32_continuation_pc != NULL &&
_safefetchN_continuation_pc != NULL,
"not initialized");
if (pc == _safefetch32_fault_pc) return _safefetch32_continuation_pc;
if (pc == _safefetchN_fault_pc) return _safefetchN_continuation_pc;
ShouldNotReachHere();
return NULL;
}
//
// Default versions of the above arraycopy functions for platforms which do
// not have specialized versions
@ -400,4 +436,15 @@ class StubRoutines: AllStatic {
static void arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count);
};
// Safefetch allows to load a value from a location that's not known
// to be valid. If the load causes a fault, the error value is returned.
inline int SafeFetch32(int* adr, int errValue) {
assert(StubRoutines::SafeFetch32_stub(), "stub not yet generated");
return StubRoutines::SafeFetch32_stub()(adr, errValue);
}
inline intptr_t SafeFetchN(intptr_t* adr, intptr_t errValue) {
assert(StubRoutines::SafeFetchN_stub(), "stub not yet generated");
return StubRoutines::SafeFetchN_stub()(adr, errValue);
}
#endif // SHARE_VM_RUNTIME_STUBROUTINES_HPP

View File

@ -218,6 +218,7 @@ Thread::Thread() {
// 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_stack(address adr) const {
}
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 @@ WatcherThread* WatcherThread::_watcher_thread = NULL;
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 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
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 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
// 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();
}

View File

@ -86,6 +86,8 @@ class GCTaskQueue;
class ThreadClosure;
class IdealGraphPrinter;
DEBUG_ONLY(class ResourceMark;)
class WorkerThread;
// Class hierarchy
@ -519,6 +521,9 @@ public:
// 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 @@ public:
// 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 @@ public:
// 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 @@ class WatcherThread: public Thread {
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 @@ class WatcherThread: public Thread {
// 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;
};

View File

@ -50,6 +50,7 @@ struct AttachOperationFunctionInfo {
class AttachListener: AllStatic {
public:
static void vm_start() NOT_SERVICES_RETURN;
static void init() NOT_SERVICES_RETURN;
static void abort() NOT_SERVICES_RETURN;

View File

@ -81,13 +81,13 @@ void MemTracker::init_tracking_options(const char* option_line) {
} else if (strcmp(option_line, "=detail") == 0) {
// detail relies on a stack-walking ability that may not
// be available depending on platform and/or compiler flags
if (PLATFORM_NMT_DETAIL_SUPPORTED) {
#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
_tracking_level = NMT_detail;
} else {
#else
jio_fprintf(defaultStream::error_stream(),
"NMT detail is not supported on this platform. Using NMT summary instead.");
"NMT detail is not supported on this platform. Using NMT summary instead.\n");
_tracking_level = NMT_summary;
}
#endif
} else if (strcmp(option_line, "=off") != 0) {
vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
}
@ -385,6 +385,7 @@ void MemTracker::enqueue_pending_recorder(MemRecorder* rec) {
#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 @@ void MemTracker::sync() {
// 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

View File

@ -63,5 +63,7 @@ typedef u8 stacktraceid;
typedef u8 methodid;
typedef u8 fieldid;
class TraceUnicodeString;
#endif // SHARE_VM_TRACE_TRACEDATATYPES_HPP

View File

@ -55,18 +55,6 @@ Before we can use it we need also define a primary field data type:
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 @@ creating the constant pool data in VM_JFRCheckpoint::write_checkpoint
<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 @@ creating the constant pool data in VM_JFRCheckpoint::write_checkpoint
<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"

View File

@ -1,28 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<!--
Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.

View File

@ -381,12 +381,12 @@ const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlass
#endif
/*
* If a platform does not support NMT_detail
* If a platform does not support native stack walking
* the platform specific globalDefinitions (above)
* can set PLATFORM_NMT_DETAIL_SUPPORTED to false
* can set PLATFORM_NATIVE_STACK_WALKING_SUPPORTED to 0
*/
#ifndef PLATFORM_NMT_DETAIL_SUPPORTED
#define PLATFORM_NMT_DETAIL_SUPPORTED true
#ifndef PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
#define PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 1
#endif
// The byte alignment to be used by Arena::Amalloc. See bugid 4169348.

View File

@ -296,6 +296,7 @@ stringStream::stringStream(size_t initial_size) : outputStream() {
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 @@ void stringStream::write(const char* s, size_t len) {
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;

View File

@ -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 @@ class stringStream : public outputStream {
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);

View File

@ -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");
}
}

View File

@ -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);
}
}

View File

@ -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.");
}
}

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -220,3 +220,5 @@ b8c5f4b6f0fffb44618fc609a584953c4ed67c0b jdk8-b95
6121efd299235b057f3de94b0a4158c388c2907c jdk8-b96
6c830db28d21108f32af990ecf4d80a75887980d jdk8-b97
15e5bb51bc0cd89304dc2f7f29b4c8002e632353 jdk8-b98
adf49c3ef83c160d53ece623049b2cdccaf78fc7 jdk8-b99
5d1974c1d7b9a86431bc253dc5a6a52d4586622e jdk8-b100

View File

@ -220,3 +220,5 @@ a0f604766ca14818e2a7b1558cc399499caabf75 jdk8-b92
690d34b326bc78a6f5f225522695b41c7f7f70e8 jdk8-b96
dcde7f049111353ad23175f54985a4f6bfea720c jdk8-b97
b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98
8ef83d4b23c933935e28f59b282cea920b1b1f5f jdk8-b99
4fd722afae5c02f00bbd44c3a34425ee474afb1c jdk8-b100

View File

@ -220,3 +220,5 @@ a2a2a91075ad85becbe10a39d7fd04ef9bea8df5 jdk8-b92
4a5d3cf2b3af1660db0237e8da324c140e534fa4 jdk8-b96
978a95239044f26dcc8a6d59246be07ad6ca6be2 jdk8-b97
c4908732fef5235f1b98cafe0ce507771ef7892c jdk8-b98
6a099a36589bd933957272ba63e5263bede29971 jdk8-b99
5be9c5bfcfe9b2a40412b4fb364377d49de014eb jdk8-b100

View File

@ -102,7 +102,7 @@ SUNWprivate_1.1 {
Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle;
Java_sun_security_pkcs11_Secmod_nssLoadLibrary;
Java_sun_security_pkcs11_Secmod_nssVersionCheck;
Java_sun_security_pkcs11_Secmod_nssInit;
Java_sun_security_pkcs11_Secmod_nssInitialize;
Java_sun_security_pkcs11_Secmod_nssGetModuleList;
local:

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 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
@ -102,7 +102,7 @@ SUNWprivate_1.1 {
Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle;
Java_sun_security_pkcs11_Secmod_nssLoadLibrary;
Java_sun_security_pkcs11_Secmod_nssVersionCheck;
Java_sun_security_pkcs11_Secmod_nssInit;
Java_sun_security_pkcs11_Secmod_nssInitialize;
Java_sun_security_pkcs11_Secmod_nssGetModuleList;
local:

View File

@ -32,6 +32,7 @@ import java.util.List;
import javax.swing.RootPaneContainer;
import com.apple.eawt.AppEvent.FullScreenEvent;
import sun.awt.SunToolkit;
import java.lang.annotation.Native;
@ -75,7 +76,7 @@ final class FullScreenHandler {
static void handleFullScreenEventFromNative(final Window window, final int type) {
if (!(window instanceof RootPaneContainer)) return; // handles null
EventQueue.invokeLater(new Runnable() {
SunToolkit.executeOnEventHandlerThread(window, new Runnable() {
public void run() {
final FullScreenHandler handler = getHandlerFor((RootPaneContainer)window);
if (handler != null) handler.notifyListener(new FullScreenEvent(window), type);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 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
@ -31,6 +31,8 @@ import java.io.File;
import java.net.*;
import java.util.*;
import java.util.List;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
import com.apple.eawt.AppEvent.*;
@ -269,11 +271,9 @@ class _AppEventHandler {
}
class _AppReOpenedDispatcher extends _AppEventMultiplexor<AppReOpenedListener> {
void performOnListeners(final List<AppReOpenedListener> listeners, final _NativeEvent event) {
void performOnListener(AppReOpenedListener listener, final _NativeEvent event) {
final AppReOpenedEvent e = new AppReOpenedEvent();
for (final AppReOpenedListener listener : listeners) {
listener.appReOpened(e);
}
listener.appReOpened(e);
}
}
@ -415,50 +415,67 @@ class _AppEventHandler {
}
abstract class _AppEventMultiplexor<L> {
final List<L> _listeners = new ArrayList<L>(0);
private final Map<L, AppContext> listenerToAppContext =
new IdentityHashMap<L, AppContext>();
boolean nativeListenerRegistered;
// called from AppKit Thread-0
void dispatch(final _NativeEvent event, final Object... args) {
// grab a local ref to the listeners
final List<L> localListeners;
// grab a local ref to the listeners and its contexts as an array of the map's entries
final ArrayList<Map.Entry<L, AppContext>> localEntries;
synchronized (this) {
if (_listeners.size() == 0) return;
localListeners = new ArrayList<L>(_listeners);
if (listenerToAppContext.size() == 0) {
return;
}
localEntries = new ArrayList<Map.Entry<L, AppContext>>(listenerToAppContext.size());
localEntries.addAll(listenerToAppContext.entrySet());
}
EventQueue.invokeLater(new Runnable() {
public void run() {
performOnListeners(localListeners, event);
}
});
for (final Map.Entry<L, AppContext> e : localEntries) {
final L listener = e.getKey();
final AppContext listenerContext = e.getValue();
SunToolkit.invokeLaterOnAppContext(listenerContext, new Runnable() {
public void run() {
performOnListener(listener, event);
}
});
}
}
synchronized void addListener(final L listener) {
setListenerContext(listener, AppContext.getAppContext());
if (!nativeListenerRegistered) {
registerNativeListener();
nativeListenerRegistered = true;
}
_listeners.add(listener);
}
synchronized void removeListener(final L listener) {
_listeners.remove(listener);
listenerToAppContext.remove(listener);
}
abstract void performOnListeners(final List<L> listeners, final _NativeEvent event);
abstract void performOnListener(L listener, final _NativeEvent event);
void registerNativeListener() { }
private void setListenerContext(L listener, AppContext listenerContext) {
if (listenerContext == null) {
throw new RuntimeException(
"Attempting to add a listener from a thread group without AppContext");
}
listenerToAppContext.put(listener, AppContext.getAppContext());
}
}
abstract class _BooleanAppEventMultiplexor<L, E> extends _AppEventMultiplexor<L> {
@Override
void performOnListeners(final List<L> listeners, final _NativeEvent event) {
void performOnListener(L listener, final _NativeEvent event) {
final boolean isTrue = Boolean.TRUE.equals(event.get(0));
final E e = createEvent(isTrue);
if (isTrue) {
for (final L listener : listeners) performTrueEventOn(listener, e);
performTrueEventOn(listener, e);
} else {
for (final L listener : listeners) performFalseEventOn(listener, e);
performFalseEventOn(listener, e);
}
}
@ -479,30 +496,34 @@ class _AppEventHandler {
*/
abstract class _AppEventDispatcher<H> {
H _handler;
AppContext handlerContext;
// called from AppKit Thread-0
void dispatch(final _NativeEvent event) {
EventQueue.invokeLater(new Runnable() {
public void run() {
// grab a local ref to the handler
final H localHandler;
synchronized (_AppEventDispatcher.this) {
localHandler = _handler;
}
// grab a local ref to the handler
final H localHandler;
final AppContext localHandlerContext;
synchronized (_AppEventDispatcher.this) {
localHandler = _handler;
localHandlerContext = handlerContext;
}
// invoke the handler outside of the synchronized block
if (localHandler == null) {
performDefaultAction(event);
} else {
if (localHandler == null) {
performDefaultAction(event);
} else {
SunToolkit.invokeLaterOnAppContext(localHandlerContext, new Runnable() {
public void run() {
performUsing(localHandler, event);
}
}
});
});
}
}
synchronized void setHandler(final H handler) {
this._handler = handler;
setHandlerContext(AppContext.getAppContext());
// if a new handler is installed, block addition of legacy ApplicationListeners
if (handler == legacyHandler) return;
legacyHandler.blockLegacyAPI();
@ -510,6 +531,15 @@ class _AppEventHandler {
void performDefaultAction(final _NativeEvent event) { } // by default, do nothing
abstract void performUsing(final H handler, final _NativeEvent event);
protected void setHandlerContext(AppContext ctx) {
if (ctx == null) {
throw new RuntimeException(
"Attempting to set a handler from a thread group without AppContext");
}
handlerContext = ctx;
}
}
abstract class _QueuingAppEventDispatcher<H> extends _AppEventDispatcher<H> {
@ -531,6 +561,8 @@ class _AppEventHandler {
synchronized void setHandler(final H handler) {
this._handler = handler;
setHandlerContext(AppContext.getAppContext());
// dispatch any events in the queue
if (queuedEvents != null) {
// grab a local ref to the queue, so the real one can be nulled out

View File

@ -25,6 +25,8 @@
package com.apple.eawt.event;
import sun.awt.SunToolkit;
import java.awt.*;
import java.util.*;
import java.util.List;
@ -70,7 +72,7 @@ final class GestureHandler {
static void handleGestureFromNative(final Window window, final int type, final double x, final double y, final double a, final double b) {
if (window == null) return; // should never happen...
EventQueue.invokeLater(new Runnable() {
SunToolkit.executeOnEventHandlerThread(window, new Runnable() {
public void run() {
final Component component = SwingUtilities.getDeepestComponentAt(window, (int)x, (int)y);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 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
@ -32,6 +32,7 @@ import java.util.Hashtable;
import javax.swing.*;
import sun.awt.SunToolkit;
import sun.lwawt.LWToolkit;
import sun.lwawt.macosx.*;
@ -144,7 +145,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
updateItems();
fItemBounds = new Rectangle[invoker.getMenuComponentCount()];
}
}, null);
}, invoker);
} catch (final Exception e) {
System.err.println(e);
e.printStackTrace();
@ -172,7 +173,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
fItemBounds = null;
}
}, null);
}, invoker);
} catch (final Exception e) {
e.printStackTrace();
}
@ -200,7 +201,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
if (kind == 0) return;
if (fItemBounds == null) return;
SwingUtilities.invokeLater(new Runnable() {
SunToolkit.executeOnEventHandlerThread(fInvoker, new Runnable() {
@Override
public void run() {
Component target = null;

Some files were not shown because too many files have changed in this diff Show More