From 9e4a795ff5a949b86d68aac961309da7d109eb62 Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Mon, 4 Oct 2010 13:11:10 -0400 Subject: [PATCH 1/2] 6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever Absolute time 0 needs to return immediately. Reviewed-by: phh, dcubed, dholmes --- hotspot/src/os/linux/vm/os_linux.cpp | 4 ++-- hotspot/src/os/solaris/vm/os_solaris.cpp | 4 ++-- hotspot/src/os/windows/vm/os_windows.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index e3e117eb5fb..38eea57f743 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4839,7 +4839,7 @@ void Parker::park(bool isAbsolute, jlong time) { // Next, demultiplex/decode time arguments timespec absTime; - if (time < 0) { // don't wait at all + if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all return; } if (time > 0) { diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 0245d6f609d..0db63b82f10 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -5837,7 +5837,7 @@ void Parker::park(bool isAbsolute, jlong time) { // First, demultiplex/decode time arguments timespec absTime; - if (time < 0) { // don't wait at all + if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all return; } if (time > 0) { diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index f2b7eedcb5e..59b60df03f9 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -3992,7 +3992,7 @@ void Parker::park(bool isAbsolute, jlong time) { if (time < 0) { // don't wait return; } - else if (time == 0) { + else if (time == 0 && !isAbsolute) { time = INFINITE; } else if (isAbsolute) { From 39992cab03e5c391d32977f557fa22f7d6d7d512 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 7 Oct 2010 08:06:06 -0700 Subject: [PATCH 2/2] 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong Min_stack_allowed is a compile time constant and Stack*Pages are settable Reviewed-by: dholmes, kvn --- hotspot/src/cpu/x86/vm/methodHandles_x86.cpp | 2 +- hotspot/src/os/linux/vm/os_linux.cpp | 19 +++++++++++++++---- hotspot/src/os/solaris/vm/os_solaris.cpp | 13 ++++++------- hotspot/src/os/windows/vm/os_windows.cpp | 16 +++++++++++++++- hotspot/src/share/vm/runtime/arguments.cpp | 3 ++- hotspot/src/share/vm/utilities/exceptions.cpp | 14 +++++++++++++- 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp index e8cd888cd71..b6c08684fff 100644 --- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp +++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp @@ -346,7 +346,7 @@ void trace_method_handle_stub(const char* adaptername, if (stack_dump_count > 64) stack_dump_count = 48; for (i = 0; i < stack_dump_count; i += 4) { printf(" dump at SP[%d] "INTPTR_FORMAT": "INTPTR_FORMAT" "INTPTR_FORMAT" "INTPTR_FORMAT" "INTPTR_FORMAT"\n", - i, &entry_sp[i+0], entry_sp[i+0], entry_sp[i+1], entry_sp[i+2], entry_sp[i+3]); + i, (intptr_t)&entry_sp[i+0], entry_sp[i+0], entry_sp[i+1], entry_sp[i+2], entry_sp[i+3]); } print_method_handle(mh); } diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 38eea57f743..e42507f4aa7 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -827,8 +827,10 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { switch (thr_type) { case os::java_thread: - // Java threads use ThreadStackSize which default value can be changed with the flag -Xss - if (JavaThread::stack_size_at_create() > 0) stack_size = JavaThread::stack_size_at_create(); + // Java threads use ThreadStackSize which default value can be + // changed with the flag -Xss + assert (JavaThread::stack_size_at_create() > 0, "this should be set"); + stack_size = JavaThread::stack_size_at_create(); break; case os::compiler_thread: if (CompilerThreadStackSize > 0) { @@ -3922,12 +3924,21 @@ jint os::init_2(void) Linux::signal_sets_init(); Linux::install_signal_handlers(); + // 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 + // class initialization depending on 32 or 64 bit VM. + os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed, + (size_t)(StackYellowPages+StackRedPages+StackShadowPages+ + 2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::page_size()); + size_t threadStackSizeInBytes = ThreadStackSize * K; if (threadStackSizeInBytes != 0 && - threadStackSizeInBytes < Linux::min_stack_allowed) { + threadStackSizeInBytes < os::Linux::min_stack_allowed) { tty->print_cr("\nThe stack size specified is too small, " "Specify at least %dk", - Linux::min_stack_allowed / K); + os::Linux::min_stack_allowed/ K); return JNI_ERR; } diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 0db63b82f10..08a16b76369 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -4878,18 +4878,17 @@ 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 BytesPerWord times page size to account for VM stack during + // Add in 2*BytesPerWord times page size to account for VM stack during // class initialization depending on 32 or 64 bit VM. - guarantee((Solaris::min_stack_allowed >= - (StackYellowPages+StackRedPages+StackShadowPages+BytesPerWord - COMPILER2_PRESENT(+1)) * page_size), - "need to increase Solaris::min_stack_allowed on this platform"); + os::Solaris::min_stack_allowed = MAX2(os::Solaris::min_stack_allowed, + (size_t)(StackYellowPages+StackRedPages+StackShadowPages+ + 2*BytesPerWord COMPILER2_PRESENT(+1)) * page_size); size_t threadStackSizeInBytes = ThreadStackSize * K; if (threadStackSizeInBytes != 0 && - threadStackSizeInBytes < Solaris::min_stack_allowed) { + threadStackSizeInBytes < os::Solaris::min_stack_allowed) { tty->print_cr("\nThe stack size specified is too small, Specify at least %dk", - Solaris::min_stack_allowed/K); + os::Solaris::min_stack_allowed/K); return JNI_ERR; } diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 59b60df03f9..d0837200194 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -3311,7 +3311,6 @@ extern "C" { } } - // this is called _after_ the global arguments have been parsed jint os::init_2(void) { // Allocate a single page and mark it as readable for safepoint polling @@ -3390,6 +3389,21 @@ jint os::init_2(void) { 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 a page for compiler2 recursion in main thread. + // 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(); + if (actual_reserve_size < min_stack_allowed) { + tty->print_cr("\nThe stack size specified is too small, " + "Specify at least %dk", + min_stack_allowed / K); + return JNI_ERR; + } + JavaThread::set_stack_size_at_create(stack_commit_size); // Calculate theoretical max. size of Threads to guard gainst artifical diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index f62565a4192..26d1f20e72d 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1663,7 +1663,8 @@ bool Arguments::check_stack_pages() bool status = true; status = status && verify_min_value(StackYellowPages, 1, "StackYellowPages"); status = status && verify_min_value(StackRedPages, 1, "StackRedPages"); - status = status && verify_min_value(StackShadowPages, 1, "StackShadowPages"); + // greater stack shadow pages can't generate instruction to bang stack + status = status && verify_interval(StackShadowPages, 1, 50, "StackShadowPages"); return status; } diff --git a/hotspot/src/share/vm/utilities/exceptions.cpp b/hotspot/src/share/vm/utilities/exceptions.cpp index ef37af5071b..0c3cdf8ce32 100644 --- a/hotspot/src/share/vm/utilities/exceptions.cpp +++ b/hotspot/src/share/vm/utilities/exceptions.cpp @@ -61,6 +61,18 @@ bool Exceptions::special_exception(Thread* thread, const char* file, int line, H ShouldNotReachHere(); } +#ifdef ASSERT + // Check for trying to throw stack overflow before initialization is complete + // to prevent infinite recursion trying to initialize stack overflow without + // adequate stack space. + // This can happen with stress testing a large value of StackShadowPages + if (h_exception()->klass() == SystemDictionary::StackOverflowError_klass()) { + instanceKlass* ik = instanceKlass::cast(h_exception->klass()); + assert(ik->is_initialized(), + "need to increase min_stack_allowed calculation"); + } +#endif // ASSERT + if (thread->is_VM_thread() || thread->is_Compiler_thread() ) { // We do not care what kind of exception we get for the vm-thread or a thread which @@ -91,7 +103,6 @@ bool Exceptions::special_exception(Thread* thread, const char* file, int line, s thread->set_pending_exception(Universe::vm_exception(), file, line); return true; } - return false; } @@ -193,6 +204,7 @@ void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file klassOop k = SystemDictionary::StackOverflowError_klass(); oop e = instanceKlass::cast(k)->allocate_instance(CHECK); exception = Handle(THREAD, e); // fill_in_stack trace does gc + assert(instanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation"); if (StackTraceInThrowable) { java_lang_Throwable::fill_in_stack_trace(exception); }