8139864: Improve handling of stack protection zones
Reviewed-by: stuefe, coleenp, fparain
This commit is contained in:
parent
8c13cfe16c
commit
b5bca5cc1b
@ -58,7 +58,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
address unextended_sp = (address)_unextended_sp;
|
||||
|
||||
// consider stack guards when trying to determine "safe" stack pointers
|
||||
static size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
|
||||
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
|
||||
(JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size()) : 0;
|
||||
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
|
||||
|
||||
// sp must be within the usable part of the stack (not in guards)
|
||||
|
@ -3938,7 +3938,7 @@ void MacroAssembler::bang_stack_size(Register size, Register tmp) {
|
||||
// was post-decremented.) Skip this address by starting at i=1, and
|
||||
// touch a few more pages below. N.B. It is important to touch all
|
||||
// the way down to and including i=StackShadowPages.
|
||||
for (int i = 0; i< StackShadowPages-1; i++) {
|
||||
for (int i = 0; i < (JavaThread::stack_shadow_zone_size() / os::vm_page_size()) - 1; i++) {
|
||||
// this could be any sized move but this is can be a debugging crumb
|
||||
// so the bigger the better.
|
||||
lea(tmp, Address(tmp, -os::vm_page_size()));
|
||||
|
@ -1542,7 +1542,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
|
||||
// Generate stack overflow check
|
||||
if (UseStackBanging) {
|
||||
__ bang_stack_with_offset(StackShadowPages*os::vm_page_size());
|
||||
__ bang_stack_with_offset(JavaThread::stack_shadow_zone_size());
|
||||
} else {
|
||||
Unimplemented();
|
||||
}
|
||||
@ -1949,7 +1949,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
Label reguard;
|
||||
Label reguard_done;
|
||||
__ ldrb(rscratch1, Address(rthread, JavaThread::stack_guard_state_offset()));
|
||||
__ cmpw(rscratch1, JavaThread::stack_guard_yellow_disabled);
|
||||
__ cmpw(rscratch1, JavaThread::stack_guard_yellow_reserved_disabled);
|
||||
__ br(Assembler::EQ, reguard);
|
||||
__ bind(reguard_done);
|
||||
|
||||
|
@ -474,12 +474,12 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
|
||||
__ sub(rscratch1, rscratch1, rscratch2); // Stack limit
|
||||
__ add(r0, r0, rscratch1);
|
||||
|
||||
// Use the maximum number of pages we might bang.
|
||||
const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages :
|
||||
(StackRedPages+StackYellowPages);
|
||||
// Use the bigger size for banging.
|
||||
const int max_bang_size = MAX2(JavaThread::stack_shadow_zone_size(),
|
||||
JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size());
|
||||
|
||||
// add in the red and yellow zone sizes
|
||||
__ add(r0, r0, max_pages * page_size * 2);
|
||||
__ add(r0, r0, max_bang_size * 2);
|
||||
|
||||
// check against the current stack bottom
|
||||
__ cmp(sp, r0);
|
||||
@ -826,9 +826,10 @@ void InterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
|
||||
// an interpreter frame with greater than a page of locals, so each page
|
||||
// needs to be checked. Only true for non-native.
|
||||
if (UseStackBanging) {
|
||||
const int start_page = native_call ? StackShadowPages : 1;
|
||||
const int size_t n_shadow_pages = JavaThread::stack_shadow_zone_size() / os::vm_page_size();
|
||||
const int start_page = native_call ? n_shadow_pages : 1;
|
||||
const int page_size = os::vm_page_size();
|
||||
for (int pages = start_page; pages <= StackShadowPages ; pages++) {
|
||||
for (int pages = start_page; pages <= n_shadow_pages ; pages++) {
|
||||
__ sub(rscratch2, sp, pages*page_size);
|
||||
__ str(zr, Address(rscratch2));
|
||||
}
|
||||
|
@ -46,9 +46,9 @@ define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs pas
|
||||
#define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2))
|
||||
#define DEFAULT_STACK_RESERVED_PAGES (0)
|
||||
|
||||
#define MIN_STACK_YELLOW_PAGES (1)
|
||||
#define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
|
||||
#define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES
|
||||
#define MIN_STACK_SHADOW_PAGES (1)
|
||||
#define MIN_STACK_SHADOW_PAGES (3 DEBUG_ONLY(+1))
|
||||
#define MIN_STACK_RESERVED_PAGES (0)
|
||||
|
||||
define_pd_global(intx, StackYellowPages, DEFAULT_STACK_YELLOW_PAGES);
|
||||
|
@ -1308,7 +1308,7 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||
// insert the code of generate_stack_overflow_check(), see
|
||||
// assembler.cpp for some illuminative comments.
|
||||
const int page_size = os::vm_page_size();
|
||||
int bang_end = StackShadowPages * page_size;
|
||||
int bang_end = JavaThread::stack_shadow_zone_size();
|
||||
|
||||
// This is how far the previous frame's stack banging extended.
|
||||
const int bang_end_safe = bang_end;
|
||||
|
@ -2388,7 +2388,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
|
||||
Label no_reguard;
|
||||
__ lwz(r_temp_1, thread_(stack_guard_state));
|
||||
__ cmpwi(CCR0, r_temp_1, JavaThread::stack_guard_yellow_disabled);
|
||||
__ cmpwi(CCR0, r_temp_1, JavaThread::stack_guard_yellow_reserved_disabled);
|
||||
__ bne(CCR0, no_reguard);
|
||||
|
||||
save_native_result(masm, ret_type, workspace_slot_offset);
|
||||
|
@ -3595,7 +3595,7 @@ void MacroAssembler::bang_stack_size(Register Rsize, Register Rtsp,
|
||||
// was post-decremented.) Skip this address by starting at i=1, and
|
||||
// touch a few more pages below. N.B. It is important to touch all
|
||||
// the way down to and including i=StackShadowPages.
|
||||
for (int i = 1; i < StackShadowPages; i++) {
|
||||
for (int i = 1; i < JavaThread::stack_shadow_zone_size() / os::vm_page_size(); i++) {
|
||||
set((-i*offset)+STACK_BIAS, Rscratch);
|
||||
st(G0, Rtsp, Rscratch);
|
||||
}
|
||||
|
@ -2643,7 +2643,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
|
||||
Label no_reguard;
|
||||
__ ld(G2_thread, JavaThread::stack_guard_state_offset(), G3_scratch);
|
||||
__ cmp_and_br_short(G3_scratch, JavaThread::stack_guard_yellow_disabled, Assembler::notEqual, Assembler::pt, no_reguard);
|
||||
__ cmp_and_br_short(G3_scratch, JavaThread::stack_guard_yellow_reserved_disabled, Assembler::notEqual, Assembler::pt, no_reguard);
|
||||
|
||||
save_native_result(masm, ret_type, stack_slots);
|
||||
__ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages));
|
||||
@ -2936,7 +2936,7 @@ void SharedRuntime::generate_deopt_blob() {
|
||||
int pad = VerifyThread ? 512 : 0;// Extra slop space for more verify code
|
||||
#ifdef ASSERT
|
||||
if (UseStackBanging) {
|
||||
pad += StackShadowPages*16 + 32;
|
||||
pad += (JavaThread::stack_shadow_zone_size() / os::vm_page_size())*16 + 32;
|
||||
}
|
||||
#endif
|
||||
#if INCLUDE_JVMCI
|
||||
@ -3225,7 +3225,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
|
||||
int pad = VerifyThread ? 512 : 0;
|
||||
#ifdef ASSERT
|
||||
if (UseStackBanging) {
|
||||
pad += StackShadowPages*16 + 32;
|
||||
pad += (JavaThread::stack_shadow_zone_size() / os::vm_page_size())*16 + 32;
|
||||
}
|
||||
#endif
|
||||
#ifdef _LP64
|
||||
|
@ -437,7 +437,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
|
||||
|
||||
// compute the beginning of the protected zone minus the requested frame size
|
||||
__ sub( Rscratch, Rscratch2, Rscratch );
|
||||
__ set( (StackRedPages+StackYellowPages) * page_size, Rscratch2 );
|
||||
__ set( JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size(), Rscratch2 );
|
||||
__ add( Rscratch, Rscratch2, Rscratch );
|
||||
|
||||
// Add in the size of the frame (which is the same as subtracting it from the
|
||||
|
@ -56,7 +56,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
address unextended_sp = (address)_unextended_sp;
|
||||
|
||||
// consider stack guards when trying to determine "safe" stack pointers
|
||||
static size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
|
||||
static size_t stack_guard_size = os::uses_stack_guard_pages() ?
|
||||
JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size() : 0;
|
||||
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
|
||||
|
||||
// sp must be within the usable part of the stack (not in guards)
|
||||
|
@ -1059,8 +1059,8 @@ void MacroAssembler::bang_stack_size(Register size, Register tmp) {
|
||||
// touch it again. (It was touched as (tmp-pagesize) but then tmp
|
||||
// was post-decremented.) Skip this address by starting at i=1, and
|
||||
// touch a few more pages below. N.B. It is important to touch all
|
||||
// the way down to and including i=StackShadowPages.
|
||||
for (int i = 1; i < StackShadowPages; i++) {
|
||||
// the way down including all pages in the shadow zone.
|
||||
for (int i = 1; i < ((int)JavaThread::stack_shadow_zone_size() / os::vm_page_size()); i++) {
|
||||
// this could be any sized move but this is can be a debugging crumb
|
||||
// so the bigger the better.
|
||||
movptr(Address(tmp, (-i*os::vm_page_size())), size );
|
||||
|
@ -1776,7 +1776,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
// Generate stack overflow check
|
||||
|
||||
if (UseStackBanging) {
|
||||
__ bang_stack_with_offset(StackShadowPages*os::vm_page_size());
|
||||
__ bang_stack_with_offset((int)JavaThread::stack_shadow_zone_size());
|
||||
} else {
|
||||
// need a 5 byte instruction to allow MT safe patching to non-entrant
|
||||
__ fat_nop();
|
||||
@ -2151,7 +2151,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
|
||||
Label reguard;
|
||||
Label reguard_done;
|
||||
__ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled);
|
||||
__ cmpl(Address(thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_reserved_disabled);
|
||||
__ jcc(Assembler::equal, reguard);
|
||||
|
||||
// slow path reguard re-enters here
|
||||
|
@ -2065,7 +2065,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
// Generate stack overflow check
|
||||
|
||||
if (UseStackBanging) {
|
||||
__ bang_stack_with_offset(StackShadowPages*os::vm_page_size());
|
||||
__ bang_stack_with_offset((int)JavaThread::stack_shadow_zone_size());
|
||||
} else {
|
||||
// need a 5 byte instruction to allow MT safe patching to non-entrant
|
||||
__ fat_nop();
|
||||
@ -2499,7 +2499,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
|
||||
Label reguard;
|
||||
Label reguard_done;
|
||||
__ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled);
|
||||
__ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_reserved_disabled);
|
||||
__ jcc(Assembler::equal, reguard);
|
||||
__ bind(reguard_done);
|
||||
|
||||
|
@ -540,12 +540,12 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
|
||||
__ addptr(rax, stack_base);
|
||||
__ subptr(rax, stack_size);
|
||||
|
||||
// Use the maximum number of pages we might bang.
|
||||
const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages+StackReservedPages) ? StackShadowPages :
|
||||
(StackRedPages+StackYellowPages+StackReservedPages);
|
||||
// Use the bigger size for banging.
|
||||
const int max_bang_size = (int)MAX2(JavaThread::stack_shadow_zone_size(),
|
||||
JavaThread::stack_guard_zone_size());
|
||||
|
||||
// add in the red and yellow zone sizes
|
||||
__ addptr(rax, max_pages * page_size);
|
||||
__ addptr(rax, max_bang_size);
|
||||
|
||||
// check against the current stack bottom
|
||||
__ cmpptr(rsp, rax);
|
||||
@ -1187,7 +1187,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
{
|
||||
Label no_reguard;
|
||||
__ cmpl(Address(thread, JavaThread::stack_guard_state_offset()),
|
||||
JavaThread::stack_guard_yellow_disabled);
|
||||
JavaThread::stack_guard_yellow_reserved_disabled);
|
||||
__ jcc(Assembler::notEqual, no_reguard);
|
||||
|
||||
__ pusha(); // XXX only save smashed registers
|
||||
|
@ -40,7 +40,7 @@ class ZeroStack {
|
||||
public:
|
||||
ZeroStack()
|
||||
: _base(NULL), _top(NULL), _sp(NULL) {
|
||||
_shadow_pages_size = StackShadowPages * os::vm_page_size();
|
||||
_shadow_pages_size = JavaThread::stack_shadow_zone_size();
|
||||
}
|
||||
|
||||
bool needs_setup() const {
|
||||
|
@ -49,10 +49,11 @@ inline void ZeroStack::overflow_check(int required_words, TRAPS) {
|
||||
// value can be negative.
|
||||
inline int ZeroStack::abi_stack_available(Thread *thread) const {
|
||||
guarantee(Thread::current() == thread, "should run in the same thread");
|
||||
int stack_used = thread->stack_base() - (address) &stack_used
|
||||
+ (StackYellowPages+StackRedPages+StackShadowPages) * os::vm_page_size();
|
||||
int stack_free = thread->stack_size() - stack_used;
|
||||
return stack_free;
|
||||
assert(thread->stack_size() -
|
||||
(thread->stack_base() - (address) &stack_used +
|
||||
JavaThread::stack_guard_zone_size() + JavaThread::stack_shadow_zone_size()) ==
|
||||
(address)&stack_used - thread->stack_overflow_limit(), "sanity");
|
||||
return (address)&stack_used - stack_overflow_limit();
|
||||
}
|
||||
|
||||
#endif // CPU_ZERO_VM_STACK_ZERO_INLINE_HPP
|
||||
|
@ -845,7 +845,7 @@ static void *java_start(Thread *thread) {
|
||||
trcVerbose("newborn Thread : pthread-id %u, ktid " UINT64_FORMAT
|
||||
", stack %p ... %p, stacksize 0x%IX (%IB)",
|
||||
pthread_id, kernel_thread_id,
|
||||
thread->stack_base() - thread->stack_size(),
|
||||
thread->stack_end(),
|
||||
thread->stack_base(),
|
||||
thread->stack_size(),
|
||||
thread->stack_size());
|
||||
@ -1014,7 +1014,7 @@ bool os::create_attached_thread(JavaThread* thread) {
|
||||
|
||||
trcVerbose("attaching Thread : pthread-id %u, ktid " UINT64_FORMAT ", stack %p ... %p, stacksize 0x%IX (%IB)",
|
||||
pthread_id, kernel_thread_id,
|
||||
thread->stack_base() - thread->stack_size(),
|
||||
thread->stack_end(),
|
||||
thread->stack_base(),
|
||||
thread->stack_size(),
|
||||
thread->stack_size());
|
||||
@ -3570,15 +3570,6 @@ void os::init(void) {
|
||||
Aix::_main_thread = pthread_self();
|
||||
|
||||
initial_time_count = os::elapsed_counter();
|
||||
|
||||
// If the pagesize of the VM is greater than 8K determine the appropriate
|
||||
// number of initial guard pages. The user can change this with the
|
||||
// command line arguments, if needed.
|
||||
if (vm_page_size() > (int)Aix::vm_default_page_size()) {
|
||||
StackYellowPages = 1;
|
||||
StackRedPages = 1;
|
||||
StackShadowPages = round_to((StackShadowPages*Aix::vm_default_page_size()), vm_page_size()) / vm_page_size();
|
||||
}
|
||||
}
|
||||
|
||||
// This is called _after_ the global arguments have been parsed.
|
||||
@ -3684,8 +3675,9 @@ jint os::init_2(void) {
|
||||
// Add in 2*BytesPerWord times page size to account for VM stack during
|
||||
// class initialization depending on 32 or 64 bit VM.
|
||||
os::Aix::min_stack_allowed = MAX2(os::Aix::min_stack_allowed,
|
||||
(size_t)(StackYellowPages+StackRedPages+StackShadowPages) * Aix::page_size() +
|
||||
(2*BytesPerWord COMPILER2_PRESENT(+1)) * Aix::vm_default_page_size());
|
||||
JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size() +
|
||||
(2*BytesPerWord COMPILER2_PRESENT(+1)) * Aix::vm_default_page_size());
|
||||
|
||||
os::Aix::min_stack_allowed = align_size_up(os::Aix::min_stack_allowed, os::Aix::page_size());
|
||||
|
||||
|
@ -3479,8 +3479,9 @@ jint os::init_2(void) {
|
||||
// Add in 2*BytesPerWord times page size to account for VM stack during
|
||||
// class initialization depending on 32 or 64 bit VM.
|
||||
os::Bsd::min_stack_allowed = MAX2(os::Bsd::min_stack_allowed,
|
||||
(size_t)(StackReservedPages+StackYellowPages+StackRedPages+StackShadowPages+
|
||||
2*BytesPerWord COMPILER2_PRESENT(+1)) * Bsd::page_size());
|
||||
JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size() +
|
||||
2*BytesPerWord COMPILER2_PRESENT(+1) * Bsd::page_size());
|
||||
|
||||
size_t threadStackSizeInBytes = ThreadStackSize * K;
|
||||
if (threadStackSizeInBytes != 0 &&
|
||||
|
@ -621,7 +621,7 @@ bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
|
||||
assert(t->osthread()->expanding_stack(), "expand should be set");
|
||||
assert(t->stack_base() != NULL, "stack_base was not initialized");
|
||||
|
||||
if (addr < t->stack_base() && addr >= t->stack_yellow_zone_base()) {
|
||||
if (addr < t->stack_base() && addr >= t->stack_reserved_zone_base()) {
|
||||
sigset_t mask_all, old_sigset;
|
||||
sigfillset(&mask_all);
|
||||
pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);
|
||||
@ -836,7 +836,7 @@ bool os::create_attached_thread(JavaThread* thread) {
|
||||
// is no gap between the last two virtual memory regions.
|
||||
|
||||
JavaThread *jt = (JavaThread *)thread;
|
||||
address addr = jt->stack_yellow_zone_base();
|
||||
address addr = jt->stack_reserved_zone_base();
|
||||
assert(addr != NULL, "initialization problem?");
|
||||
assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
|
||||
|
||||
@ -1863,8 +1863,7 @@ void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf,
|
||||
while (jt) {
|
||||
if (!jt->stack_guard_zone_unused() && // Stack not yet fully initialized
|
||||
jt->stack_guards_enabled()) { // No pending stack overflow exceptions
|
||||
if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(),
|
||||
jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) {
|
||||
if (!os::guard_memory((char *)jt->stack_end(), jt->stack_guard_zone_size())) {
|
||||
warning("Attempt to reguard stack yellow zone failed.");
|
||||
}
|
||||
}
|
||||
@ -4580,20 +4579,6 @@ void os::init(void) {
|
||||
}
|
||||
// else it defaults to CLOCK_REALTIME
|
||||
|
||||
// If the pagesize of the VM is greater than 8K determine the appropriate
|
||||
// number of initial guard pages. The user can change this with the
|
||||
// command line arguments, if needed.
|
||||
if (vm_page_size() > (int)Linux::vm_default_page_size()) {
|
||||
StackYellowPages = 1;
|
||||
StackRedPages = 1;
|
||||
#if defined(IA32) || defined(IA64)
|
||||
StackReservedPages = 1;
|
||||
#else
|
||||
StackReservedPages = 0;
|
||||
#endif
|
||||
StackShadowPages = round_to((StackShadowPages*Linux::vm_default_page_size()), vm_page_size()) / vm_page_size();
|
||||
}
|
||||
|
||||
// retrieve entry point for pthread_setname_np
|
||||
Linux::_pthread_setname_np =
|
||||
(int(*)(pthread_t, const char*))dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||
@ -4652,7 +4637,8 @@ jint os::init_2(void) {
|
||||
// Add in 2*BytesPerWord times page size to account for VM stack during
|
||||
// class initialization depending on 32 or 64 bit VM.
|
||||
os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed,
|
||||
(size_t)(StackReservedPages+StackYellowPages+StackRedPages+StackShadowPages) * Linux::page_size() +
|
||||
JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size() +
|
||||
(2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::vm_default_page_size());
|
||||
|
||||
size_t threadStackSizeInBytes = ThreadStackSize * K;
|
||||
|
@ -4359,15 +4359,6 @@ void os::init(void) {
|
||||
// the minimum of what the OS supports (thr_min_stack()), and
|
||||
// enough to allow the thread to get to user bytecode execution.
|
||||
Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed);
|
||||
// If the pagesize of the VM is greater than 8K determine the appropriate
|
||||
// number of initial guard pages. The user can change this with the
|
||||
// command line arguments, if needed.
|
||||
if (vm_page_size() > 8*K) {
|
||||
StackYellowPages = 1;
|
||||
StackRedPages = 1;
|
||||
StackReservedPages = 1;
|
||||
StackShadowPages = round_to((StackShadowPages*8*K), vm_page_size()) / vm_page_size();
|
||||
}
|
||||
}
|
||||
|
||||
// To install functions for atexit system call
|
||||
@ -4422,8 +4413,9 @@ jint os::init_2(void) {
|
||||
// Add in 2*BytesPerWord times page size to account for VM stack during
|
||||
// class initialization depending on 32 or 64 bit VM.
|
||||
os::Solaris::min_stack_allowed = MAX2(os::Solaris::min_stack_allowed,
|
||||
(size_t)(StackReservedPages+StackYellowPages+StackRedPages+StackShadowPages+
|
||||
2*BytesPerWord COMPILER2_PRESENT(+1)) * page_size);
|
||||
JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size() +
|
||||
2*BytesPerWord COMPILER2_PRESENT(+1) * page_size);
|
||||
|
||||
size_t threadStackSizeInBytes = ThreadStackSize * K;
|
||||
if (threadStackSizeInBytes != 0 &&
|
||||
@ -4443,7 +4435,8 @@ jint os::init_2(void) {
|
||||
if (vm_page_size() > 8*K) {
|
||||
threadStackSizeInBytes = (threadStackSizeInBytes != 0)
|
||||
? threadStackSizeInBytes +
|
||||
((StackYellowPages + StackRedPages) * vm_page_size())
|
||||
JavaThread::stack_red_zone_size() +
|
||||
JavaThread::stack_yellow_zone_size()
|
||||
: 0;
|
||||
ThreadStackSize = threadStackSizeInBytes/K;
|
||||
}
|
||||
|
@ -2551,8 +2551,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
} else if(thread->addr_inside_register_stack(addr)) {
|
||||
// Disable the yellow zone which sets the state that
|
||||
// we've got a stack overflow problem.
|
||||
if (thread->stack_yellow_zone_enabled()) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
if (thread->stack_yellow_reserved_zone_enabled()) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
}
|
||||
// Give us some room to process the exception.
|
||||
thread->disable_register_stack_guard();
|
||||
@ -2587,7 +2587,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
// Yellow zone violation. The o/s has unprotected the first yellow
|
||||
// zone page for us. Note: must call disable_stack_yellow_zone to
|
||||
// update the enabled status, even if the zone contains only one page.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
// If not in java code, return and hope for the best.
|
||||
return in_java
|
||||
? Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW))
|
||||
@ -2616,7 +2616,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
if (in_java) {
|
||||
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
|
||||
address addr = (address) exceptionRecord->ExceptionInformation[1];
|
||||
address stack_end = thread->stack_base() - thread->stack_size();
|
||||
address stack_end = thread->stack_end();
|
||||
if (addr < stack_end && addr >= stack_end - os::vm_page_size()) {
|
||||
// Stack overflow.
|
||||
assert(!os::uses_stack_guard_pages(),
|
||||
@ -2640,7 +2640,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
//
|
||||
PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
|
||||
address addr = (address) exceptionRecord->ExceptionInformation[1];
|
||||
if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base()) {
|
||||
if (addr > thread->stack_reserved_zone_base() && addr < thread->stack_base()) {
|
||||
addr = (address)((uintptr_t)addr &
|
||||
(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
|
||||
os::commit_memory((char *)addr, thread->stack_base() - addr,
|
||||
@ -4080,7 +4080,7 @@ void nx_check_protection() {
|
||||
#endif // _WIN64
|
||||
#endif // PRODUCT
|
||||
|
||||
// this is called _before_ the global arguments have been parsed
|
||||
// This is called _before_ the global arguments have been parsed
|
||||
void os::init(void) {
|
||||
_initial_pid = _getpid();
|
||||
|
||||
@ -4185,8 +4185,9 @@ jint os::init_2(void) {
|
||||
// Add in 2*BytesPerWord times page size to account for VM stack during
|
||||
// class initialization depending on 32 or 64 bit VM.
|
||||
size_t min_stack_allowed =
|
||||
(size_t)(StackYellowPages+StackRedPages+StackShadowPages+
|
||||
2*BytesPerWord COMPILER2_PRESENT(+1)) * os::vm_page_size();
|
||||
(size_t)(JavaThread::stack_yellow_zone_size() + JavaThread::stack_red_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size() +
|
||||
(2*BytesPerWord COMPILER2_PRESENT(+1)) * os::vm_page_size());
|
||||
if (actual_reserve_size < min_stack_allowed) {
|
||||
tty->print_cr("\nThe stack size specified is too small, "
|
||||
"Specify at least %dk",
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
|
||||
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
|
||||
inline const char* os::dll_file_extension() { return ".dll"; }
|
||||
|
||||
@ -72,7 +73,7 @@ inline void os::bang_stack_shadow_pages() {
|
||||
// the OS may not map an intervening page into our space
|
||||
// and may fault on a memory access to interior of our frame.
|
||||
address sp = current_stack_pointer();
|
||||
for (int pages = 1; pages <= StackShadowPages; pages++) {
|
||||
for (size_t pages = 1; pages <= (JavaThread::stack_shadow_zone_size() / os::vm_page_size()); pages++) {
|
||||
*((int *)(sp - (pages * vm_page_size()))) = 0;
|
||||
}
|
||||
}
|
||||
|
@ -238,8 +238,7 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
|
||||
if (thread != NULL) {
|
||||
|
||||
// Handle ALL stack overflow variations here
|
||||
if (sig == SIGSEGV && (addr < thread->stack_base() &&
|
||||
addr >= thread->stack_base() - thread->stack_size())) {
|
||||
if (sig == SIGSEGV && thread->on_local_stack(addr)) {
|
||||
// stack overflow
|
||||
//
|
||||
// If we are in a yellow zone and we are inside java, we disable the yellow zone and
|
||||
@ -247,8 +246,8 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
|
||||
// If we are in native code or VM C code, we report-and-die. The original coding tried
|
||||
// to continue with yellow zone disabled, but that doesn't buy us much and prevents
|
||||
// hs_err_pid files.
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
// Throw a stack overflow exception.
|
||||
// Guard pages will be reenabled while unwinding the stack.
|
||||
|
@ -518,10 +518,9 @@ JVM_handle_bsd_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (addr < thread->stack_base() &&
|
||||
addr >= thread->stack_base() - thread->stack_size()) {
|
||||
if (thread->on_local_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
if (thread->in_stack_reserved_zone(addr)) {
|
||||
frame fr;
|
||||
@ -542,11 +541,11 @@ JVM_handle_bsd_signal(int sig,
|
||||
}
|
||||
// Throw a stack overflow exception. Guard pages will be reenabled
|
||||
// while unwinding the stack.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
|
||||
} else {
|
||||
// Thread was in the vm or native code. Return and try to finish.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
return 1;
|
||||
}
|
||||
} else if (thread->in_stack_red_zone(addr)) {
|
||||
|
@ -187,11 +187,10 @@ JVM_handle_bsd_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (addr < thread->stack_base() &&
|
||||
addr >= thread->stack_base() - thread->stack_size()) {
|
||||
if (thread->on_local_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
ShouldNotCallThis();
|
||||
}
|
||||
else if (thread->in_stack_red_zone(addr)) {
|
||||
|
@ -330,11 +330,10 @@ JVM_handle_linux_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (addr < thread->stack_base() &&
|
||||
addr >= thread->stack_base() - thread->stack_size()) {
|
||||
if (thread->on_local_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
// Throw a stack overflow exception. Guard pages will be reenabled
|
||||
// while unwinding the stack.
|
||||
|
@ -242,11 +242,10 @@ JVM_handle_linux_signal(int sig,
|
||||
address addr = ((NativeInstruction*)pc)->get_stack_bang_address(uc);
|
||||
|
||||
// Check if fault address is within thread stack.
|
||||
if (addr < thread->stack_base() &&
|
||||
addr >= thread->stack_base() - thread->stack_size()) {
|
||||
if (thread->on_local_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
// Throw a stack overflow exception.
|
||||
// Guard pages will be reenabled while unwinding the stack.
|
||||
|
@ -380,11 +380,10 @@ inline static bool checkOverflow(sigcontext* uc,
|
||||
JavaThread* thread,
|
||||
address* stub) {
|
||||
// check if fault address is within thread stack
|
||||
if (addr < thread->stack_base() &&
|
||||
addr >= thread->stack_base() - thread->stack_size()) {
|
||||
if (thread->on_local_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
// Throw a stack overflow exception. Guard pages will be reenabled
|
||||
// while unwinding the stack.
|
||||
|
@ -346,10 +346,9 @@ JVM_handle_linux_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (addr < thread->stack_base() &&
|
||||
addr >= thread->stack_base() - thread->stack_size()) {
|
||||
if (thread->on_local_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
if (thread->in_stack_reserved_zone(addr)) {
|
||||
frame fr;
|
||||
@ -371,11 +370,11 @@ JVM_handle_linux_signal(int sig,
|
||||
}
|
||||
// Throw a stack overflow exception. Guard pages will be reenabled
|
||||
// while unwinding the stack.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
|
||||
} else {
|
||||
// Thread was in the vm or native code. Return and try to finish.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
return 1;
|
||||
}
|
||||
} else if (thread->in_stack_red_zone(addr)) {
|
||||
@ -931,10 +930,10 @@ void os::workaround_expand_exec_shield_cs_limit() {
|
||||
* If we are embedded in an app other than launcher (initial != main stack),
|
||||
* we don't have much control or understanding of the address space, just let it slide.
|
||||
*/
|
||||
char* hint = (char*) (Linux::initial_thread_stack_bottom() -
|
||||
((StackReservedPages + StackYellowPages + StackRedPages + 1) * page_size));
|
||||
char* hint = (char*)(Linux::initial_thread_stack_bottom() -
|
||||
(JavaThread::stack_guard_zone_size() + page_size));
|
||||
char* codebuf = os::attempt_reserve_memory_at(page_size, hint);
|
||||
if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
|
||||
if ((codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true))) {
|
||||
return; // No matter, we tried, best effort.
|
||||
}
|
||||
|
||||
|
@ -178,11 +178,10 @@ JVM_handle_linux_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (addr < thread->stack_base() &&
|
||||
addr >= thread->stack_base() - thread->stack_size()) {
|
||||
if (thread->on_local_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
thread->disable_stack_yellow_zone();
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
ShouldNotCallThis();
|
||||
}
|
||||
else if (thread->in_stack_red_zone(addr)) {
|
||||
|
@ -402,7 +402,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
// Handle ALL stack overflow variations here
|
||||
if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
|
||||
address addr = (address) info->si_addr;
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
// Sometimes the register windows are not properly flushed.
|
||||
if(uc->uc_mcontext.gwins != NULL) {
|
||||
::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
|
||||
@ -424,11 +424,11 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
}
|
||||
// Throw a stack overflow exception. Guard pages will be reenabled
|
||||
// while unwinding the stack.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
|
||||
} else {
|
||||
// Thread was in the vm or native code. Return and try to finish.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
return true;
|
||||
}
|
||||
} else if (thread->in_stack_red_zone(addr)) {
|
||||
|
@ -465,7 +465,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
// Handle ALL stack overflow variations here
|
||||
if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
|
||||
address addr = (address) info->si_addr;
|
||||
if (thread->in_stack_yellow_zone(addr)) {
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
if (thread->in_stack_reserved_zone(addr)) {
|
||||
frame fr;
|
||||
@ -486,11 +486,11 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
}
|
||||
// Throw a stack overflow exception. Guard pages will be reenabled
|
||||
// while unwinding the stack.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
|
||||
} else {
|
||||
// Thread was in the vm or native code. Return and try to finish.
|
||||
thread->disable_stack_yellow_zone();
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
return true;
|
||||
}
|
||||
} else if (thread->in_stack_red_zone(addr)) {
|
||||
|
@ -65,23 +65,19 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr,
|
||||
|
||||
// Something would really have to be screwed up to get a NULL pc
|
||||
|
||||
if (addr.pc() == NULL ) {
|
||||
if (addr.pc() == NULL) {
|
||||
assert(false, "NULL pc from signal handler!");
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// If sp and fp are nonsense just leave them out
|
||||
|
||||
if ((address)ret_sp >= jt->stack_base() ||
|
||||
(address)ret_sp < jt->stack_base() - jt->stack_size() ) {
|
||||
|
||||
ret_sp = NULL;
|
||||
ret_fp = NULL;
|
||||
if (!jt->on_local_stack((address)ret_sp)) {
|
||||
ret_sp = NULL;
|
||||
ret_fp = NULL;
|
||||
} else {
|
||||
|
||||
// sp is reasonable is fp reasonable?
|
||||
if ( (address)ret_fp >= jt->stack_base() || ret_fp < ret_sp) {
|
||||
if ((address)ret_fp >= jt->stack_base() || ret_fp < ret_sp) {
|
||||
ret_fp = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,13 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/codeBuffer.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "asm/codeBuffer.hpp"
|
||||
#include "runtime/atomic.inline.hpp"
|
||||
#include "runtime/icache.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
|
||||
|
||||
// Implementation of AbstractAssembler
|
||||
@ -132,7 +133,7 @@ void AbstractAssembler::generate_stack_overflow_check(int frame_size_in_bytes) {
|
||||
// is greater than a page.
|
||||
|
||||
const int page_size = os::vm_page_size();
|
||||
int bang_end = StackShadowPages * page_size;
|
||||
int bang_end = (int)JavaThread::stack_shadow_zone_size();
|
||||
|
||||
// This is how far the previous frame's stack banging extended.
|
||||
const int bang_end_safe = bang_end;
|
||||
|
@ -532,9 +532,10 @@ void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
|
||||
// an interpreter frame with greater than a page of locals, so each page
|
||||
// needs to be checked. Only true for non-native.
|
||||
if (UseStackBanging) {
|
||||
const int start_page = native_call ? StackShadowPages : 1;
|
||||
const int page_size = os::vm_page_size();
|
||||
for (int pages = start_page; pages <= StackShadowPages ; pages++) {
|
||||
const int n_shadow_pages = ((int)JavaThread::stack_shadow_zone_size()) / page_size;
|
||||
const int start_page = native_call ? n_shadow_pages : 1;
|
||||
for (int pages = start_page; pages <= n_shadow_pages; pages++) {
|
||||
__ bang_stack_with_offset(pages*page_size);
|
||||
}
|
||||
}
|
||||
|
@ -1201,7 +1201,7 @@ WB_END
|
||||
|
||||
WB_ENTRY(jlong, WB_GetThreadRemainingStackSize(JNIEnv* env, jobject o))
|
||||
JavaThread* t = JavaThread::current();
|
||||
return (jlong) t->stack_available(os::current_stack_pointer()) - (jlong) StackShadowPages * os::vm_page_size();
|
||||
return (jlong) t->stack_available(os::current_stack_pointer()) - (jlong)JavaThread::stack_shadow_zone_size();
|
||||
WB_END
|
||||
|
||||
|
||||
|
@ -3428,15 +3428,18 @@ public:
|
||||
\
|
||||
/* stack parameters */ \
|
||||
product_pd(intx, StackYellowPages, \
|
||||
"Number of yellow zone (recoverable overflows) pages") \
|
||||
"Number of yellow zone (recoverable overflows) pages of size " \
|
||||
"4KB. If pages are bigger yellow zone is aligned up.") \
|
||||
range(MIN_STACK_YELLOW_PAGES, (DEFAULT_STACK_YELLOW_PAGES+5)) \
|
||||
\
|
||||
product_pd(intx, StackRedPages, \
|
||||
"Number of red zone (unrecoverable overflows) pages") \
|
||||
"Number of red zone (unrecoverable overflows) pages of size " \
|
||||
"4KB. If pages are bigger red zone is aligned up.") \
|
||||
range(MIN_STACK_RED_PAGES, (DEFAULT_STACK_RED_PAGES+2)) \
|
||||
\
|
||||
product_pd(intx, StackReservedPages, \
|
||||
"Number of reserved zone (reserved to annotated methods) pages") \
|
||||
"Number of reserved zone (reserved to annotated methods) pages" \
|
||||
" of size 4KB. If pages are bigger reserved zone is aligned up.") \
|
||||
range(MIN_STACK_RESERVED_PAGES, (DEFAULT_STACK_RESERVED_PAGES+10))\
|
||||
\
|
||||
product(bool, RestrictReservedStack, true, \
|
||||
@ -3444,13 +3447,14 @@ public:
|
||||
\
|
||||
/* greater stack shadow pages can't generate instruction to bang stack */ \
|
||||
product_pd(intx, StackShadowPages, \
|
||||
"Number of shadow zone (for overflow checking) pages " \
|
||||
"this should exceed the depth of the VM and native call stack") \
|
||||
"Number of shadow zone (for overflow checking) pages of size " \
|
||||
"4KB. If pages are bigger shadow zone is aligned up. " \
|
||||
"This should exceed the depth of the VM and native call stack.") \
|
||||
range(MIN_STACK_SHADOW_PAGES, (DEFAULT_STACK_SHADOW_PAGES+30)) \
|
||||
\
|
||||
product_pd(intx, ThreadStackSize, \
|
||||
"Thread Stack Size (in Kbytes)") \
|
||||
range(0, max_intx-os::vm_page_size()) \
|
||||
range(0, (max_intx-os::vm_page_size())/(1 * K)) \
|
||||
\
|
||||
product_pd(intx, VMThreadStackSize, \
|
||||
"Non-Java Thread Stack Size (in Kbytes)") \
|
||||
@ -3458,7 +3462,7 @@ public:
|
||||
\
|
||||
product_pd(intx, CompilerThreadStackSize, \
|
||||
"Compiler Thread Stack Size (in Kbytes)") \
|
||||
range(0, max_intx /(1 * K)) \
|
||||
range(0, max_intx/(1 * K)) \
|
||||
\
|
||||
develop_pd(size_t, JVMInvokeMethodSlack, \
|
||||
"Stack space (bytes) required for JVM_InvokeMethod to complete") \
|
||||
|
@ -316,8 +316,16 @@ void os::init_before_ergo() {
|
||||
// decisions depending on large page support and the calculated large page size.
|
||||
large_page_init();
|
||||
|
||||
// We need to adapt the configured number of stack protection pages given
|
||||
// in 4K pages to the actual os page size. We must do this before setting
|
||||
// up minimal stack sizes etc. in os::init_2().
|
||||
JavaThread::set_stack_red_zone_size (align_size_up(StackRedPages * 4 * K, vm_page_size()));
|
||||
JavaThread::set_stack_yellow_zone_size (align_size_up(StackYellowPages * 4 * K, vm_page_size()));
|
||||
JavaThread::set_stack_reserved_zone_size(align_size_up(StackReservedPages * 4 * K, vm_page_size()));
|
||||
JavaThread::set_stack_shadow_zone_size (align_size_up(StackShadowPages * 4 * K, vm_page_size()));
|
||||
|
||||
// VM version initialization identifies some characteristics of the
|
||||
// the platform that are used during ergonomic decisions.
|
||||
// platform that are used during ergonomic decisions.
|
||||
VM_Version::init_before_ergo();
|
||||
}
|
||||
|
||||
@ -1015,8 +1023,7 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||
}
|
||||
// If the addr is in the stack region for this thread then report that
|
||||
// and print thread info
|
||||
if (thread->stack_base() >= addr &&
|
||||
addr > (thread->stack_base() - thread->stack_size())) {
|
||||
if (thread->on_local_stack(addr)) {
|
||||
st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: "
|
||||
INTPTR_FORMAT, p2i(addr), p2i(thread));
|
||||
if (verbose) thread->print_on(st);
|
||||
@ -1375,9 +1382,8 @@ void os::serialize_thread_states() {
|
||||
|
||||
// Returns true if the current stack pointer is above the stack shadow
|
||||
// pages, false otherwise.
|
||||
|
||||
bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method) {
|
||||
assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check");
|
||||
if (!thread->is_Java_thread()) return false;
|
||||
address sp = current_stack_pointer();
|
||||
// Check if we have StackShadowPages above the yellow zone. This parameter
|
||||
// is dependent on the depth of the maximum VM call stack possible from
|
||||
@ -1386,12 +1392,13 @@ bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method
|
||||
// respectively.
|
||||
const int framesize_in_bytes =
|
||||
Interpreter::size_top_interpreter_activation(method()) * wordSize;
|
||||
int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages
|
||||
+ StackReservedPages) * vm_page_size())
|
||||
+ framesize_in_bytes;
|
||||
// The very lower end of the stack
|
||||
address stack_limit = thread->stack_base() - thread->stack_size();
|
||||
return (sp > (stack_limit + reserved_area));
|
||||
|
||||
assert((thread->stack_base() - thread->stack_size()) +
|
||||
(JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size() + framesize_in_bytes) ==
|
||||
((JavaThread*)thread)->stack_overflow_limit() + framesize_in_bytes, "sanity");
|
||||
|
||||
return (sp > ((JavaThread*)thread)->stack_overflow_limit() + framesize_in_bytes);
|
||||
}
|
||||
|
||||
size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {
|
||||
|
@ -319,8 +319,7 @@ void Thread::record_stack_base_and_size() {
|
||||
|
||||
#if INCLUDE_NMT
|
||||
// record thread's native stack, stack grows downward
|
||||
address stack_low_addr = stack_base() - stack_size();
|
||||
MemTracker::record_thread_stack(stack_low_addr, stack_size());
|
||||
MemTracker::record_thread_stack(stack_end(), stack_size());
|
||||
#endif // INCLUDE_NMT
|
||||
}
|
||||
|
||||
@ -337,8 +336,7 @@ Thread::~Thread() {
|
||||
// not proper way to enforce that.
|
||||
#if INCLUDE_NMT
|
||||
if (_stack_base != NULL) {
|
||||
address low_stack_addr = stack_base() - stack_size();
|
||||
MemTracker::release_thread_stack(low_stack_addr, stack_size());
|
||||
MemTracker::release_thread_stack(stack_end(), stack_size());
|
||||
#ifdef ASSERT
|
||||
set_stack_base(NULL);
|
||||
#endif
|
||||
@ -821,7 +819,7 @@ void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
|
||||
else st->print("Thread");
|
||||
|
||||
st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
|
||||
p2i(_stack_base - _stack_size), p2i(_stack_base));
|
||||
p2i(stack_end()), p2i(stack_base()));
|
||||
|
||||
if (osthread()) {
|
||||
st->print(" [id=%d]", osthread()->thread_id());
|
||||
@ -907,9 +905,8 @@ bool Thread::is_in_stack(address adr) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Thread::is_in_usable_stack(address adr) const {
|
||||
size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
|
||||
size_t stack_guard_size = os::uses_stack_guard_pages() ? JavaThread::stack_guard_zone_size() : 0;
|
||||
size_t usable_stack_size = _stack_size - stack_guard_size;
|
||||
|
||||
return ((adr < stack_base()) && (adr >= stack_base() - usable_stack_size));
|
||||
@ -1534,7 +1531,7 @@ JavaThread::JavaThread(bool is_attaching_via_jni) :
|
||||
}
|
||||
|
||||
bool JavaThread::reguard_stack(address cur_sp) {
|
||||
if (_stack_guard_state != stack_guard_yellow_disabled
|
||||
if (_stack_guard_state != stack_guard_yellow_reserved_disabled
|
||||
&& _stack_guard_state != stack_guard_reserved_disabled) {
|
||||
return true; // Stack already guarded or guard pages not needed.
|
||||
}
|
||||
@ -1551,9 +1548,10 @@ bool JavaThread::reguard_stack(address cur_sp) {
|
||||
// is executing there, either StackShadowPages should be larger, or
|
||||
// some exception code in c1, c2 or the interpreter isn't unwinding
|
||||
// when it should.
|
||||
guarantee(cur_sp > stack_yellow_zone_base(), "not enough space to reguard - increase StackShadowPages");
|
||||
if (_stack_guard_state == stack_guard_yellow_disabled) {
|
||||
enable_stack_yellow_zone();
|
||||
guarantee(cur_sp > stack_reserved_zone_base(),
|
||||
"not enough space to reguard - increase StackShadowPages");
|
||||
if (_stack_guard_state == stack_guard_yellow_reserved_disabled) {
|
||||
enable_stack_yellow_reserved_zone();
|
||||
if (reserved_stack_activation() != stack_base()) {
|
||||
set_reserved_stack_activation(stack_base());
|
||||
}
|
||||
@ -2480,10 +2478,15 @@ void JavaThread::java_resume() {
|
||||
}
|
||||
}
|
||||
|
||||
size_t JavaThread::_stack_red_zone_size = 0;
|
||||
size_t JavaThread::_stack_yellow_zone_size = 0;
|
||||
size_t JavaThread::_stack_reserved_zone_size = 0;
|
||||
size_t JavaThread::_stack_shadow_zone_size = 0;
|
||||
|
||||
void JavaThread::create_stack_guard_pages() {
|
||||
if (! os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) return;
|
||||
address low_addr = stack_base() - stack_size();
|
||||
size_t len = (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size();
|
||||
if (!os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) { return; }
|
||||
address low_addr = stack_end();
|
||||
size_t len = stack_guard_zone_size();
|
||||
|
||||
int allocate = os::allocate_stack_guard_pages();
|
||||
// warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
|
||||
@ -2506,8 +2509,8 @@ void JavaThread::create_stack_guard_pages() {
|
||||
void JavaThread::remove_stack_guard_pages() {
|
||||
assert(Thread::current() == this, "from different thread");
|
||||
if (_stack_guard_state == stack_guard_unused) return;
|
||||
address low_addr = stack_base() - stack_size();
|
||||
size_t len = (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size();
|
||||
address low_addr = stack_end();
|
||||
size_t len = stack_guard_zone_size();
|
||||
|
||||
if (os::allocate_stack_guard_pages()) {
|
||||
if (os::remove_stack_guard_pages((char *) low_addr, len)) {
|
||||
@ -2563,18 +2566,18 @@ void JavaThread::disable_stack_reserved_zone() {
|
||||
disable_register_stack_guard();
|
||||
}
|
||||
|
||||
void JavaThread::enable_stack_yellow_zone() {
|
||||
void JavaThread::enable_stack_yellow_reserved_zone() {
|
||||
assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
|
||||
assert(_stack_guard_state != stack_guard_enabled, "already enabled");
|
||||
|
||||
// The base notation is from the stacks point of view, growing downward.
|
||||
// We need to adjust it to work correctly with guard_memory()
|
||||
address base = stack_yellow_zone_base() - stack_yellow_zone_size();
|
||||
address base = stack_red_zone_base();
|
||||
|
||||
guarantee(base < stack_base(), "Error calculating stack yellow zone");
|
||||
guarantee(base < os::current_stack_pointer(), "Error calculating stack yellow zone");
|
||||
|
||||
if (os::guard_memory((char *) base, stack_yellow_zone_size())) {
|
||||
if (os::guard_memory((char *) base, stack_yellow_reserved_zone_size())) {
|
||||
_stack_guard_state = stack_guard_enabled;
|
||||
} else {
|
||||
warning("Attempt to guard stack yellow zone failed.");
|
||||
@ -2582,19 +2585,19 @@ void JavaThread::enable_stack_yellow_zone() {
|
||||
enable_register_stack_guard();
|
||||
}
|
||||
|
||||
void JavaThread::disable_stack_yellow_zone() {
|
||||
void JavaThread::disable_stack_yellow_reserved_zone() {
|
||||
assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
|
||||
assert(_stack_guard_state != stack_guard_yellow_disabled, "already disabled");
|
||||
assert(_stack_guard_state != stack_guard_yellow_reserved_disabled, "already disabled");
|
||||
|
||||
// Simply return if called for a thread that does not use guard pages.
|
||||
if (_stack_guard_state == stack_guard_unused) return;
|
||||
|
||||
// The base notation is from the stacks point of view, growing downward.
|
||||
// We need to adjust it to work correctly with guard_memory()
|
||||
address base = stack_yellow_zone_base() - stack_yellow_zone_size();
|
||||
address base = stack_red_zone_base();
|
||||
|
||||
if (os::unguard_memory((char *)base, stack_yellow_zone_size())) {
|
||||
_stack_guard_state = stack_guard_yellow_disabled;
|
||||
if (os::unguard_memory((char *)base, stack_yellow_reserved_zone_size())) {
|
||||
_stack_guard_state = stack_guard_yellow_reserved_disabled;
|
||||
} else {
|
||||
warning("Attempt to unguard stack yellow zone failed.");
|
||||
}
|
||||
@ -2899,7 +2902,7 @@ void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const {
|
||||
st->print(", id=%d", osthread()->thread_id());
|
||||
}
|
||||
st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")",
|
||||
p2i(_stack_base - _stack_size), p2i(_stack_base));
|
||||
p2i(stack_end()), p2i(stack_base()));
|
||||
st->print("]");
|
||||
return;
|
||||
}
|
||||
|
@ -549,15 +549,15 @@ protected:
|
||||
public:
|
||||
// Stack overflow support
|
||||
address stack_base() const { assert(_stack_base != NULL,"Sanity check"); return _stack_base; }
|
||||
|
||||
void set_stack_base(address base) { _stack_base = base; }
|
||||
size_t stack_size() const { return _stack_size; }
|
||||
void set_stack_size(size_t size) { _stack_size = size; }
|
||||
address stack_end() const { return stack_base() - stack_size(); }
|
||||
void record_stack_base_and_size();
|
||||
|
||||
bool on_local_stack(address adr) const {
|
||||
// QQQ this has knowledge of direction, ought to be a stack method
|
||||
return (_stack_base >= adr && adr >= (_stack_base - _stack_size));
|
||||
return (_stack_base >= adr && adr >= stack_end());
|
||||
}
|
||||
|
||||
uintptr_t self_raw_id() { return _self_raw_id; }
|
||||
@ -910,7 +910,7 @@ class JavaThread: public Thread {
|
||||
enum StackGuardState {
|
||||
stack_guard_unused, // not needed
|
||||
stack_guard_reserved_disabled,
|
||||
stack_guard_yellow_disabled,// disabled (temporarily) after stack overflow
|
||||
stack_guard_yellow_reserved_disabled,// disabled (temporarily) after stack overflow
|
||||
stack_guard_enabled // enabled
|
||||
};
|
||||
|
||||
@ -1344,32 +1344,138 @@ class JavaThread: public Thread {
|
||||
}
|
||||
|
||||
// Stack overflow support
|
||||
//
|
||||
// (small addresses)
|
||||
//
|
||||
// -- <-- stack_end() ---
|
||||
// | |
|
||||
// | red pages |
|
||||
// | |
|
||||
// -- <-- stack_red_zone_base() |
|
||||
// | |
|
||||
// | guard
|
||||
// | yellow pages zone
|
||||
// | |
|
||||
// | |
|
||||
// -- <-- stack_yellow_zone_base() |
|
||||
// | |
|
||||
// | |
|
||||
// | reserved pages |
|
||||
// | |
|
||||
// -- <-- stack_reserved_zone_base() --- ---
|
||||
// /|\ shadow
|
||||
// | zone
|
||||
// \|/ size
|
||||
// some untouched memory --- <-- stack_overflow_limit()
|
||||
//
|
||||
//
|
||||
// --
|
||||
// |
|
||||
// | shadow zone
|
||||
// |
|
||||
// --
|
||||
// x frame n
|
||||
// --
|
||||
// x frame n-1
|
||||
// x
|
||||
// --
|
||||
// ...
|
||||
//
|
||||
// --
|
||||
// x frame 0
|
||||
// -- <-- stack_base()
|
||||
//
|
||||
// (large addresses)
|
||||
//
|
||||
|
||||
private:
|
||||
// These values are derived from flags StackRedPages, StackYellowPages,
|
||||
// StackReservedPages and StackShadowPages. The zone size is determined
|
||||
// ergonomically if page_size > 4K.
|
||||
static size_t _stack_red_zone_size;
|
||||
static size_t _stack_yellow_zone_size;
|
||||
static size_t _stack_reserved_zone_size;
|
||||
static size_t _stack_shadow_zone_size;
|
||||
public:
|
||||
inline size_t stack_available(address cur_sp);
|
||||
address stack_reserved_zone_base() {
|
||||
return stack_yellow_zone_base(); }
|
||||
size_t stack_reserved_zone_size() {
|
||||
return StackReservedPages * os::vm_page_size(); }
|
||||
address stack_yellow_zone_base() {
|
||||
return (address)(stack_base() -
|
||||
(stack_size() -
|
||||
(stack_red_zone_size() + stack_yellow_zone_size())));
|
||||
|
||||
static size_t stack_red_zone_size() {
|
||||
assert(_stack_red_zone_size > 0, "Don't call this before the field is initialized.");
|
||||
return _stack_red_zone_size;
|
||||
}
|
||||
size_t stack_yellow_zone_size() {
|
||||
return StackYellowPages * os::vm_page_size() + stack_reserved_zone_size();
|
||||
static void set_stack_red_zone_size(size_t s) {
|
||||
assert(is_size_aligned(s, os::vm_page_size()),
|
||||
"We can not protect if the red zone size is not page aligned.");
|
||||
assert(_stack_red_zone_size == 0, "This should be called only once.");
|
||||
_stack_red_zone_size = s;
|
||||
}
|
||||
address stack_red_zone_base() {
|
||||
return (address)(stack_base() - (stack_size() - stack_red_zone_size()));
|
||||
}
|
||||
size_t stack_red_zone_size() { return StackRedPages * os::vm_page_size(); }
|
||||
bool in_stack_reserved_zone(address a) {
|
||||
return (a <= stack_reserved_zone_base()) && (a >= (address)((intptr_t)stack_reserved_zone_base() - stack_reserved_zone_size()));
|
||||
}
|
||||
bool in_stack_yellow_zone(address a) {
|
||||
return (a <= stack_yellow_zone_base()) && (a >= stack_red_zone_base());
|
||||
return (address)(stack_end() + stack_red_zone_size());
|
||||
}
|
||||
bool in_stack_red_zone(address a) {
|
||||
return (a <= stack_red_zone_base()) &&
|
||||
(a >= (address)((intptr_t)stack_base() - stack_size()));
|
||||
return a <= stack_red_zone_base() && a >= stack_end();
|
||||
}
|
||||
|
||||
static size_t stack_yellow_zone_size() {
|
||||
assert(_stack_yellow_zone_size > 0, "Don't call this before the field is initialized.");
|
||||
return _stack_yellow_zone_size;
|
||||
}
|
||||
static void set_stack_yellow_zone_size(size_t s) {
|
||||
assert(is_size_aligned(s, os::vm_page_size()),
|
||||
"We can not protect if the yellow zone size is not page aligned.");
|
||||
assert(_stack_yellow_zone_size == 0, "This should be called only once.");
|
||||
_stack_yellow_zone_size = s;
|
||||
}
|
||||
|
||||
static size_t stack_reserved_zone_size() {
|
||||
// _stack_reserved_zone_size may be 0. This indicates the feature is off.
|
||||
return _stack_reserved_zone_size;
|
||||
}
|
||||
static void set_stack_reserved_zone_size(size_t s) {
|
||||
assert(is_size_aligned(s, os::vm_page_size()),
|
||||
"We can not protect if the reserved zone size is not page aligned.");
|
||||
assert(_stack_reserved_zone_size == 0, "This should be called only once.");
|
||||
_stack_reserved_zone_size = s;
|
||||
}
|
||||
address stack_reserved_zone_base() {
|
||||
return (address)(stack_end() +
|
||||
(stack_red_zone_size() + stack_yellow_zone_size() + stack_reserved_zone_size()));
|
||||
}
|
||||
bool in_stack_reserved_zone(address a) {
|
||||
return (a <= stack_reserved_zone_base()) &&
|
||||
(a >= (address)((intptr_t)stack_reserved_zone_base() - stack_reserved_zone_size()));
|
||||
}
|
||||
|
||||
static size_t stack_yellow_reserved_zone_size() {
|
||||
return _stack_yellow_zone_size + _stack_reserved_zone_size;
|
||||
}
|
||||
bool in_stack_yellow_reserved_zone(address a) {
|
||||
return (a <= stack_reserved_zone_base()) && (a >= stack_red_zone_base());
|
||||
}
|
||||
|
||||
// Size of red + yellow + reserved zones.
|
||||
static size_t stack_guard_zone_size() {
|
||||
return stack_red_zone_size() + stack_yellow_reserved_zone_size();
|
||||
}
|
||||
|
||||
static size_t stack_shadow_zone_size() {
|
||||
assert(_stack_shadow_zone_size > 0, "Don't call this before the field is initialized.");
|
||||
return _stack_shadow_zone_size;
|
||||
}
|
||||
static void set_stack_shadow_zone_size(size_t s) {
|
||||
// The shadow area is not allocated or protected, so
|
||||
// it needs not be page aligned.
|
||||
// But the stack bang currently assumes that it is a
|
||||
// multiple of page size. This guarantees that the bang
|
||||
// loop touches all pages in the shadow zone.
|
||||
// This can be guaranteed differently, as well. E.g., if
|
||||
// the page size is a multiple of 4K, banging in 4K steps
|
||||
// suffices to touch all pages. (Some pages are banged
|
||||
// several times, though.)
|
||||
assert(is_size_aligned(s, os::vm_page_size()),
|
||||
"Stack bang assumes multiple of page size.");
|
||||
assert(_stack_shadow_zone_size == 0, "This should be called only once.");
|
||||
_stack_shadow_zone_size = s;
|
||||
}
|
||||
|
||||
void create_stack_guard_pages();
|
||||
@ -1377,18 +1483,18 @@ class JavaThread: public Thread {
|
||||
|
||||
void enable_stack_reserved_zone();
|
||||
void disable_stack_reserved_zone();
|
||||
void enable_stack_yellow_zone();
|
||||
void disable_stack_yellow_zone();
|
||||
void enable_stack_yellow_reserved_zone();
|
||||
void disable_stack_yellow_reserved_zone();
|
||||
void enable_stack_red_zone();
|
||||
void disable_stack_red_zone();
|
||||
|
||||
inline bool stack_guard_zone_unused();
|
||||
inline bool stack_yellow_zone_disabled();
|
||||
inline bool stack_yellow_reserved_zone_disabled();
|
||||
inline bool stack_reserved_zone_disabled();
|
||||
inline bool stack_guards_enabled();
|
||||
|
||||
address reserved_stack_activation() const { return _reserved_stack_activation; }
|
||||
void set_reserved_stack_activation(address addr) {
|
||||
void set_reserved_stack_activation(address addr) {
|
||||
assert(_reserved_stack_activation == stack_base()
|
||||
|| _reserved_stack_activation == NULL
|
||||
|| addr == stack_base(), "Must not be set twice");
|
||||
@ -1408,11 +1514,9 @@ class JavaThread: public Thread {
|
||||
|
||||
address stack_overflow_limit() { return _stack_overflow_limit; }
|
||||
void set_stack_overflow_limit() {
|
||||
_stack_overflow_limit = _stack_base - _stack_size +
|
||||
((StackShadowPages +
|
||||
StackReservedPages +
|
||||
StackYellowPages +
|
||||
StackRedPages) * os::vm_page_size());
|
||||
_stack_overflow_limit = stack_end() +
|
||||
(JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size());
|
||||
}
|
||||
|
||||
// Misc. accessors/mutators
|
||||
|
@ -126,8 +126,8 @@ inline bool JavaThread::stack_guard_zone_unused() {
|
||||
return _stack_guard_state == stack_guard_unused;
|
||||
}
|
||||
|
||||
inline bool JavaThread::stack_yellow_zone_disabled() {
|
||||
return _stack_guard_state == stack_guard_yellow_disabled;
|
||||
inline bool JavaThread::stack_yellow_reserved_zone_disabled() {
|
||||
return _stack_guard_state == stack_guard_yellow_reserved_disabled;
|
||||
}
|
||||
|
||||
inline bool JavaThread::stack_reserved_zone_disabled() {
|
||||
@ -138,9 +138,9 @@ inline size_t JavaThread::stack_available(address cur_sp) {
|
||||
// This code assumes java stacks grow down
|
||||
address low_addr; // Limit on the address for deepest stack depth
|
||||
if (_stack_guard_state == stack_guard_unused) {
|
||||
low_addr = stack_base() - stack_size();
|
||||
low_addr = stack_end();
|
||||
} else {
|
||||
low_addr = stack_yellow_zone_base();
|
||||
low_addr = stack_reserved_zone_base();
|
||||
}
|
||||
return cur_sp > low_addr ? cur_sp - low_addr : 0;
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ void SharkStack::CreateStackOverflowCheck(Value* sp) {
|
||||
builder()->CreateCondBr(
|
||||
builder()->CreateICmpULT(
|
||||
free_stack,
|
||||
LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),
|
||||
LLVMValue::intptr_constant(JavaThread::stack_shadow_zone_size())),
|
||||
overflow, abi_ok);
|
||||
|
||||
// Handle overflows
|
||||
|
Loading…
Reference in New Issue
Block a user