Merge
This commit is contained in:
commit
18c3256b56
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
|
|||||||
|
|
||||||
HS_MAJOR_VER=25
|
HS_MAJOR_VER=25
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=41
|
HS_BUILD_NUMBER=42
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=8
|
JDK_MINOR_VER=8
|
||||||
|
@ -46,6 +46,7 @@ ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
|||||||
include $(MAKEFILES_DIR)/zeroshark.make
|
include $(MAKEFILES_DIR)/zeroshark.make
|
||||||
else
|
else
|
||||||
include $(MAKEFILES_DIR)/$(BUILDARCH).make
|
include $(MAKEFILES_DIR)/$(BUILDARCH).make
|
||||||
|
-include $(HS_ALT_MAKE)/$(Platform_os_family)/makefiles/$(BUILDARCH).make
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# set VPATH so make knows where to look for source files
|
# set VPATH so make knows where to look for source files
|
||||||
@ -380,4 +381,4 @@ build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) dtraceChe
|
|||||||
|
|
||||||
install: install_jvm install_jsig install_saproc
|
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
|
||||||
|
@ -410,6 +410,51 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
return start;
|
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
|
// 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
|
// Don't initialize the platform math functions since sparc
|
||||||
// doesn't have intrinsics for these operations.
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2766,6 +2766,39 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
return start;
|
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:
|
public:
|
||||||
// Information about frame layout at time of blocking runtime call.
|
// 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_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
|
||||||
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3357,7 +3357,45 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
return start;
|
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
|
// This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time
|
||||||
// to hide instruction latency
|
// to hide instruction latency
|
||||||
@ -3833,6 +3871,14 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
|
StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
|
||||||
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
|
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:
|
public:
|
||||||
|
@ -2323,6 +2323,11 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
|||||||
#endif
|
#endif
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
|
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
|
#ifndef _WIN64
|
||||||
// Execution protection violation - win32 running on AMD64 only
|
// Execution protection violation - win32 running on AMD64 only
|
||||||
// Handled first to avoid misdiagnosis as a "normal" access violation;
|
// Handled first to avoid misdiagnosis as a "normal" access violation;
|
||||||
|
@ -63,24 +63,6 @@ SYMBOL(fixcw):
|
|||||||
popl %eax
|
popl %eax
|
||||||
ret
|
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)
|
.globl SYMBOL(SpinPause)
|
||||||
ELF_TYPE(SpinPause,@function)
|
ELF_TYPE(SpinPause,@function)
|
||||||
.p2align 4,,15
|
.p2align 4,,15
|
||||||
|
@ -46,28 +46,6 @@
|
|||||||
|
|
||||||
.text
|
.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)
|
.globl SYMBOL(SpinPause)
|
||||||
.p2align 4,,15
|
.p2align 4,,15
|
||||||
ELF_TYPE(SpinPause,@function)
|
ELF_TYPE(SpinPause,@function)
|
||||||
|
@ -385,13 +385,6 @@ enum {
|
|||||||
trap_page_fault = 0xE
|
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
|
extern "C" JNIEXPORT int
|
||||||
JVM_handle_bsd_signal(int sig,
|
JVM_handle_bsd_signal(int sig,
|
||||||
siginfo_t* info,
|
siginfo_t* info,
|
||||||
@ -454,16 +447,10 @@ JVM_handle_bsd_signal(int sig,
|
|||||||
if (info != NULL && uc != NULL && thread != NULL) {
|
if (info != NULL && uc != NULL && thread != NULL) {
|
||||||
pc = (address) os::Bsd::ucontext_get_pc(uc);
|
pc = (address) os::Bsd::ucontext_get_pc(uc);
|
||||||
|
|
||||||
if (pc == (address) Fetch32PFI) {
|
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||||
uc->context_pc = intptr_t(Fetch32Resume) ;
|
uc->context_pc = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#ifdef AMD64
|
|
||||||
if (pc == (address) FetchNPFI) {
|
|
||||||
uc->context_pc = intptr_t (FetchNResume) ;
|
|
||||||
return 1 ;
|
|
||||||
}
|
|
||||||
#endif // AMD64
|
|
||||||
|
|
||||||
// Handle ALL stack overflow variations here
|
// Handle ALL stack overflow variations here
|
||||||
if (sig == SIGSEGV || sig == SIGBUS) {
|
if (sig == SIGSEGV || sig == SIGBUS) {
|
||||||
|
@ -21,42 +21,6 @@
|
|||||||
# questions.
|
# 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:
|
# Possibilities:
|
||||||
# -- membar
|
# -- membar
|
||||||
# -- CAS (SP + BIAS, G0, G0)
|
# -- CAS (SP + BIAS, G0, G0)
|
||||||
|
@ -366,18 +366,9 @@ intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) {
|
|||||||
|
|
||||||
// Utility functions
|
// 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) {
|
inline static bool checkPrefetch(sigcontext* uc, address pc) {
|
||||||
if (pc == (address) Fetch32PFI) {
|
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||||
set_cont_address(uc, address(Fetch32Resume));
|
set_cont_address(uc, address(StubRoutines::continuation_for_safefetch_fault(pc)));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (pc == (address) FetchNPFI) {
|
|
||||||
set_cont_address(uc, address(FetchNResume));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -42,24 +42,6 @@
|
|||||||
|
|
||||||
.text
|
.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
|
.globl SpinPause
|
||||||
.type SpinPause,@function
|
.type SpinPause,@function
|
||||||
.p2align 4,,15
|
.p2align 4,,15
|
||||||
|
@ -38,28 +38,6 @@
|
|||||||
|
|
||||||
.text
|
.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
|
.globl SpinPause
|
||||||
.align 16
|
.align 16
|
||||||
.type SpinPause,@function
|
.type SpinPause,@function
|
||||||
|
@ -209,13 +209,6 @@ enum {
|
|||||||
trap_page_fault = 0xE
|
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
|
extern "C" JNIEXPORT int
|
||||||
JVM_handle_linux_signal(int sig,
|
JVM_handle_linux_signal(int sig,
|
||||||
siginfo_t* info,
|
siginfo_t* info,
|
||||||
@ -278,16 +271,10 @@ JVM_handle_linux_signal(int sig,
|
|||||||
if (info != NULL && uc != NULL && thread != NULL) {
|
if (info != NULL && uc != NULL && thread != NULL) {
|
||||||
pc = (address) os::Linux::ucontext_get_pc(uc);
|
pc = (address) os::Linux::ucontext_get_pc(uc);
|
||||||
|
|
||||||
if (pc == (address) Fetch32PFI) {
|
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||||
uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ;
|
uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#ifdef AMD64
|
|
||||||
if (pc == (address) FetchNPFI) {
|
|
||||||
uc->uc_mcontext.gregs[REG_PC] = intptr_t (FetchNResume) ;
|
|
||||||
return 1 ;
|
|
||||||
}
|
|
||||||
#endif // AMD64
|
|
||||||
|
|
||||||
#ifndef AMD64
|
#ifndef AMD64
|
||||||
// Halt if SI_KERNEL before more crashes get misdiagnosed as Java bugs
|
// Halt if SI_KERNEL before more crashes get misdiagnosed as Java bugs
|
||||||
|
@ -303,11 +303,6 @@ bool os::is_allocatable(size_t bytes) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Fetch32PFI () ;
|
|
||||||
extern "C" void Fetch32Resume () ;
|
|
||||||
extern "C" void FetchNPFI () ;
|
|
||||||
extern "C" void FetchNResume () ;
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT int
|
extern "C" JNIEXPORT int
|
||||||
JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
@ -379,17 +374,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
|||||||
npc = (address) uc->uc_mcontext.gregs[REG_nPC];
|
npc = (address) uc->uc_mcontext.gregs[REG_nPC];
|
||||||
|
|
||||||
// SafeFetch() support
|
// SafeFetch() support
|
||||||
// Implemented with either a fixed set of addresses such
|
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||||
// as Fetch32*, or with Thread._OnTrap.
|
uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
|
||||||
if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(Fetch32PFI)) {
|
uc->uc_mcontext.gregs[REG_nPC] = uc->uc_mcontext.gregs[REG_PC] + 4;
|
||||||
uc->uc_mcontext.gregs [REG_PC] = intptr_t(Fetch32Resume) ;
|
return 1;
|
||||||
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 ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle ALL stack overflow variations here
|
// Handle ALL stack overflow variations here
|
||||||
|
@ -21,47 +21,6 @@
|
|||||||
!! questions.
|
!! 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:
|
!! Possibilities:
|
||||||
!! -- membar
|
!! -- membar
|
||||||
!! -- CAS (SP + BIAS, G0, G0)
|
!! -- CAS (SP + BIAS, G0, G0)
|
||||||
|
@ -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
|
extern "C" JNIEXPORT int
|
||||||
JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
@ -436,17 +429,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
|||||||
// factor me: getPCfromContext
|
// factor me: getPCfromContext
|
||||||
pc = (address) uc->uc_mcontext.gregs[REG_PC];
|
pc = (address) uc->uc_mcontext.gregs[REG_PC];
|
||||||
|
|
||||||
// SafeFetch32() support
|
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||||
if (pc == (address) Fetch32PFI) {
|
uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
|
||||||
uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ;
|
|
||||||
return true;
|
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
|
// Handle ALL stack overflow variations here
|
||||||
if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
|
if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
|
||||||
|
@ -54,20 +54,6 @@ fixcw:
|
|||||||
popl %eax
|
popl %eax
|
||||||
ret
|
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
|
.align 16
|
||||||
.globl SpinPause
|
.globl SpinPause
|
||||||
SpinPause:
|
SpinPause:
|
||||||
|
@ -51,26 +51,6 @@ fs_thread:
|
|||||||
movq %fs:0x0,%rax
|
movq %fs:0x0,%rax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.globl SafeFetch32, Fetch32PFI, Fetch32Resume
|
|
||||||
.align 16
|
|
||||||
// Prototype: int SafeFetch32 (int * Adr, int ErrValue)
|
|
||||||
SafeFetch32:
|
|
||||||
movl %esi, %eax
|
|
||||||
Fetch32PFI:
|
|
||||||
movl (%rdi), %eax
|
|
||||||
Fetch32Resume:
|
|
||||||
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:
|
|
||||||
ret
|
|
||||||
|
|
||||||
.globl SpinPause
|
.globl SpinPause
|
||||||
.align 16
|
.align 16
|
||||||
SpinPause:
|
SpinPause:
|
||||||
|
@ -518,24 +518,6 @@ void os::print_register_info(outputStream *st, void *context) {
|
|||||||
st->cr();
|
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 () {
|
extern "C" int SpinPause () {
|
||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
return 0 ;
|
return 0 ;
|
||||||
|
@ -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;
|
size_t alloc_byte_size = alloc_word_size * HeapWordSize;
|
||||||
|
|
||||||
if ((cur_used_bytes + alloc_byte_size) > marking_initiating_used_threshold) {
|
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,
|
ergo_verbose5(ErgoConcCycles,
|
||||||
"request concurrent cycle initiation",
|
"request concurrent cycle initiation",
|
||||||
ergo_format_reason("occupancy higher than threshold")
|
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();
|
last_pause_included_initial_mark = during_initial_mark_pause();
|
||||||
if (last_pause_included_initial_mark) {
|
if (last_pause_included_initial_mark) {
|
||||||
record_concurrent_mark_init_end(0.0);
|
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
|
// Note: this might have already been set, if during the last
|
||||||
// pause we decided to start a cycle but at the beginning of
|
// pause we decided to start a cycle but at the beginning of
|
||||||
// this pause we decided to postpone it. That's OK.
|
// this pause we decided to postpone it. That's OK.
|
||||||
|
@ -916,7 +916,5 @@ class os: AllStatic {
|
|||||||
// It'd also be eligible for inlining on many platforms.
|
// It'd also be eligible for inlining on many platforms.
|
||||||
|
|
||||||
extern "C" int SpinPause();
|
extern "C" int SpinPause();
|
||||||
extern "C" int SafeFetch32 (int * adr, int errValue) ;
|
|
||||||
extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t errValue) ;
|
|
||||||
|
|
||||||
#endif // SHARE_VM_RUNTIME_OS_HPP
|
#endif // SHARE_VM_RUNTIME_OS_HPP
|
||||||
|
@ -136,6 +136,13 @@ double (* StubRoutines::_intrinsic_sin )(double) = NULL;
|
|||||||
double (* StubRoutines::_intrinsic_cos )(double) = NULL;
|
double (* StubRoutines::_intrinsic_cos )(double) = NULL;
|
||||||
double (* StubRoutines::_intrinsic_tan )(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
|
// Initialization
|
||||||
//
|
//
|
||||||
// Note: to break cycle with universe initialization, stubs are generated in two phases.
|
// Note: to break cycle with universe initialization, stubs are generated in two phases.
|
||||||
|
@ -221,6 +221,14 @@ class StubRoutines: AllStatic {
|
|||||||
static double (*_intrinsic_cos)(double);
|
static double (*_intrinsic_cos)(double);
|
||||||
static double (*_intrinsic_tan)(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:
|
public:
|
||||||
// Initialization/Testing
|
// Initialization/Testing
|
||||||
static void initialize1(); // must happen before universe::genesis
|
static void initialize1(); // must happen before universe::genesis
|
||||||
@ -381,6 +389,34 @@ class StubRoutines: AllStatic {
|
|||||||
return _intrinsic_tan(d);
|
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
|
// Default versions of the above arraycopy functions for platforms which do
|
||||||
// not have specialized versions
|
// not have specialized versions
|
||||||
@ -400,4 +436,15 @@ class StubRoutines: AllStatic {
|
|||||||
static void arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count);
|
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
|
#endif // SHARE_VM_RUNTIME_STUBROUTINES_HPP
|
||||||
|
@ -81,13 +81,13 @@ void MemTracker::init_tracking_options(const char* option_line) {
|
|||||||
} else if (strcmp(option_line, "=detail") == 0) {
|
} else if (strcmp(option_line, "=detail") == 0) {
|
||||||
// detail relies on a stack-walking ability that may not
|
// detail relies on a stack-walking ability that may not
|
||||||
// be available depending on platform and/or compiler flags
|
// be available depending on platform and/or compiler flags
|
||||||
if (PLATFORM_NMT_DETAIL_SUPPORTED) {
|
#if PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
|
||||||
_tracking_level = NMT_detail;
|
_tracking_level = NMT_detail;
|
||||||
} else {
|
#else
|
||||||
jio_fprintf(defaultStream::error_stream(),
|
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;
|
_tracking_level = NMT_summary;
|
||||||
}
|
#endif
|
||||||
} else if (strcmp(option_line, "=off") != 0) {
|
} else if (strcmp(option_line, "=off") != 0) {
|
||||||
vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
|
vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
|
||||||
}
|
}
|
||||||
|
@ -381,12 +381,12 @@ const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlass
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a platform does not support NMT_detail
|
* If a platform does not support native stack walking
|
||||||
* the platform specific globalDefinitions (above)
|
* 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
|
#ifndef PLATFORM_NATIVE_STACK_WALKING_SUPPORTED
|
||||||
#define PLATFORM_NMT_DETAIL_SUPPORTED true
|
#define PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The byte alignment to be used by Arena::Amalloc. See bugid 4169348.
|
// The byte alignment to be used by Arena::Amalloc. See bugid 4169348.
|
||||||
|
Loading…
Reference in New Issue
Block a user