8159335: Fix problems with stack overflow handling

Reviewed-by: dlong, coleenp, mdoerr
This commit is contained in:
Goetz Lindenmaier 2016-06-13 09:28:25 +02:00
parent dd9df0a16c
commit 8a945875b6
33 changed files with 182 additions and 235 deletions

View File

@ -630,7 +630,11 @@ void TemplateInterpreterGenerator::generate_counter_overflow(Label& do_continue)
__ b(do_continue);
}
// See if we've got enough room on the stack for locals plus overhead.
// See if we've got enough room on the stack for locals plus overhead
// below JavaThread::stack_overflow_limit(). If not, throw a StackOverflowError
// without going through the signal handler, i.e., reserved and yellow zones
// will not be made usable. The shadow zone must suffice to handle the
// overflow.
// The expression stack grows down incrementally, so the normal guard
// page mechanism will work for that.
//
@ -674,40 +678,25 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(void) {
// compute rsp as if this were going to be the last frame on
// the stack before the red zone
const Address stack_base(rthread, Thread::stack_base_offset());
const Address stack_size(rthread, Thread::stack_size_offset());
// locals + overhead, in bytes
__ mov(r0, overhead_size);
__ add(r0, r0, r3, Assembler::LSL, Interpreter::logStackElementSize); // 2 slots per parameter.
__ ldr(rscratch1, stack_base);
__ ldr(rscratch2, stack_size);
const Address stack_limit(rthread, Thread::stack_overflow_limit_offset());
__ ldr(rscratch1, stack_limit);
#ifdef ASSERT
Label stack_base_okay, stack_size_okay;
// verify that thread stack base is non-zero
__ cbnz(rscratch1, stack_base_okay);
__ stop("stack base is zero");
Label limit_okay;
// Verify that thread stack limit is non-zero.
__ cbnz(rscratch1, limit_okay);
__ stop("stack overflow limit is zero");
__ bind(stack_base_okay);
// verify that thread stack size is non-zero
__ cbnz(rscratch2, stack_size_okay);
__ stop("stack size is zero");
__ bind(stack_size_okay);
#endif
// Add stack base to locals and subtract stack size
__ sub(rscratch1, rscratch1, rscratch2); // Stack limit
// Add stack limit to locals.
__ add(r0, r0, rscratch1);
// 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_bang_size * 2);
// check against the current stack bottom
// Check against the current stack bottom.
__ cmp(sp, r0);
__ br(Assembler::HI, after_frame_check);
@ -1088,9 +1077,9 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
__ ldr(r2, constMethod);
__ load_unsigned_short(r2, size_of_parameters);
// native calls don't need the stack size check since they have no
// Native calls don't need the stack size check since they have no
// expression stack and the arguments are already on the stack and
// we only add a handful of words to the stack
// we only add a handful of words to the stack.
// rmethod: Method*
// r2: size of parameters

View File

@ -40,9 +40,9 @@ define_pd_global(bool, ImplicitNullChecks, true); // Generate code for impli
define_pd_global(bool, TrapBasedNullChecks, true);
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs passed to check cast.
#define DEFAULT_STACK_YELLOW_PAGES (6)
#define DEFAULT_STACK_YELLOW_PAGES (2)
#define DEFAULT_STACK_RED_PAGES (1)
#define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2))
#define DEFAULT_STACK_SHADOW_PAGES (20 DEBUG_ONLY(+2))
#define DEFAULT_STACK_RESERVED_PAGES (1)
#define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -478,33 +478,6 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, Register
profile_typecheck_failed(Rtmp1, Rtmp2);
}
void InterpreterMacroAssembler::generate_stack_overflow_check_with_compare_and_throw(Register Rmem_frame_size, Register Rscratch1) {
Label done;
BLOCK_COMMENT("stack_overflow_check_with_compare_and_throw {");
sub(Rmem_frame_size, R1_SP, Rmem_frame_size);
ld(Rscratch1, thread_(stack_overflow_limit));
cmpld(CCR0/*is_stack_overflow*/, Rmem_frame_size, Rscratch1);
bgt(CCR0/*is_stack_overflow*/, done);
// Load target address of the runtime stub.
assert(StubRoutines::throw_StackOverflowError_entry() != NULL, "generated in wrong order");
load_const_optimized(Rscratch1, (StubRoutines::throw_StackOverflowError_entry()), R0);
mtctr(Rscratch1);
// Restore caller_sp.
#ifdef ASSERT
ld(Rscratch1, 0, R1_SP);
ld(R0, 0, R21_sender_SP);
cmpd(CCR0, R0, Rscratch1);
asm_assert_eq("backlink", 0x547);
#endif // ASSERT
mr(R1_SP, R21_sender_SP);
bctr();
align(32, 12);
bind(done);
BLOCK_COMMENT("} stack_overflow_check_with_compare_and_throw");
}
// Separate these two to allow for delay slot in middle.
// These are used to do a test and full jump to exception-throwing code.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -79,7 +79,6 @@ class InterpreterMacroAssembler: public MacroAssembler {
// Load object from cpool->resolved_references(index).
void load_resolved_reference_at_index(Register result, Register index, Label *is_null = NULL);
void generate_stack_overflow_check_with_compare_and_throw(Register Rmem_frame_size, Register Rscratch1);
void load_receiver(Register Rparam_count, Register Rrecv_dst);
// helpers for expression stack

