diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os/aix/os_aix.cpp --- a/src/hotspot/os/aix/os_aix.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os/aix/os_aix.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -776,12 +776,7 @@ // Thread start routine for all newly created threads static void *thread_native_entry(Thread *thread) { - // find out my own stack dimensions - { - // actually, this should do exactly the same as thread->record_stack_base_and_size... - thread->set_stack_base(os::current_stack_base()); - thread->set_stack_size(os::current_stack_size()); - } + thread->record_stack_base_and_size(); const pthread_t pthread_id = ::pthread_self(); const tid_t kernel_thread_id = ::thread_self(); @@ -834,20 +829,15 @@ assert(osthread->get_state() == RUNNABLE, "invalid os thread state"); // Call one more level start routine. - thread->run(); + thread->call_run(); + + // Note: at this point the thread object may already have deleted itself. + // Prevent dereferencing it from here on out. + thread = NULL; log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").", os::current_thread_id(), (uintx) kernel_thread_id); - // If a thread has not deleted itself ("delete this") as part of its - // termination sequence, we have to ensure thread-local-storage is - // cleared before we actually terminate. No threads should ever be - // deleted asynchronously with respect to their termination. - if (Thread::current_or_null_safe() != NULL) { - assert(Thread::current_or_null_safe() == thread, "current thread is wrong"); - thread->clear_thread_current(); - } - return 0; } diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os/bsd/os_bsd.cpp --- a/src/hotspot/os/bsd/os_bsd.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os/bsd/os_bsd.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -644,6 +644,9 @@ // Thread start routine for all newly created threads static void *thread_native_entry(Thread *thread) { + + thread->record_stack_base_and_size(); + // Try to randomize the cache line index of hot stack frames. // This helps when threads of the same stack traces evict each other's // cache lines. The threads can be either from the same JVM instance, or @@ -696,20 +699,15 @@ } // call one more level start routine - thread->run(); + thread->call_run(); + + // Note: at this point the thread object may already have deleted itself. + // Prevent dereferencing it from here on out. + thread = NULL; log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").", os::current_thread_id(), (uintx) pthread_self()); - // If a thread has not deleted itself ("delete this") as part of its - // termination sequence, we have to ensure thread-local-storage is - // cleared before we actually terminate. No threads should ever be - // deleted asynchronously with respect to their termination. - if (Thread::current_or_null_safe() != NULL) { - assert(Thread::current_or_null_safe() == thread, "current thread is wrong"); - thread->clear_thread_current(); - } - return 0; } diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os/linux/os_linux.cpp --- a/src/hotspot/os/linux/os_linux.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os/linux/os_linux.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -649,6 +649,9 @@ // Thread start routine for all newly created threads static void *thread_native_entry(Thread *thread) { + + thread->record_stack_base_and_size(); + // Try to randomize the cache line index of hot stack frames. // This helps when threads of the same stack traces evict each other's // cache lines. The threads can be either from the same JVM instance, or @@ -695,20 +698,15 @@ } // call one more level start routine - thread->run(); + thread->call_run(); + + // Note: at this point the thread object may already have deleted itself. + // Prevent dereferencing it from here on out. + thread = NULL; log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").", os::current_thread_id(), (uintx) pthread_self()); - // If a thread has not deleted itself ("delete this") as part of its - // termination sequence, we have to ensure thread-local-storage is - // cleared before we actually terminate. No threads should ever be - // deleted asynchronously with respect to their termination. - if (Thread::current_or_null_safe() != NULL) { - assert(Thread::current_or_null_safe() == thread, "current thread is wrong"); - thread->clear_thread_current(); - } - return 0; } diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os/solaris/os_solaris.cpp --- a/src/hotspot/os/solaris/os_solaris.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os/solaris/os_solaris.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -199,6 +199,10 @@ return st; } +static void _handle_uncaught_cxx_exception() { + VMError::report_and_die("An uncaught C++ exception"); +} + bool os::is_primordial_thread(void) { int r = thr_main(); guarantee(r == 0 || r == 1, "CR6501650 or CR6493689"); @@ -724,6 +728,11 @@ // Thread start routine for all newly created threads extern "C" void* thread_native_entry(void* thread_addr) { + + Thread* thread = (Thread*)thread_addr; + + thread->record_stack_base_and_size(); + // Try to randomize the cache line index of hot stack frames. // This helps when threads of the same stack traces evict each other's // cache lines. The threads can be either from the same JVM instance, or @@ -734,7 +743,6 @@ alloca(((pid ^ counter++) & 7) * 128); int prio; - Thread* thread = (Thread*)thread_addr; thread->initialize_thread_current(); @@ -775,7 +783,13 @@ // initialize signal mask for this thread os::Solaris::hotspot_sigmask(thread); - thread->run(); + os::Solaris::init_thread_fpu_state(); + std::set_terminate(_handle_uncaught_cxx_exception); + + thread->call_run(); + + // Note: at this point the thread object may already have deleted itself. + // Do not dereference it from here on out. // One less thread is executing // When the VMThread gets here, the main thread may have already exited @@ -786,15 +800,6 @@ log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id()); - // If a thread has not deleted itself ("delete this") as part of its - // termination sequence, we have to ensure thread-local-storage is - // cleared before we actually terminate. No threads should ever be - // deleted asynchronously with respect to their termination. - if (Thread::current_or_null_safe() != NULL) { - assert(Thread::current_or_null_safe() == thread, "current thread is wrong"); - thread->clear_thread_current(); - } - if (UseDetachedThreads) { thr_exit(NULL); ShouldNotReachHere(); @@ -1090,67 +1095,58 @@ return &vm_sigs; } -void _handle_uncaught_cxx_exception() { - VMError::report_and_die("An uncaught C++ exception"); -} - - -// First crack at OS-specific initialization, from inside the new thread. -void os::initialize_thread(Thread* thr) { - if (is_primordial_thread()) { - JavaThread* jt = (JavaThread *)thr; - assert(jt != NULL, "Sanity check"); - size_t stack_size; - address base = jt->stack_base(); - if (Arguments::created_by_java_launcher()) { - // Use 2MB to allow for Solaris 7 64 bit mode. - stack_size = JavaThread::stack_size_at_create() == 0 - ? 2048*K : JavaThread::stack_size_at_create(); - - // There are rare cases when we may have already used more than - // the basic stack size allotment before this method is invoked. - // Attempt to allow for a normally sized java_stack. - size_t current_stack_offset = (size_t)(base - (address)&stack_size); - stack_size += ReservedSpace::page_align_size_down(current_stack_offset); - } else { - // 6269555: If we were not created by a Java launcher, i.e. if we are - // running embedded in a native application, treat the primordial thread - // as much like a native attached thread as possible. This means using - // the current stack size from thr_stksegment(), unless it is too large - // to reliably setup guard pages. A reasonable max size is 8MB. - size_t current_size = current_stack_size(); - // This should never happen, but just in case.... - if (current_size == 0) current_size = 2 * K * K; - stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size; - } - address bottom = align_up(base - stack_size, os::vm_page_size());; - stack_size = (size_t)(base - bottom); - - assert(stack_size > 0, "Stack size calculation problem"); - - if (stack_size > jt->stack_size()) { +// CR 7190089: on Solaris, primordial thread's stack needs adjusting. +// Without the adjustment, stack size is incorrect if stack is set to unlimited (ulimit -s unlimited). +void os::Solaris::correct_stack_boundaries_for_primordial_thread(Thread* thr) { + assert(is_primordial_thread(), "Call only for primordial thread"); + + JavaThread* jt = (JavaThread *)thr; + assert(jt != NULL, "Sanity check"); + size_t stack_size; + address base = jt->stack_base(); + if (Arguments::created_by_java_launcher()) { + // Use 2MB to allow for Solaris 7 64 bit mode. + stack_size = JavaThread::stack_size_at_create() == 0 + ? 2048*K : JavaThread::stack_size_at_create(); + + // There are rare cases when we may have already used more than + // the basic stack size allotment before this method is invoked. + // Attempt to allow for a normally sized java_stack. + size_t current_stack_offset = (size_t)(base - (address)&stack_size); + stack_size += ReservedSpace::page_align_size_down(current_stack_offset); + } else { + // 6269555: If we were not created by a Java launcher, i.e. if we are + // running embedded in a native application, treat the primordial thread + // as much like a native attached thread as possible. This means using + // the current stack size from thr_stksegment(), unless it is too large + // to reliably setup guard pages. A reasonable max size is 8MB. + size_t current_size = os::current_stack_size(); + // This should never happen, but just in case.... + if (current_size == 0) current_size = 2 * K * K; + stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size; + } + address bottom = align_up(base - stack_size, os::vm_page_size());; + stack_size = (size_t)(base - bottom); + + assert(stack_size > 0, "Stack size calculation problem"); + + if (stack_size > jt->stack_size()) { #ifndef PRODUCT - struct rlimit limits; - getrlimit(RLIMIT_STACK, &limits); - size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur); - assert(size >= jt->stack_size(), "Stack size problem in main thread"); + struct rlimit limits; + getrlimit(RLIMIT_STACK, &limits); + size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur); + assert(size >= jt->stack_size(), "Stack size problem in main thread"); #endif - tty->print_cr("Stack size of %d Kb exceeds current limit of %d Kb.\n" - "(Stack sizes are rounded up to a multiple of the system page size.)\n" - "See limit(1) to increase the stack size limit.", - stack_size / K, jt->stack_size() / K); - vm_exit(1); - } - assert(jt->stack_size() >= stack_size, - "Attempt to map more stack than was allocated"); - jt->set_stack_size(stack_size); - } - - // With the T2 libthread (T1 is no longer supported) threads are always bound - // and we use stackbanging in all cases. - - os::Solaris::init_thread_fpu_state(); - std::set_terminate(_handle_uncaught_cxx_exception); + tty->print_cr("Stack size of %d Kb exceeds current limit of %d Kb.\n" + "(Stack sizes are rounded up to a multiple of the system page size.)\n" + "See limit(1) to increase the stack size limit.", + stack_size / K, jt->stack_size() / K); + vm_exit(1); + } + assert(jt->stack_size() >= stack_size, + "Attempt to map more stack than was allocated"); + jt->set_stack_size(stack_size); + } diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os/solaris/os_solaris.hpp --- a/src/hotspot/os/solaris/os_solaris.hpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os/solaris/os_solaris.hpp Fri Oct 19 09:39:29 2018 +0200 @@ -102,8 +102,6 @@ static size_t page_size_for_alignment(size_t alignment); static bool setup_large_pages(caddr_t start, size_t bytes, size_t align); - static void init_thread_fpu_state(void); - static void try_enable_extended_io(); static struct sigaction *(*get_signal_action)(int); @@ -148,6 +146,9 @@ // SR_handler static void SR_handler(Thread* thread, ucontext_t* uc); + + static void init_thread_fpu_state(void); + protected: // Solaris-specific interface goes here static julong available_memory(); @@ -268,6 +269,7 @@ static jint _os_thread_limit; static volatile jint _os_thread_count; + static void correct_stack_boundaries_for_primordial_thread(Thread* thr); // Stack overflow handling diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os/windows/os_windows.cpp --- a/src/hotspot/os/windows/os_windows.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os/windows/os_windows.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -420,6 +420,9 @@ // Thread start routine for all newly created threads static unsigned __stdcall thread_native_entry(Thread* thread) { + + thread->record_stack_base_and_size(); + // Try to randomize the cache line index of hot stack frames. // This helps when threads of the same stack traces evict each other's // cache lines. The threads can be either from the same JVM instance, or @@ -453,12 +456,15 @@ // by VM, so VM can generate error dump when an exception occurred in non- // Java thread (e.g. VM thread). __try { - thread->run(); + thread->call_run(); } __except(topLevelExceptionFilter( (_EXCEPTION_POINTERS*)_exception_info())) { // Nothing to do. } + // Note: at this point the thread object may already have deleted itself. + // Do not dereference it from here on out. + log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id()); // One less thread is executing @@ -468,15 +474,6 @@ Atomic::dec(&os::win32::_os_thread_count); } - // If a thread has not deleted itself ("delete this") as part of its - // termination sequence, we have to ensure thread-local-storage is - // cleared before we actually terminate. No threads should ever be - // deleted asynchronously with respect to their termination. - if (Thread::current_or_null_safe() != NULL) { - assert(Thread::current_or_null_safe() == thread, "current thread is wrong"); - thread->clear_thread_current(); - } - // Thread must not return from exit_process_or_thread(), but if it does, // let it proceed to exit normally return (unsigned)os::win32::exit_process_or_thread(os::win32::EPT_THREAD, res); diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp --- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -85,11 +85,6 @@ return (char*) -1; } -// OS specific thread initialization -// -// Calculate and store the limits of the memory stack. -void os::initialize_thread(Thread *thread) { } - // Frame information (pc, sp, fp) retrieved via ucontext // always looks like a C-frame according to the frame // conventions in frame_ppc.hpp. diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -300,10 +300,6 @@ return (char*) -1; } -void os::initialize_thread(Thread* thr) { -// Nothing to do. -} - address os::Bsd::ucontext_get_pc(const ucontext_t * uc) { return (address)uc->context_pc; } diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp --- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -100,10 +100,6 @@ #endif // SPARC } -void os::initialize_thread(Thread* thr) { - // Nothing to do. -} - address os::Bsd::ucontext_get_pc(const ucontext_t* uc) { ShouldNotCallThis(); return NULL; diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -106,9 +106,6 @@ return (char*) 0xffffffffffff; } -void os::initialize_thread(Thread *thr) { -} - address os::Linux::ucontext_get_pc(const ucontext_t * uc) { #ifdef BUILTIN_SIM return (address)uc->uc_mcontext.gregs[REG_PC]; diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp --- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -91,10 +91,6 @@ return (char*) -1; } -void os::initialize_thread(Thread* thr) { - // Nothing to do -} - #ifdef AARCH64 #define arm_pc pc diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -94,8 +94,6 @@ return (char*) -1; } -void os::initialize_thread(Thread *thread) { } - // Frame information (pc, sp, fp) retrieved via ucontext // always looks like a C-frame according to the frame // conventions in frame_ppc64.hpp. diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -95,9 +95,6 @@ return (char*) -1; } -// OS specific thread initialization. -void os::initialize_thread(Thread* thread) { } - // Frame information (pc, sp, fp) retrieved via ucontext // always looks like a C-frame according to the frame // conventions in frame_s390.hpp. diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp --- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -159,8 +159,6 @@ return (char*) 0; } -void os::initialize_thread(Thread* thr) {} - void os::print_context(outputStream *st, const void *context) { if (context == NULL) return; diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -116,10 +116,6 @@ return (char*) -1; } -void os::initialize_thread(Thread* thr) { -// Nothing to do. -} - address os::Linux::ucontext_get_pc(const ucontext_t * uc) { return (address)uc->uc_mcontext.gregs[REG_PC]; } diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp --- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -96,10 +96,6 @@ #endif // SPARC } -void os::initialize_thread(Thread * thr){ - // Nothing to do. -} - address os::Linux::ucontext_get_pc(const ucontext_t* uc) { ShouldNotCallThis(); return NULL; // silence compile warnings diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -212,10 +212,6 @@ return true; } -void os::initialize_thread(Thread* thr) { -// Nothing to do. -} - // Atomics and Stub Functions typedef int32_t xchg_func_t (int32_t, volatile int32_t*); diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/gc/parallel/gcTaskThread.cpp --- a/src/hotspot/share/gc/parallel/gcTaskThread.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/gc/parallel/gcTaskThread.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -114,8 +114,6 @@ // for tasks to be enqueued for execution. void GCTaskThread::run() { - // Set up the thread for stack overflow support - this->record_stack_base_and_size(); this->initialize_named_thread(); // Bind yourself to your processor. if (processor_id() != GCTaskManager::sentinel_worker()) { diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/gc/shared/concurrentGCThread.cpp --- a/src/hotspot/share/gc/shared/concurrentGCThread.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/gc/shared/concurrentGCThread.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -49,7 +49,6 @@ } void ConcurrentGCThread::initialize_in_thread() { - this->record_stack_base_and_size(); this->initialize_named_thread(); this->set_active_handles(JNIHandleBlock::allocate_block()); // From this time Thread::current() should be working. diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/gc/shared/workgroup.cpp --- a/src/hotspot/share/gc/shared/workgroup.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/gc/shared/workgroup.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -297,7 +297,6 @@ } void AbstractGangWorker::initialize() { - this->record_stack_base_and_size(); this->initialize_named_thread(); assert(_gang != NULL, "No gang to run in"); os::set_priority(this, NearMaxPriority); diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -455,8 +455,6 @@ void JfrThreadSampler::run() { assert(_sampler_thread == NULL, "invariant"); - record_stack_base_and_size(); - _sampler_thread = this; jlong last_java_ms = get_monotonic_ms(); diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/prims/jni.cpp --- a/src/hotspot/share/prims/jni.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/prims/jni.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -4132,6 +4132,7 @@ // be set in order for the Safepoint code to deal with it correctly. thread->set_thread_state(_thread_in_vm); thread->record_stack_base_and_size(); + thread->register_thread_stack_with_NMT(); thread->initialize_thread_current(); if (!os::create_attached_thread(thread)) { diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/runtime/os.hpp --- a/src/hotspot/share/runtime/os.hpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/runtime/os.hpp Fri Oct 19 09:39:29 2018 +0200 @@ -505,7 +505,6 @@ static void pd_start_thread(Thread* thread); static void start_thread(Thread* thread); - static void initialize_thread(Thread* thr); static void free_thread(OSThread* osthread); // thread id on Linux/64bit is 64bit, on Windows and Solaris, it's 32bit diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/runtime/thread.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -338,32 +338,61 @@ } void Thread::record_stack_base_and_size() { + // Note: at this point, Thread object is not yet initialized. Do not rely on + // any members being initialized. Do not rely on Thread::current() being set. + // If possible, refrain from doing anything which may crash or assert since + // quite probably those crash dumps will be useless. set_stack_base(os::current_stack_base()); set_stack_size(os::current_stack_size()); - // CR 7190089: on Solaris, primordial thread's stack is adjusted - // in initialize_thread(). Without the adjustment, stack size is - // incorrect if stack is set to unlimited (ulimit -s unlimited). - // So far, only Solaris has real implementation of initialize_thread(). - // - // set up any platform-specific state. - os::initialize_thread(this); + +#ifdef SOLARIS + if (os::is_primordial_thread()) { + os::Solaris::correct_stack_boundaries_for_primordial_thread(this); + } +#endif // Set stack limits after thread is initialized. if (is_Java_thread()) { ((JavaThread*) this)->set_stack_overflow_limit(); ((JavaThread*) this)->set_reserved_stack_activation(stack_base()); } +} + #if INCLUDE_NMT - // record thread's native stack, stack grows downward +void Thread::register_thread_stack_with_NMT() { MemTracker::record_thread_stack(stack_end(), stack_size()); +} #endif // INCLUDE_NMT + +void Thread::call_run() { + // At this point, Thread object should be fully initialized and + // Thread::current() should be set. + + register_thread_stack_with_NMT(); + log_debug(os, thread)("Thread " UINTX_FORMAT " stack dimensions: " PTR_FORMAT "-" PTR_FORMAT " (" SIZE_FORMAT "k).", os::current_thread_id(), p2i(stack_base() - stack_size()), p2i(stack_base()), stack_size()/1024); + + // Invoke ::run() + this->run(); + // Returned from ::run(). Thread finished. + + // Note: at this point the thread object may already have deleted itself. + // So from here on do not dereference *this*. + + // If a thread has not deleted itself ("delete this") as part of its + // termination sequence, we have to ensure thread-local-storage is + // cleared before we actually terminate. No threads should ever be + // deleted asynchronously with respect to their termination. + if (Thread::current_or_null_safe() != NULL) { + assert(Thread::current_or_null_safe() == this, "current thread is wrong"); + Thread::clear_thread_current(); + } + } - Thread::~Thread() { JFR_ONLY(Jfr::on_thread_destruct(this);) @@ -417,17 +446,12 @@ // clear Thread::current if thread is deleting itself. // Needed to ensure JNI correctly detects non-attached threads. if (this == Thread::current()) { - clear_thread_current(); + Thread::clear_thread_current(); } CHECK_UNHANDLED_OOPS_ONLY(if (CheckUnhandledOops) delete unhandled_oops();) } -// NOTE: dummy function for assertion purpose. -void Thread::run() { - ShouldNotReachHere(); -} - #ifdef ASSERT // A JavaThread is considered "dangling" if it is not the current // thread, has been added the Threads list, the system is not at a @@ -1374,7 +1398,6 @@ void WatcherThread::run() { assert(this == watcher_thread(), "just checking"); - this->record_stack_base_and_size(); this->set_native_thread_name(this->name()); this->set_active_handles(JNIHandleBlock::allocate_block()); while (true) { @@ -1740,9 +1763,6 @@ // used to test validity of stack trace backs this->record_base_of_stack_pointer(); - // Record real stack base and size. - this->record_stack_base_and_size(); - this->create_stack_guard_pages(); this->cache_global_variables(); @@ -3709,6 +3729,7 @@ main_thread->initialize_thread_current(); // must do this before set_active_handles main_thread->record_stack_base_and_size(); + main_thread->register_thread_stack_with_NMT(); main_thread->set_active_handles(JNIHandleBlock::allocate_block()); if (!main_thread->set_as_starting_thread()) { diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/runtime/thread.hpp --- a/src/hotspot/share/runtime/thread.hpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/runtime/thread.hpp Fri Oct 19 09:39:29 2018 +0200 @@ -397,11 +397,15 @@ // Manage Thread::current() void initialize_thread_current(); - void clear_thread_current(); // TLS cleanup needed before threads terminate + static void clear_thread_current(); // TLS cleanup needed before threads terminate + + protected: + // To be implemented by children. + virtual void run() = 0; public: - // thread entry point - virtual void run(); + // invokes ::run(), with common preparations and cleanups. + void call_run(); // Testers virtual bool is_VM_thread() const { return false; } @@ -643,6 +647,7 @@ 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(); + void register_thread_stack_with_NMT() NOT_NMT_RETURN; bool on_local_stack(address adr) const { // QQQ this has knowledge of direction, ought to be a stack method diff -r fbfcdc5bf694 -r 912b79d983d9 src/hotspot/share/runtime/vmThread.cpp --- a/src/hotspot/share/runtime/vmThread.cpp Fri Oct 26 08:23:52 2018 -0400 +++ b/src/hotspot/share/runtime/vmThread.cpp Fri Oct 19 09:39:29 2018 +0200 @@ -243,7 +243,7 @@ assert(this == vm_thread(), "check"); this->initialize_named_thread(); - this->record_stack_base_and_size(); + // Notify_lock wait checks on active_handles() to rewait in // case of spurious wakeup, it should wait on the last // value set prior to the notify