8285832: runtime/Thread/TooSmallStackSize.java failed "assert(k->is_initialized()) failed: need to increase java_thread_min_stack_allowed calculation"
Reviewed-by: dholmes, fparain, iklam
This commit is contained in:
parent
39e50c2d69
commit
be67acdf5c
@ -2378,7 +2378,7 @@ jint os::init_2(void) {
|
||||
}
|
||||
|
||||
// Check and sets minimum stack sizes against command line options
|
||||
if (Posix::set_minimum_stack_sizes() == JNI_ERR) {
|
||||
if (set_minimum_stack_sizes() == JNI_ERR) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
|
@ -1980,7 +1980,7 @@ jint os::init_2(void) {
|
||||
}
|
||||
|
||||
// Check and sets minimum stack sizes against command line options
|
||||
if (Posix::set_minimum_stack_sizes() == JNI_ERR) {
|
||||
if (set_minimum_stack_sizes() == JNI_ERR) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
|
@ -4483,7 +4483,7 @@ jint os::init_2(void) {
|
||||
}
|
||||
|
||||
// Check and sets minimum stack sizes against command line options
|
||||
if (Posix::set_minimum_stack_sizes() == JNI_ERR) {
|
||||
if (set_minimum_stack_sizes() == JNI_ERR) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,9 @@ static jlong initial_time_count = 0;
|
||||
|
||||
static int clock_tics_per_sec = 100;
|
||||
|
||||
// Platform minimum stack allowed
|
||||
size_t os::_os_min_stack_allowed = PTHREAD_STACK_MIN;
|
||||
|
||||
// Check core dump limit and report possible place where core can be found
|
||||
void os::check_dump_limit(char* buffer, size_t bufferSize) {
|
||||
if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) {
|
||||
@ -925,73 +928,6 @@ bool os::same_files(const char* file1, const char* file2) {
|
||||
return is_same;
|
||||
}
|
||||
|
||||
// Check minimum allowable stack sizes for thread creation and to initialize
|
||||
// the java system classes, including StackOverflowError - depends on page
|
||||
// size.
|
||||
// The space needed for frames during startup is platform dependent. It
|
||||
// depends on word size, platform calling conventions, C frame layout and
|
||||
// interpreter/C1/C2 design decisions. Therefore this is given in a
|
||||
// platform (os/cpu) dependent constant.
|
||||
// To this, space for guard mechanisms is added, which depends on the
|
||||
// page size which again depends on the concrete system the VM is running
|
||||
// on. Space for libc guard pages is not included in this size.
|
||||
jint os::Posix::set_minimum_stack_sizes() {
|
||||
size_t os_min_stack_allowed = PTHREAD_STACK_MIN;
|
||||
|
||||
_java_thread_min_stack_allowed = _java_thread_min_stack_allowed +
|
||||
StackOverflow::stack_guard_zone_size() +
|
||||
StackOverflow::stack_shadow_zone_size();
|
||||
|
||||
_java_thread_min_stack_allowed = align_up(_java_thread_min_stack_allowed, vm_page_size());
|
||||
_java_thread_min_stack_allowed = MAX2(_java_thread_min_stack_allowed, os_min_stack_allowed);
|
||||
|
||||
size_t stack_size_in_bytes = ThreadStackSize * K;
|
||||
if (stack_size_in_bytes != 0 &&
|
||||
stack_size_in_bytes < _java_thread_min_stack_allowed) {
|
||||
// The '-Xss' and '-XX:ThreadStackSize=N' options both set
|
||||
// ThreadStackSize so we go with "Java thread stack size" instead
|
||||
// of "ThreadStackSize" to be more friendly.
|
||||
tty->print_cr("\nThe Java thread stack size specified is too small. "
|
||||
"Specify at least " SIZE_FORMAT "k",
|
||||
_java_thread_min_stack_allowed / K);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
// Make the stack size a multiple of the page size so that
|
||||
// the yellow/red zones can be guarded.
|
||||
JavaThread::set_stack_size_at_create(align_up(stack_size_in_bytes, vm_page_size()));
|
||||
|
||||
// Reminder: a compiler thread is a Java thread.
|
||||
_compiler_thread_min_stack_allowed = _compiler_thread_min_stack_allowed +
|
||||
StackOverflow::stack_guard_zone_size() +
|
||||
StackOverflow::stack_shadow_zone_size();
|
||||
|
||||
_compiler_thread_min_stack_allowed = align_up(_compiler_thread_min_stack_allowed, vm_page_size());
|
||||
_compiler_thread_min_stack_allowed = MAX2(_compiler_thread_min_stack_allowed, os_min_stack_allowed);
|
||||
|
||||
stack_size_in_bytes = CompilerThreadStackSize * K;
|
||||
if (stack_size_in_bytes != 0 &&
|
||||
stack_size_in_bytes < _compiler_thread_min_stack_allowed) {
|
||||
tty->print_cr("\nThe CompilerThreadStackSize specified is too small. "
|
||||
"Specify at least " SIZE_FORMAT "k",
|
||||
_compiler_thread_min_stack_allowed / K);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
_vm_internal_thread_min_stack_allowed = align_up(_vm_internal_thread_min_stack_allowed, vm_page_size());
|
||||
_vm_internal_thread_min_stack_allowed = MAX2(_vm_internal_thread_min_stack_allowed, os_min_stack_allowed);
|
||||
|
||||
stack_size_in_bytes = VMThreadStackSize * K;
|
||||
if (stack_size_in_bytes != 0 &&
|
||||
stack_size_in_bytes < _vm_internal_thread_min_stack_allowed) {
|
||||
tty->print_cr("\nThe VMThreadStackSize specified is too small. "
|
||||
"Specify at least " SIZE_FORMAT "k",
|
||||
_vm_internal_thread_min_stack_allowed / K);
|
||||
return JNI_ERR;
|
||||
}
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
// Called when creating the thread. The minimum stack sizes have already been calculated
|
||||
size_t os::Posix::get_initial_stack_size(ThreadType thr_type, size_t req_stack_size) {
|
||||
size_t stack_size;
|
||||
|
@ -50,24 +50,12 @@ protected:
|
||||
static void print_load_average(outputStream* st);
|
||||
static void print_uptime_info(outputStream* st);
|
||||
|
||||
// Minimum stack size a thread can be created with (allowing
|
||||
// the VM to completely create the thread and enter user code).
|
||||
// The initial values exclude any guard pages (by HotSpot or libc).
|
||||
// set_minimum_stack_sizes() will add the size required for
|
||||
// HotSpot guard pages depending on page size and flag settings.
|
||||
// Libc guard pages are never considered by these values.
|
||||
static size_t _compiler_thread_min_stack_allowed;
|
||||
static size_t _java_thread_min_stack_allowed;
|
||||
static size_t _vm_internal_thread_min_stack_allowed;
|
||||
|
||||
public:
|
||||
static void init(void); // early initialization - no logging available
|
||||
static void init_2(void);// later initialization - logging available
|
||||
|
||||
// Return default stack size for the specified thread type
|
||||
static size_t default_stack_size(os::ThreadType thr_type);
|
||||
// Check and sets minimum stack sizes
|
||||
static jint set_minimum_stack_sizes();
|
||||
static size_t get_initial_stack_size(ThreadType thr_type, size_t req_stack_size);
|
||||
|
||||
// Helper function; describes pthread attributes as short string. String is written
|
||||
|
@ -3875,7 +3875,6 @@ int os::win32::_processor_type = 0;
|
||||
// Processor level is not available on non-NT systems, use vm_version instead
|
||||
int os::win32::_processor_level = 0;
|
||||
julong os::win32::_physical_memory = 0;
|
||||
size_t os::win32::_default_stack_size = 0;
|
||||
|
||||
intx os::win32::_os_thread_limit = 0;
|
||||
volatile intx os::win32::_os_thread_count = 0;
|
||||
@ -3925,11 +3924,6 @@ void os::win32::initialize_system_info() {
|
||||
default: fatal("Unknown platform");
|
||||
}
|
||||
|
||||
_default_stack_size = os::current_stack_size();
|
||||
assert(_default_stack_size > (size_t) _vm_page_size, "invalid stack size");
|
||||
assert((_default_stack_size & (_vm_page_size - 1)) == 0,
|
||||
"stack size not a multiple of page size");
|
||||
|
||||
initialize_performance_counter();
|
||||
}
|
||||
|
||||
@ -4250,6 +4244,21 @@ extern "C" {
|
||||
|
||||
static jint initSock();
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::_compiler_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 40 * K;
|
||||
#ifdef _LP64
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
#else
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
#endif // _LP64
|
||||
|
||||
// If stack_commit_size is 0, windows will reserve the default size,
|
||||
// but only commit a small portion of it. This stack size is the size of this
|
||||
// current thread but is larger than we need for Java threads.
|
||||
// If -Xss is given to the launcher, it will pick 64K as default stack size and pass that.
|
||||
size_t os::_os_min_stack_allowed = 64 * K;
|
||||
|
||||
// this is called _after_ the global arguments have been parsed
|
||||
jint os::init_2(void) {
|
||||
@ -4275,38 +4284,18 @@ jint os::init_2(void) {
|
||||
__asm { fldcw fp_control_word }
|
||||
#endif
|
||||
|
||||
// If stack_commit_size is 0, windows will reserve the default size,
|
||||
// but only commit a small portion of it.
|
||||
size_t stack_commit_size = align_up(ThreadStackSize*K, os::vm_page_size());
|
||||
size_t default_reserve_size = os::win32::default_stack_size();
|
||||
size_t actual_reserve_size = stack_commit_size;
|
||||
if (stack_commit_size < default_reserve_size) {
|
||||
// If stack_commit_size == 0, we want this too
|
||||
actual_reserve_size = default_reserve_size;
|
||||
}
|
||||
|
||||
// Check minimum allowable stack size for thread creation and to initialize
|
||||
// the java system classes, including StackOverflowError - depends on page
|
||||
// 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)(StackOverflow::stack_guard_zone_size() +
|
||||
StackOverflow::stack_shadow_zone_size() +
|
||||
(4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
|
||||
|
||||
min_stack_allowed = align_up(min_stack_allowed, os::vm_page_size());
|
||||
|
||||
if (actual_reserve_size < min_stack_allowed) {
|
||||
tty->print_cr("\nThe Java thread stack size specified is too small. "
|
||||
"Specify at least %dk",
|
||||
min_stack_allowed / K);
|
||||
// Check and sets minimum stack sizes against command line options
|
||||
if (set_minimum_stack_sizes() == JNI_ERR) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
JavaThread::set_stack_size_at_create(stack_commit_size);
|
||||
size_t actual_reserve_size = JavaThread::stack_size_at_create();
|
||||
if (actual_reserve_size == 0) {
|
||||
// -Xss or -XX:ThreadStackSize were not given, use the current stack size.
|
||||
actual_reserve_size = current_stack_size();
|
||||
}
|
||||
|
||||
// Calculate theoretical max. size of Threads to guard gainst artificial
|
||||
// Calculate theoretical max. size of Threads to guard against artificial
|
||||
// out-of-memory situations, where all available address-space has been
|
||||
// reserved by thread stacks.
|
||||
assert(actual_reserve_size != 0, "Must have a stack");
|
||||
|
@ -50,7 +50,6 @@ class win32 {
|
||||
static int _processor_type;
|
||||
static int _processor_level;
|
||||
static julong _physical_memory;
|
||||
static size_t _default_stack_size;
|
||||
static bool _is_windows_server;
|
||||
static bool _has_exit_bug;
|
||||
|
||||
@ -103,9 +102,6 @@ class win32 {
|
||||
// the structure passed in (see winnt.h).
|
||||
static void read_executable_headers(PIMAGE_NT_HEADERS);
|
||||
|
||||
// Default stack size for the current process.
|
||||
static size_t default_stack_size() { return _default_stack_size; }
|
||||
|
||||
static bool get_frame_at_stack_banging_point(JavaThread* thread,
|
||||
struct _EXCEPTION_POINTERS* exceptionInfo,
|
||||
address pc, frame* fr);
|
||||
|
@ -417,9 +417,9 @@ void os::Aix::init_thread_fpu_state(void) {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 192 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 192 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
|
||||
// Return default stack size for thr_type.
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
|
@ -347,9 +347,9 @@ bool os::is_allocatable(size_t bytes) {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 72 * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
|
@ -659,12 +659,12 @@ juint os::cpu_microcode_revision() {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 48 * K;
|
||||
#ifdef _LP64
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
#else
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
#endif // _LP64
|
||||
|
||||
#ifndef AMD64
|
||||
|
@ -161,9 +161,9 @@ void os::Bsd::init_thread_fpu_state(void) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
#ifdef _LP64
|
||||
|
@ -309,9 +309,9 @@ void os::Linux::set_fpu_control_word(int fpu_control) {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 72 * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
|
@ -418,9 +418,9 @@ void os::setup_fpu() {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::_java_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
|
@ -430,9 +430,9 @@ void os::Linux::set_fpu_control_word(int fpu_control) {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
|
||||
// Return default stack size for thr_type.
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
|
@ -308,9 +308,9 @@ void os::Linux::set_fpu_control_word(int fpu_control) {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 72 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 72 * K;
|
||||
|
||||
// return default stack size for thr_type
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
|
@ -376,9 +376,9 @@ void os::Linux::set_fpu_control_word(int fpu_control) {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = (52 DEBUG_ONLY(+ 32)) * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 8)) * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 32 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = (52 DEBUG_ONLY(+ 32)) * K;
|
||||
size_t os::_java_thread_min_stack_allowed = (32 DEBUG_ONLY(+ 8)) * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 32 * K;
|
||||
|
||||
// Return default stack size for thr_type.
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
|
@ -499,12 +499,12 @@ juint os::cpu_microcode_revision() {
|
||||
|
||||
// Minimum usable stack sizes required to get to user code. Space for
|
||||
// HotSpot guard pages is added later.
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 40 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 48 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 40 * K;
|
||||
#ifdef _LP64
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
#else
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
|
||||
#endif // _LP64
|
||||
|
||||
// return default stack size for thr_type
|
||||
|
@ -185,9 +185,9 @@ void os::Linux::set_fpu_control_word(int fpu) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// thread stack
|
||||
|
||||
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_compiler_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_java_thread_min_stack_allowed = 64 * K;
|
||||
size_t os::_vm_internal_thread_min_stack_allowed = 64 * K;
|
||||
|
||||
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
|
||||
#ifdef _LP64
|
||||
|
@ -1993,3 +1993,69 @@ void os::PageSizes::print_on(outputStream* st) const {
|
||||
st->print("empty");
|
||||
}
|
||||
}
|
||||
|
||||
// Check minimum allowable stack sizes for thread creation and to initialize
|
||||
// the java system classes, including StackOverflowError - depends on page
|
||||
// size.
|
||||
// The space needed for frames during startup is platform dependent. It
|
||||
// depends on word size, platform calling conventions, C frame layout and
|
||||
// interpreter/C1/C2 design decisions. Therefore this is given in a
|
||||
// platform (os/cpu) dependent constant.
|
||||
// To this, space for guard mechanisms is added, which depends on the
|
||||
// page size which again depends on the concrete system the VM is running
|
||||
// on. Space for libc guard pages is not included in this size.
|
||||
jint os::set_minimum_stack_sizes() {
|
||||
|
||||
_java_thread_min_stack_allowed = _java_thread_min_stack_allowed +
|
||||
StackOverflow::stack_guard_zone_size() +
|
||||
StackOverflow::stack_shadow_zone_size();
|
||||
|
||||
_java_thread_min_stack_allowed = align_up(_java_thread_min_stack_allowed, vm_page_size());
|
||||
_java_thread_min_stack_allowed = MAX2(_java_thread_min_stack_allowed, _os_min_stack_allowed);
|
||||
|
||||
size_t stack_size_in_bytes = ThreadStackSize * K;
|
||||
if (stack_size_in_bytes != 0 &&
|
||||
stack_size_in_bytes < _java_thread_min_stack_allowed) {
|
||||
// The '-Xss' and '-XX:ThreadStackSize=N' options both set
|
||||
// ThreadStackSize so we go with "Java thread stack size" instead
|
||||
// of "ThreadStackSize" to be more friendly.
|
||||
tty->print_cr("\nThe Java thread stack size specified is too small. "
|
||||
"Specify at least " SIZE_FORMAT "k",
|
||||
_java_thread_min_stack_allowed / K);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
// Make the stack size a multiple of the page size so that
|
||||
// the yellow/red zones can be guarded.
|
||||
JavaThread::set_stack_size_at_create(align_up(stack_size_in_bytes, vm_page_size()));
|
||||
|
||||
// Reminder: a compiler thread is a Java thread.
|
||||
_compiler_thread_min_stack_allowed = _compiler_thread_min_stack_allowed +
|
||||
StackOverflow::stack_guard_zone_size() +
|
||||
StackOverflow::stack_shadow_zone_size();
|
||||
|
||||
_compiler_thread_min_stack_allowed = align_up(_compiler_thread_min_stack_allowed, vm_page_size());
|
||||
_compiler_thread_min_stack_allowed = MAX2(_compiler_thread_min_stack_allowed, _os_min_stack_allowed);
|
||||
|
||||
stack_size_in_bytes = CompilerThreadStackSize * K;
|
||||
if (stack_size_in_bytes != 0 &&
|
||||
stack_size_in_bytes < _compiler_thread_min_stack_allowed) {
|
||||
tty->print_cr("\nThe CompilerThreadStackSize specified is too small. "
|
||||
"Specify at least " SIZE_FORMAT "k",
|
||||
_compiler_thread_min_stack_allowed / K);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
_vm_internal_thread_min_stack_allowed = align_up(_vm_internal_thread_min_stack_allowed, vm_page_size());
|
||||
_vm_internal_thread_min_stack_allowed = MAX2(_vm_internal_thread_min_stack_allowed, _os_min_stack_allowed);
|
||||
|
||||
stack_size_in_bytes = VMThreadStackSize * K;
|
||||
if (stack_size_in_bytes != 0 &&
|
||||
stack_size_in_bytes < _vm_internal_thread_min_stack_allowed) {
|
||||
tty->print_cr("\nThe VMThreadStackSize specified is too small. "
|
||||
"Specify at least " SIZE_FORMAT "k",
|
||||
_vm_internal_thread_min_stack_allowed / K);
|
||||
return JNI_ERR;
|
||||
}
|
||||
return JNI_OK;
|
||||
}
|
||||
|
@ -287,6 +287,22 @@ class os: AllStatic {
|
||||
static void map_stack_shadow_pages(address sp);
|
||||
static bool stack_shadow_pages_available(Thread *thread, const methodHandle& method, address sp);
|
||||
|
||||
private:
|
||||
// Minimum stack size a thread can be created with (allowing
|
||||
// the VM to completely create the thread and enter user code).
|
||||
// The initial values exclude any guard pages (by HotSpot or libc).
|
||||
// set_minimum_stack_sizes() will add the size required for
|
||||
// HotSpot guard pages depending on page size and flag settings.
|
||||
// Libc guard pages are never considered by these values.
|
||||
static size_t _compiler_thread_min_stack_allowed;
|
||||
static size_t _java_thread_min_stack_allowed;
|
||||
static size_t _vm_internal_thread_min_stack_allowed;
|
||||
static size_t _os_min_stack_allowed;
|
||||
|
||||
// Check and sets minimum stack sizes
|
||||
static jint set_minimum_stack_sizes();
|
||||
|
||||
public:
|
||||
// Find committed memory region within specified range (start, start + size),
|
||||
// return true if found any
|
||||
static bool committed_in_range(address start, size_t size, address& committed_start, size_t& committed_size);
|
||||
|
@ -57,6 +57,8 @@ public class TooSmallStackSize {
|
||||
static final String ThreadStackSizeString = "Java thread stack size";
|
||||
static final String VMThreadStackSizeString = "VMThreadStackSize";
|
||||
|
||||
static String testShadowSize = null;
|
||||
|
||||
/*
|
||||
* Returns the minimum stack size this platform will allowed based on the
|
||||
* contents of the error message the JVM outputs when too small of a
|
||||
@ -90,6 +92,25 @@ public class TooSmallStackSize {
|
||||
throw new RuntimeException("test fails");
|
||||
}
|
||||
|
||||
static ProcessBuilder createProcessWithOptions(String stackOption, String stackSize) throws Exception {
|
||||
if (testShadowSize == null) {
|
||||
return ProcessTools.createJavaProcessBuilder(
|
||||
stackOption + stackSize,
|
||||
// Uncomment the following to get log output
|
||||
// that shows actual thread creation sizes.
|
||||
// "-Xlog:os+thread",
|
||||
"-version");
|
||||
} else {
|
||||
return ProcessTools.createJavaProcessBuilder(
|
||||
stackOption + stackSize,
|
||||
// Uncomment the following to get log output
|
||||
// that shows actual thread creation sizes.
|
||||
// "-Xlog:os+thread",
|
||||
"-XX:StackShadowPages=" + testShadowSize,
|
||||
"-version");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the JVM with the specified stack size.
|
||||
*
|
||||
@ -101,13 +122,7 @@ public class TooSmallStackSize {
|
||||
|
||||
System.out.println("*** Testing " + stackOption + stackSize);
|
||||
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
stackOption + stackSize,
|
||||
// Uncomment the following to get log output
|
||||
// that shows actual thread creation sizes.
|
||||
// "-Xlog:os+thread",
|
||||
"-version");
|
||||
|
||||
ProcessBuilder pb = createProcessWithOptions(stackOption, stackSize);
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
|
||||
if (verbose) {
|
||||
@ -144,20 +159,14 @@ public class TooSmallStackSize {
|
||||
static void checkMinStackAllowed(String stackOption, String optionMesg, String stackSize) throws Exception {
|
||||
System.out.println("*** Testing " + stackOption + stackSize);
|
||||
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
stackOption + stackSize,
|
||||
// Uncomment the following to get log output
|
||||
// that shows actual thread creation sizes.
|
||||
// "-Xlog:os+thread",
|
||||
"-version");
|
||||
|
||||
ProcessBuilder pb = createProcessWithOptions(stackOption, stackSize);
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldHaveExitValue(0);
|
||||
|
||||
System.out.println("PASSED: VM launched with " + stackOption + stackSize);
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
public static void test(String... args) throws Exception {
|
||||
/*
|
||||
* The result of a 16k stack size should be a quick exit with a complaint
|
||||
* that the stack size is too small. However, for some win32 builds, the
|
||||
@ -209,4 +218,13 @@ public class TooSmallStackSize {
|
||||
checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "513");
|
||||
checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "0");
|
||||
}
|
||||
|
||||
// aarch64 StackShadowPage size range is 25-55
|
||||
static String shadowSizes[] = { null, "30" };
|
||||
public static void main(java.lang.String[] unused) throws Exception {
|
||||
for (String sz : shadowSizes) {
|
||||
testShadowSize = sz;
|
||||
test();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user