View File

@ -845,9 +845,40 @@ void TemplateInterpreterGenerator::generate_counter_overflow(Label& continue_ent
__ b(continue_entry);
}
// See if we've got enough room on the stack for locals plus overhead below
// JavaThread::stack_overflow_limit(). If not, throw a StackOverflowError
// without going through the signal handler, i.e., reserved and yellow zones
// will not be made usable. The shadow zone must suffice to handle the
// overflow.
//
// Kills Rmem_frame_size, Rscratch1.
void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rmem_frame_size, Register Rscratch1) {
Label done;
assert_different_registers(Rmem_frame_size, Rscratch1);
__ generate_stack_overflow_check_with_compare_and_throw(Rmem_frame_size, Rscratch1);
BLOCK_COMMENT("stack_overflow_check_with_compare {");
__ sub(Rmem_frame_size, R1_SP, Rmem_frame_size);
__ ld(Rscratch1, thread_(stack_overflow_limit));
__ cmpld(CCR0/*is_stack_overflow*/, Rmem_frame_size, Rscratch1);
__ bgt(CCR0/*is_stack_overflow*/, done);
// The stack overflows. Load target address of the runtime stub and call it.
assert(StubRoutines::throw_StackOverflowError_entry() != NULL, "generated in wrong order");
__ load_const_optimized(Rscratch1, (StubRoutines::throw_StackOverflowError_entry()), R0);
__ mtctr(Rscratch1);
// Restore caller_sp.
#ifdef ASSERT
__ ld(Rscratch1, 0, R1_SP);
__ ld(R0, 0, R21_sender_SP);
__ cmpd(CCR0, R0, Rscratch1);
__ asm_assert_eq("backlink", 0x547);
#endif // ASSERT
__ mr(R1_SP, R21_sender_SP);
__ bctr();
__ align(32, 12);
__ bind(done);
BLOCK_COMMENT("} stack_overflow_check_with_compare");
}
void TemplateInterpreterGenerator::unlock_method(bool check_exceptions) {
@ -1014,10 +1045,10 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
// Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.
if (!native_call) {
// --------------------------------------------------------------------------
// Stack overflow check
Label cont;
// Stack overflow check.
// Native calls don't need the stack size check since they have no
// expression stack and the arguments are already on the stack and
// we only add a handful of words to the stack.
__ add(R11_scratch1, parent_frame_resize, top_frame_size);
generate_stack_overflow_check(R11_scratch1, R12_scratch2);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015 SAP SE. All rights reserved.
* Copyright (c) 2013, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -4093,20 +4093,8 @@ void TemplateTable::monitorenter() {
__ lock_object(Rcurrent_monitor, Robj_to_lock);
// Check if there's enough space on the stack for the monitors after locking.
Label Lskip_stack_check;
// Optimization: If the monitors stack section is less then a std page size (4K) don't run
// the stack check. There should be enough shadow pages to fit that in.
__ ld(Rscratch3, 0, R1_SP);
__ sub(Rscratch3, Rscratch3, R26_monitor);
__ cmpdi(CCR0, Rscratch3, 4*K);
__ blt(CCR0, Lskip_stack_check);
DEBUG_ONLY(__ untested("stack overflow check during monitor enter");)
__ li(Rscratch1, 0);
__ generate_stack_overflow_check_with_compare_and_throw(Rscratch1, Rscratch2);
__ align(32, 12);
__ bind(Lskip_stack_check);
// This emits a single store.
__ generate_stack_overflow_check(0);
// The bcp has already been incremented. Just need to dispatch to next instruction.
__ dispatch_next(vtos);

View File

@ -59,11 +59,11 @@ define_pd_global(intx, InlineSmallCode, 1500);
// Stack slots are 2X larger in LP64 than in the 32 bit VM.
define_pd_global(intx, ThreadStackSize, 1024);
define_pd_global(intx, VMThreadStackSize, 1024);
#define DEFAULT_STACK_SHADOW_PAGES (10 DEBUG_ONLY(+1))
#define DEFAULT_STACK_SHADOW_PAGES (20 DEBUG_ONLY(+2))
#else
define_pd_global(intx, ThreadStackSize, 512);
define_pd_global(intx, VMThreadStackSize, 512);
#define DEFAULT_STACK_SHADOW_PAGES (3 DEBUG_ONLY(+1))
#define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2))
#endif // _LP64
#define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES

View File

@ -578,51 +578,39 @@ void TemplateInterpreterGenerator::lock_method() {
__ lock_object(Lmonitors, O0);
}
// See if we've got enough room on the stack for locals plus overhead below
// JavaThread::stack_overflow_limit(). If not, throw a StackOverflowError
// without going through the signal handler, i.e., reserved and yellow zones
// will not be made usable. The shadow zone must suffice to handle the
// overflow.
void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe_size,
Register Rscratch,
Register Rscratch2) {
Register Rscratch) {
const int page_size = os::vm_page_size();
Label after_frame_check;
assert_different_registers(Rframe_size, Rscratch, Rscratch2);
assert_different_registers(Rframe_size, Rscratch);
__ set(page_size, Rscratch);
__ cmp_and_br_short(Rframe_size, Rscratch, Assembler::lessEqual, Assembler::pt, after_frame_check);
// get the stack base, and in debug, verify it is non-zero
__ ld_ptr( G2_thread, Thread::stack_base_offset(), Rscratch );
// Get the stack overflow limit, and in debug, verify it is non-zero.
__ ld_ptr(G2_thread, JavaThread::stack_overflow_limit_offset(), Rscratch);
#ifdef ASSERT
Label base_not_zero;
__ br_notnull_short(Rscratch, Assembler::pn, base_not_zero);
__ stop("stack base is zero in generate_stack_overflow_check");
__ bind(base_not_zero);
Label limit_ok;
__ br_notnull_short(Rscratch, Assembler::pn, limit_ok);
__ stop("stack overflow limit is zero in generate_stack_overflow_check");
__ bind(limit_ok);
#endif
// get the stack size, and in debug, verify it is non-zero
assert( sizeof(size_t) == sizeof(intptr_t), "wrong load size" );
__ ld_ptr( G2_thread, Thread::stack_size_offset(), Rscratch2 );
#ifdef ASSERT
Label size_not_zero;
__ br_notnull_short(Rscratch2, Assembler::pn, size_not_zero);
__ stop("stack size is zero in generate_stack_overflow_check");
__ bind(size_not_zero);
#endif
// compute the beginning of the protected zone minus the requested frame size
__ sub( Rscratch, Rscratch2, Rscratch );
__ set(MAX2(JavaThread::stack_shadow_zone_size(), JavaThread::stack_guard_zone_size()), Rscratch2 );
__ add( Rscratch, Rscratch2, Rscratch );
// Add in the size of the frame (which is the same as subtracting it from the
// SP, which would take another register
__ add( Rscratch, Rframe_size, Rscratch );
// SP, which would take another register.
__ add(Rscratch, Rframe_size, Rscratch);
// the frame is greater than one page in size, so check against
// the bottom of the stack
// The frame is greater than one page in size, so check against
// the bottom of the stack.
__ cmp_and_brx_short(SP, Rscratch, Assembler::greaterUnsigned, Assembler::pt, after_frame_check);
// the stack will overflow, throw an exception
// The stack will overflow, throw an exception.
// Note that SP is restored to sender's sp (in the delay slot). This
// is necessary if the sender's frame is an extended compiled frame
@ -636,8 +624,8 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
__ jump_to(stub, Rscratch);
__ delayed()->mov(O5_savedSP, SP);
// if you get to here, then there is enough stack space
__ bind( after_frame_check );
// If you get to here, then there is enough stack space.
__ bind(after_frame_check);
}
@ -821,40 +809,44 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
__ add( Gframe_size, extra_space, Gframe_size);
__ round_to( Gframe_size, WordsPerLong );
__ sll( Gframe_size, LogBytesPerWord, Gframe_size );
// Native calls don't need the stack size check since they have no
// expression stack and the arguments are already on the stack and
// we only add a handful of words to the stack.
} else {
//
// Compute number of locals in method apart from incoming parameters
//
const Address size_of_locals (Otmp1, ConstMethod::size_of_locals_offset());
__ ld_ptr( constMethod, Otmp1 );
__ lduh( size_of_locals, Otmp1 );
__ sub( Otmp1, Glocals_size, Glocals_size );
__ round_to( Glocals_size, WordsPerLong );
__ sll( Glocals_size, Interpreter::logStackElementSize, Glocals_size );
const Address size_of_locals(Otmp1, ConstMethod::size_of_locals_offset());
__ ld_ptr(constMethod, Otmp1);
__ lduh(size_of_locals, Otmp1);
__ sub(Otmp1, Glocals_size, Glocals_size);
__ round_to(Glocals_size, WordsPerLong);
__ sll(Glocals_size, Interpreter::logStackElementSize, Glocals_size);
// see if the frame is greater than one page in size. If so,
// then we need to verify there is enough stack space remaining
// See if the frame is greater than one page in size. If so,
// then we need to verify there is enough stack space remaining.
// Frame_size = (max_stack + extra_space) * BytesPerWord;
__ ld_ptr( constMethod, Gframe_size );
__ lduh( Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size );
__ add( Gframe_size, extra_space, Gframe_size );
__ round_to( Gframe_size, WordsPerLong );
__ sll( Gframe_size, Interpreter::logStackElementSize, Gframe_size);
__ ld_ptr(constMethod, Gframe_size);
__ lduh(Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size);
__ add(Gframe_size, extra_space, Gframe_size);
__ round_to(Gframe_size, WordsPerLong);
__ sll(Gframe_size, Interpreter::logStackElementSize, Gframe_size);
// Add in java locals size for stack overflow check only
__ add( Gframe_size, Glocals_size, Gframe_size );
__ add(Gframe_size, Glocals_size, Gframe_size);
const Register Otmp2 = O4;
assert_different_registers(Otmp1, Otmp2, O5_savedSP);
generate_stack_overflow_check(Gframe_size, Otmp1, Otmp2);
generate_stack_overflow_check(Gframe_size, Otmp1);
__ sub( Gframe_size, Glocals_size, Gframe_size);
__ sub(Gframe_size, Glocals_size, Gframe_size);
//
// bump SP to accomodate the extra locals
//
__ sub( SP, Glocals_size, SP );
__ sub(SP, Glocals_size, SP);
}
//

View File

@ -473,7 +473,11 @@ void TemplateInterpreterGenerator::generate_counter_overflow(Label& do_continue)
__ jmp(do_continue, relocInfo::none);
}
// See if we've got enough room on the stack for locals plus overhead.
// See if we've got enough room on the stack for locals plus overhead below
// JavaThread::stack_overflow_limit(). If not, throw a StackOverflowError
// without going through the signal handler, i.e., reserved and yellow zones
// will not be made usable. The shadow zone must suffice to handle the
// overflow.
// The expression stack grows down incrementally, so the normal guard
// page mechanism will work for that.
//
@ -518,40 +522,26 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(void) {
__ get_thread(thread);
#endif
const Address stack_base(thread, Thread::stack_base_offset());
const Address stack_size(thread, Thread::stack_size_offset());
const Address stack_limit(thread, JavaThread::stack_overflow_limit_offset());
// locals + overhead, in bytes
__ mov(rax, rdx);
__ shlptr(rax, Interpreter::logStackElementSize); // 2 slots per parameter.
__ shlptr(rax, Interpreter::logStackElementSize); // Convert parameter count to bytes.
__ addptr(rax, overhead_size);
#ifdef ASSERT
Label stack_base_okay, stack_size_okay;
// verify that thread stack base is non-zero
__ cmpptr(stack_base, (int32_t)NULL_WORD);
__ jcc(Assembler::notEqual, stack_base_okay);
__ stop("stack base is zero");
__ bind(stack_base_okay);
// verify that thread stack size is non-zero
__ cmpptr(stack_size, 0);
__ jcc(Assembler::notEqual, stack_size_okay);
__ stop("stack size is zero");
__ bind(stack_size_okay);
Label limit_okay;
// Verify that thread stack overflow limit is non-zero.
__ cmpptr(stack_limit, (int32_t)NULL_WORD);
__ jcc(Assembler::notEqual, limit_okay);
__ stop("stack overflow limit is zero");
__ bind(limit_okay);
#endif
// Add stack base to locals and subtract stack size
__ addptr(rax, stack_base);
__ subptr(rax, stack_size);
// Add locals/frame size to stack limit.
__ addptr(rax, stack_limit);
// 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_bang_size);
// check against the current stack bottom
// Check against the current stack bottom.
__ cmpptr(rsp, rax);
__ jcc(Assembler::above, after_frame_check_pop);
@ -782,8 +772,6 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
return NULL;
}
// TODO: rather than touching all pages, check against stack_overflow_limit and bang yellow page to
// generate exception. Windows might need this to map the shadow pages though.
void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
// Quick & dirty stack overflow checking: bang the stack & handle trap.
// Note that we do the banging after the frame is setup, since the exception
@ -945,7 +933,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
__ load_unsigned_short(t, Address(t, ConstMethod::size_of_parameters_offset()));
#ifndef _LP64
__ shlptr(t, Interpreter::logStackElementSize);
__ shlptr(t, Interpreter::logStackElementSize); // Convert parameter count to bytes.
__ addptr(t, 2*wordSize); // allocate two more slots for JNIEnv and possible mirror
__ subptr(rsp, t);
__ andptr(rsp, -(StackAlignmentInBytes)); // gcc needs 16 byte aligned stacks to do XMM intrinsics

View File

@ -156,8 +156,6 @@ int os::Aix::_on_pase = -1;
// SS - service pack, if known, 0 otherwise
uint32_t os::Aix::_os_version = 0;
int os::Aix::_stack_page_size = -1;
// -1 = uninitialized, 0 - no, 1 - yes
int os::Aix::_xpg_sus_mode = -1;
@ -1499,7 +1497,6 @@ void os::print_memory_info(outputStream* st) {
g_multipage_support.error);
st->cr();
st->print_cr(" os::vm_page_size: %s", describe_pagesize(os::vm_page_size()));
// not used in OpenJDK st->print_cr(" os::stack_page_size: %s", describe_pagesize(os::stack_page_size()));
// print out LDR_CNTRL because it affects the default page sizes
const char* const ldr_cntrl = ::getenv("LDR_CNTRL");
@ -3451,10 +3448,6 @@ void os::init(void) {
FLAG_SET_ERGO(bool, Use64KPages, true);
}
// Short-wire stack page size to base page size; if that works, we just remove
// that stack page size altogether.
Aix::_stack_page_size = Aix::_page_size;
// For now UseLargePages is just ignored.
FLAG_SET_ERGO(bool, UseLargePages, false);
_page_sizes[0] = 0;
@ -3589,15 +3582,15 @@ jint os::init_2(void) {
// Check minimum allowable stack size for thread creation and to initialize
// the java system classes, including StackOverflowError - depends on page
// size. Add a page for compiler2 recursion in main thread.
// Add in 2*BytesPerWord times page size to account for VM stack during
// size. Add two 4K pages for compiler2 recursion in main thread.
// Add in 4*BytesPerWord 4K pages 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,
JavaThread::stack_guard_zone_size() +
JavaThread::stack_shadow_zone_size() +
(2*BytesPerWord COMPILER2_PRESENT(+1)) * Aix::vm_default_page_size());
(4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
os::Aix::min_stack_allowed = align_size_up(os::Aix::min_stack_allowed, os::Aix::page_size());
os::Aix::min_stack_allowed = align_size_up(os::Aix::min_stack_allowed, os::vm_page_size());
size_t threadStackSizeInBytes = ThreadStackSize * K;
if (threadStackSizeInBytes != 0 &&

View File

@ -49,9 +49,6 @@ class Aix {
static Mutex* _createThread_lock;
static int _page_size;
// Page size of newly created pthreads.
static int _stack_page_size;
// -1 = uninitialized, 0 = AIX, 1 = OS/400 (PASE)
static int _on_pase;
@ -113,15 +110,6 @@ class Aix {
return _page_size;
}
// Accessor methods for stack page size which may be different from usual page size.
static int stack_page_size(void) {
assert(_stack_page_size != -1, "not initialized");
return _stack_page_size;
}
// This is used to scale stack space (guard pages etc.). The name is somehow misleading.
static int vm_default_page_size(void ) { return 8*K; }
static address ucontext_get_pc(const ucontext_t* uc);
static intptr_t* ucontext_get_sp(const ucontext_t* uc);
static intptr_t* ucontext_get_fp(const ucontext_t* uc);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -52,7 +52,7 @@ inline bool os::uses_stack_guard_pages() {
// Whether or not calling code should/can commit/uncommit stack pages
// before guarding them. Answer for AIX is definitly no, because memory
// is automatically committed on touch.
inline bool os::allocate_stack_guard_pages() {
inline bool os::must_commit_stack_guard_pages() {
assert(uses_stack_guard_pages(), "sanity check");
return false;
}
@ -65,7 +65,7 @@ inline void os::pd_split_reserved_memory(char *base, size_t size,
}
// Bang the shadow pages if they need to be touched to be mapped.
inline void os::map_stack_shadow_pages() {
inline void os::map_stack_shadow_pages(address sp) {
}
inline void os::dll_unload(void *lib) {

View File

@ -3491,13 +3491,15 @@ jint os::init_2(void) {
// Check minimum allowable stack size for thread creation and to initialize
// the java system classes, including StackOverflowError - depends on page
// size. Add a page for compiler2 recursion in main thread.
// Add in 2*BytesPerWord times page size to account for VM stack during
// size. Add two 4K pages for compiler2 recursion in main thread.
// Add in 4*BytesPerWord 4K pages 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,
JavaThread::stack_guard_zone_size() +
JavaThread::stack_shadow_zone_size() +
(2*BytesPerWord COMPILER2_PRESENT(+1)) * Bsd::page_size());
(4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
os::Bsd::min_stack_allowed = align_size_up(os::Bsd::min_stack_allowed, os::vm_page_size());
size_t threadStackSizeInBytes = ThreadStackSize * K;
if (threadStackSizeInBytes != 0 &&

View File

@ -47,7 +47,7 @@ inline bool os::uses_stack_guard_pages() {
return true;
}
inline bool os::allocate_stack_guard_pages() {
inline bool os::must_commit_stack_guard_pages() {
assert(uses_stack_guard_pages(), "sanity check");
#if !defined(__FreeBSD__) || __FreeBSD__ < 5
// Since FreeBSD 4 uses malloc() for allocating the thread stack
@ -68,7 +68,7 @@ inline void os::pd_split_reserved_memory(char *base, size_t size,
// Bang the shadow pages if they need to be touched to be mapped.
inline void os::map_stack_shadow_pages() {
inline void os::map_stack_shadow_pages(address sp) {
}
inline void os::dll_unload(void *lib) {

View File

@ -142,7 +142,6 @@ int (*os::Linux::_pthread_setname_np)(pthread_t, const char*) = NULL;
Mutex* os::Linux::_createThread_lock = NULL;
pthread_t os::Linux::_main_thread;
int os::Linux::_page_size = -1;
const int os::Linux::_vm_default_page_size = (8 * K);
bool os::Linux::_supports_fast_thread_cpu_time = false;
uint32_t os::Linux::_os_version = 0;
const char * os::Linux::_glibc_version = NULL;
@ -4784,13 +4783,15 @@ jint os::init_2(void) {
// Check minimum allowable stack size for thread creation and to initialize
// the java system classes, including StackOverflowError - depends on page
// size. Add a page for compiler2 recursion in main thread.
// Add in 2*BytesPerWord times page size to account for VM stack during
// size. Add two 4K pages for compiler2 recursion in main thread.
// Add in 4*BytesPerWord 4K pages 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,
JavaThread::stack_guard_zone_size() +
JavaThread::stack_shadow_zone_size() +
(2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::vm_default_page_size());
(4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
os::Linux::min_stack_allowed = align_size_up(os::Linux::min_stack_allowed, os::vm_page_size());
size_t threadStackSizeInBytes = ThreadStackSize * K;
if (threadStackSizeInBytes != 0 &&

View File

@ -71,7 +71,6 @@ class Linux {
static pthread_t _main_thread;
static Mutex* _createThread_lock;
static int _page_size;
static const int _vm_default_page_size;
static julong available_memory();
static julong physical_memory() { return _physical_memory; }
@ -130,8 +129,6 @@ class Linux {
static int page_size(void) { return _page_size; }
static void set_page_size(int val) { _page_size = val; }
static int vm_default_page_size(void) { return _vm_default_page_size; }
static address ucontext_get_pc(const ucontext_t* uc);
static void ucontext_set_pc(ucontext_t* uc, address pc);
static intptr_t* ucontext_get_sp(const ucontext_t* uc);

View File

@ -47,7 +47,7 @@ inline bool os::uses_stack_guard_pages() {
return true;
}
inline bool os::allocate_stack_guard_pages() {
inline bool os::must_commit_stack_guard_pages() {
assert(uses_stack_guard_pages(), "sanity check");
return true;
}
@ -60,7 +60,7 @@ inline void os::pd_split_reserved_memory(char *base, size_t size,
// Bang the shadow pages if they need to be touched to be mapped.
inline void os::map_stack_shadow_pages() {
inline void os::map_stack_shadow_pages(address sp) {
}
inline void os::dll_unload(void *lib) {

View File

@ -4477,13 +4477,15 @@ jint os::init_2(void) {
// Check minimum allowable stack size for thread creation and to initialize
// the java system classes, including StackOverflowError - depends on page
// size. Add a page for compiler2 recursion in main thread.
// Add in 2*BytesPerWord times page size to account for VM stack during
// size. Add two 4K pages for compiler2 recursion in main thread.
// Add in 4*BytesPerWord 4K pages 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,
JavaThread::stack_guard_zone_size() +
JavaThread::stack_shadow_zone_size() +
(2*BytesPerWord COMPILER2_PRESENT(+1)) * page_size);
(4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
os::Solaris::min_stack_allowed = align_size_up(os::Solaris::min_stack_allowed, os::vm_page_size());
size_t threadStackSizeInBytes = ThreadStackSize * K;
if (threadStackSizeInBytes != 0 &&

View File

@ -46,7 +46,7 @@ inline bool os::uses_stack_guard_pages() {
return true;
}
inline bool os::allocate_stack_guard_pages() {
inline bool os::must_commit_stack_guard_pages() {
assert(uses_stack_guard_pages(), "sanity check");
int r = thr_main() ;
guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
@ -61,8 +61,9 @@ inline void os::pd_split_reserved_memory(char *base, size_t size,
// Bang the shadow pages if they need to be touched to be mapped.
inline void os::map_stack_shadow_pages() {
inline void os::map_stack_shadow_pages(address sp) {
}
inline void os::dll_unload(void *lib) { ::dlclose(lib); }
inline const int os::default_file_open_flags() { return 0;}

View File

@ -4183,13 +4183,16 @@ jint os::init_2(void) {
// Check minimum allowable stack size for thread creation and to initialize
// the java system classes, including StackOverflowError - depends on page
// size. Add a page for compiler2 recursion in main thread.
// Add in 2*BytesPerWord times page size to account for VM stack during
// size. Add two 4K pages for compiler2 recursion in main thread.
// Add in 4*BytesPerWord 4K pages to account for VM stack during
// class initialization depending on 32 or 64 bit VM.
size_t min_stack_allowed =
(size_t)(JavaThread::stack_yellow_zone_size() + JavaThread::stack_red_zone_size() +
(size_t)(JavaThread::stack_guard_zone_size() +
JavaThread::stack_shadow_zone_size() +
(2*BytesPerWord COMPILER2_PRESENT(+1)) * os::vm_page_size());
(4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
min_stack_allowed = align_size_up(min_stack_allowed, 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",

View File

@ -53,7 +53,7 @@ inline bool os::uses_stack_guard_pages() {
return true;
}
inline bool os::allocate_stack_guard_pages() {
inline bool os::must_commit_stack_guard_pages() {
return true;
}
@ -66,14 +66,16 @@ inline int os::readdir_buf_size(const char *path)
}
// Bang the shadow pages if they need to be touched to be mapped.
inline void os::map_stack_shadow_pages() {
inline void os::map_stack_shadow_pages(address sp) {
// Write to each page of our new frame to force OS mapping.
// If we decrement stack pointer more than one page
// 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 (size_t pages = 1; pages <= (JavaThread::stack_shadow_zone_size() / os::vm_page_size()); pages++) {
*((int *)(sp - (pages * vm_page_size()))) = 0;
const int page_size = os::win32::vm_page_size();
const size_t n_pages = JavaThread::stack_shadow_zone_size() / page_size;
for (size_t pages = 1; pages <= n_pages; pages++) {
sp -= page_size;
*sp = 0;
}
}

View File

@ -108,8 +108,7 @@ class TemplateInterpreterGenerator: public AbstractInterpreterGenerator {
void generate_fixed_frame(bool native_call);
#ifdef SPARC
void generate_stack_overflow_check(Register Rframe_size, Register Rscratch,
Register Rscratch2);
void generate_stack_overflow_check(Register Rframe_size, Register Rscratch);
void save_native_result(void);
void restore_native_result(void);
#endif // SPARC

View File

@ -372,14 +372,16 @@ void JavaCalls::call_helper(JavaValue* result, const methodHandle& method, JavaC
}
// Check that there are shadow pages available before changing thread state
// to Java
if (!os::stack_shadow_pages_available(THREAD, method)) {
// to Java. Calculate current_stack_pointer here to make sure
// stack_shadow_pages_available() and bang_stack_shadow_pages() use the same sp.
address sp = os::current_stack_pointer();
if (!os::stack_shadow_pages_available(THREAD, method, sp)) {
// Throw stack overflow exception with preinitialized exception.
Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method);
return;
} else {
// Touch pages checked if the OS needs them to be touched to be mapped.
os::map_stack_shadow_pages();
os::map_stack_shadow_pages(sp);
}
#if INCLUDE_JVMCI

View File

@ -1325,9 +1325,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) {
bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method, address sp) {
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
// the handler for stack overflow. 'instanceof' in the stack overflow

View File

@ -260,9 +260,9 @@ class os: AllStatic {
// exception processing) There are guard pages, and above that shadow
// pages for stack overflow checking.
static bool uses_stack_guard_pages();
static bool allocate_stack_guard_pages();
static void map_stack_shadow_pages();
static bool stack_shadow_pages_available(Thread *thread, const methodHandle& method);
static bool must_commit_stack_guard_pages();
static void map_stack_shadow_pages(address sp);
static bool stack_shadow_pages_available(Thread *thread, const methodHandle& method, address sp);
// OS interface to Virtual Memory

View File

@ -2493,10 +2493,10 @@ void JavaThread::create_stack_guard_pages() {
address low_addr = stack_end();
size_t len = stack_guard_zone_size();
int allocate = os::allocate_stack_guard_pages();
int must_commit = os::must_commit_stack_guard_pages();
// warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) {
if (must_commit && !os::create_stack_guard_pages((char *) low_addr, len)) {
log_warning(os, thread)("Attempt to allocate stack guard pages failed.");
return;
}
@ -2515,7 +2515,6 @@ void JavaThread::create_stack_guard_pages() {
log_debug(os, thread)("Thread " UINTX_FORMAT " stack guard pages activated: "
PTR_FORMAT "-" PTR_FORMAT ".",
os::current_thread_id(), p2i(low_addr), p2i(low_addr + len));
}
void JavaThread::remove_stack_guard_pages() {
@ -2524,7 +2523,7 @@ void JavaThread::remove_stack_guard_pages() {
address low_addr = stack_end();
size_t len = stack_guard_zone_size();
if (os::allocate_stack_guard_pages()) {
if (os::must_commit_stack_guard_pages()) {
if (os::remove_stack_guard_pages((char *) low_addr, len)) {
_stack_guard_state = stack_guard_unused;
} else {
@ -2546,7 +2545,6 @@ void JavaThread::remove_stack_guard_pages() {
log_debug(os, thread)("Thread " UINTX_FORMAT " stack guard pages removed: "
PTR_FORMAT "-" PTR_FORMAT ".",
os::current_thread_id(), p2i(low_addr), p2i(low_addr + len));
}
void JavaThread::enable_stack_reserved_zone() {

View File

@ -25,7 +25,7 @@
* @test
* @bug 8054224
* @summary Recursive method compiled by C1 is unable to catch StackOverflowError
* @run main/othervm -Xcomp -XX:CompileOnly=Test.run -XX:+TieredCompilation -XX:TieredStopAtLevel=2 -Xss392K TestRecursiveReplacedException
* @run main/othervm -Xcomp -XX:CompileOnly=Test.run -XX:+TieredCompilation -XX:TieredStopAtLevel=2 -Xss512K TestRecursiveReplacedException
*
*/

View File

@ -28,7 +28,7 @@
* @summary JVM crashes with "missing exception handler" error
* @author volker.simonis@sap.com
*
* @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss392k StackOverflowBug
* @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss512k StackOverflowBug
*/

View File

@ -33,7 +33,7 @@ import java.lang.reflect.Method;
* @build Test8009761
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss392K Test8009761
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss512K Test8009761
*/
public class Test8009761 {

View File

@ -25,7 +25,7 @@
* @test
* @bug 8029383
* @summary stack overflow if callee is marked for deoptimization causes crash
* @run main/othervm -XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,StackOverflowGuardPagesOff::m1 -XX:CompileCommand=exclude,StackOverflowGuardPagesOff::m2 -Xss392K -XX:-UseOnStackReplacement StackOverflowGuardPagesOff
* @run main/othervm -XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,StackOverflowGuardPagesOff::m1 -XX:CompileCommand=exclude,StackOverflowGuardPagesOff::m2 -Xss512K -XX:-UseOnStackReplacement StackOverflowGuardPagesOff
*
*/

View File

@ -25,7 +25,7 @@
* @test
* @bug 8032410
* @summary Stack overflow at deoptimization doesn't release owned monitors
* @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangMonitorOwned::m1 -XX:CompileCommand=exclude,TestStackBangMonitorOwned::m2 -Xss392K -XX:-UseOnStackReplacement TestStackBangMonitorOwned
* @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangMonitorOwned::m1 -XX:CompileCommand=exclude,TestStackBangMonitorOwned::m2 -Xss512K -XX:-UseOnStackReplacement TestStackBangMonitorOwned
*
*/
public class TestStackBangMonitorOwned {

View File

@ -25,7 +25,7 @@
* @test
* @bug 8028308
* @summary rbp not restored when stack overflow is thrown from deopt/uncommon trap blobs
* @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangRbp::m1 -XX:CompileCommand=exclude,TestStackBangRbp::m2 -Xss392K -XX:-UseOnStackReplacement TestStackBangRbp
* @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangRbp::m1 -XX:CompileCommand=exclude,TestStackBangRbp::m2 -Xss512K -XX:-UseOnStackReplacement TestStackBangRbp
*
*/
public class TestStackBangRbp {

View File

@ -221,7 +221,7 @@ int main (int argc, const char** argv) {
printf("Test started with pid: %ld\n", (long) getpid());
options[0].optionString = "-Xint";
options[1].optionString = "-Xss328k";
options[1].optionString = "-Xss512k";
vm_args.version = JNI_VERSION_1_2;
vm_args.ignoreUnrecognized = JNI_TRUE;