diff --git a/src/os/posix/vm/os_posix.cpp b/src/os/posix/vm/os_posix.cpp index 13f02d493c68f81b7d3e927892087dbc64a81f7b..ac00e85ba11ccd2f093457844e4d84a174559120 100644 --- a/src/os/posix/vm/os_posix.cpp +++ b/src/os/posix/vm/os_posix.cpp @@ -919,59 +919,3 @@ void os::ThreadCrashProtection::check_crash_protection(int sig, } } } - -os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { - assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); -} - -/* - * See the caveats for this class in os_posix.hpp - * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this - * method and returns false. If none of the signals are raised, returns true. - * The callback is supposed to provide the method that should be protected. - */ -bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { - sigset_t saved_sig_mask; - - assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); - assert(!WatcherThread::watcher_thread()->has_crash_protection(), - "crash_protection already set?"); - - // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask - // since on at least some systems (OS X) siglongjmp will restore the mask - // for the process, not the thread - pthread_sigmask(0, NULL, &saved_sig_mask); - if (sigsetjmp(_jmpbuf, 0) == 0) { - // make sure we can see in the signal handler that we have crash protection - // installed - WatcherThread::watcher_thread()->set_crash_protection(this); - cb.call(); - // and clear the crash protection - WatcherThread::watcher_thread()->set_crash_protection(NULL); - return true; - } - // this happens when we siglongjmp() back - pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL); - WatcherThread::watcher_thread()->set_crash_protection(NULL); - return false; -} - -void os::WatcherThreadCrashProtection::restore() { - assert(WatcherThread::watcher_thread()->has_crash_protection(), - "must have crash protection"); - - siglongjmp(_jmpbuf, 1); -} - -void os::WatcherThreadCrashProtection::check_crash_protection(int sig, - Thread* thread) { - - if (thread != NULL && - thread->is_Watcher_thread() && - WatcherThread::watcher_thread()->has_crash_protection()) { - - if (sig == SIGSEGV || sig == SIGBUS) { - WatcherThread::watcher_thread()->crash_protection()->restore(); - } - } -} diff --git a/src/os/posix/vm/os_posix.hpp b/src/os/posix/vm/os_posix.hpp index 9def20a4a5116be78bb0324b8bf6bb563ac33a1a..5cdbb9ae6011653aa57f10d1b97471a7433d8b1e 100644 --- a/src/os/posix/vm/os_posix.hpp +++ b/src/os/posix/vm/os_posix.hpp @@ -88,24 +88,4 @@ private: sigjmp_buf _jmpbuf; }; -/* - * Crash protection for the watcher thread. Wrap the callback - * with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp - * back. - * To be able to use this - don't take locks, don't rely on destructors, - * don't make OS library calls, don't allocate memory, don't print, - * don't call code that could leave the heap / memory in an inconsistent state, - * or anything else where we are not in control if we suddenly jump out. - */ -class WatcherThreadCrashProtection : public StackObj { -public: - WatcherThreadCrashProtection(); - bool call(os::CrashProtectionCallback& cb); - - static void check_crash_protection(int signal, Thread* thread); -private: - void restore(); - sigjmp_buf _jmpbuf; -}; - #endif // OS_POSIX_VM_OS_POSIX_HPP diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp index eebd67562fe5c653858413792b7069c19426badd..74412a3ebb0c489b4ab378fd98c08c7a1b28729f 100644 --- a/src/os/windows/vm/os_windows.cpp +++ b/src/os/windows/vm/os_windows.cpp @@ -4905,34 +4905,6 @@ bool os::ThreadCrashProtection::call(os::CrashProtectionCallback& cb) { return success; } -os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { - assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); -} - -/* - * See the caveats for this class in os_windows.hpp - * Protects the callback call so that raised OS EXCEPTIONS causes a jump back - * into this method and returns false. If no OS EXCEPTION was raised, returns - * true. - * The callback is supposed to provide the method that should be protected. - */ -bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { - assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); - assert(!WatcherThread::watcher_thread()->has_crash_protection(), - "crash_protection already set?"); - - bool success = true; - __try { - WatcherThread::watcher_thread()->set_crash_protection(this); - cb.call(); - } __except(EXCEPTION_EXECUTE_HANDLER) { - // only for protection, nothing to do - success = false; - } - WatcherThread::watcher_thread()->set_crash_protection(NULL); - return success; -} - // An Event wraps a win32 "CreateEvent" kernel handle. // // We have a number of choices regarding "CreateEvent" win32 handle leakage: diff --git a/src/os/windows/vm/os_windows.hpp b/src/os/windows/vm/os_windows.hpp index b9359ad000807d33a48a6b00d2f6495e62bf1bcb..20e2ca2f5c3575c3a70b608b36ea246e2b486c3e 100644 --- a/src/os/windows/vm/os_windows.hpp +++ b/src/os/windows/vm/os_windows.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -125,20 +125,6 @@ private: static volatile intptr_t _crash_mux; }; -/* - * Crash protection for the watcher thread. Wrap the callback - * with a __try { call() } - * To be able to use this - don't take locks, don't rely on destructors, - * don't make OS library calls, don't allocate memory, don't print, - * don't call code that could leave the heap / memory in an inconsistent state, - * or anything else where we are not in control if we suddenly jump out. - */ -class WatcherThreadCrashProtection : public StackObj { -public: - WatcherThreadCrashProtection(); - bool call(os::CrashProtectionCallback& cb); -}; - class PlatformEvent : public CHeapObj { private: double CachePad [4] ; // increase odds that _Event is sole occupant of cache line diff --git a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp index 50051d7c699da8bbc9c5c12534c38e09db66cd0f..018feea1e0309145efdb03b0cc17d24f85a12abd 100644 --- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp @@ -407,7 +407,7 @@ JVM_handle_bsd_signal(int sig, // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); + os::ThreadCrashProtection::check_crash_protection(sig, t); SignalHandlerMark shm(t); diff --git a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp index 2a07de42ef6558eaa9d67f633af34bb1ed3dcff2..16a0686a6cc53a419e14379ac55d1a5eac4fb028 100644 --- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp @@ -544,7 +544,7 @@ JVM_handle_linux_signal(int sig, // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); + os::ThreadCrashProtection::check_crash_protection(sig, t); SignalHandlerMark shm(t); diff --git a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index 1a7375afc7b7486085f7392859a77eb735690aba..c35d8677fb0f29a96a1973b6973894486e37c8fd 100644 --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, 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 @@ -222,7 +222,7 @@ JVM_handle_linux_signal(int sig, // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); + os::ThreadCrashProtection::check_crash_protection(sig, t); SignalHandlerMark shm(t); diff --git a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp index 1785dc374b365bf25f4ccee0aa1272dc89485abf..77fcc52e6859e03d22e2a7b8d417a0b42a03a753 100644 --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp @@ -312,7 +312,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); + os::ThreadCrashProtection::check_crash_protection(sig, t); SignalHandlerMark shm(t); diff --git a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp index 36bf8058a9f56cfd5f8b92351362f5462441c41e..21c4570005b2c770e10bbaa9436ce3a9f9134652 100644 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @@ -369,7 +369,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) - os::WatcherThreadCrashProtection::check_crash_protection(sig, t); + os::ThreadCrashProtection::check_crash_protection(sig, t); SignalHandlerMark shm(t); diff --git a/src/share/vm/runtime/mutex.cpp b/src/share/vm/runtime/mutex.cpp index 5973e4f199feaf20faea7c304c0994d2bb0eb4fa..84207eae0dfa1bf36c664a4e91c429d0be01cbfe 100644 --- a/src/share/vm/runtime/mutex.cpp +++ b/src/share/vm/runtime/mutex.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, 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 @@ -1373,10 +1373,8 @@ void Monitor::check_prelock_state(Thread *thread) { debug_only(if (rank() != Mutex::special) \ thread->check_for_valid_safepoint_state(false);) } - if (thread->is_Watcher_thread()) { - assert(!WatcherThread::watcher_thread()->has_crash_protection(), - "locking not allowed when crash protection is set"); - } + assert(!os::ThreadCrashProtection::is_crash_protected(thread), + "locking not allowed when crash protection is set"); } void Monitor::check_block_state(Thread *thread) { diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp index f4b593be9b2937544e1739f060e47a4a2da00d6c..3a0cf8e11796cfd28552784c9cdce9c96ba4b751 100644 --- a/src/share/vm/runtime/os.cpp +++ b/src/share/vm/runtime/os.cpp @@ -593,21 +593,10 @@ void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) { NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); -#ifdef ASSERT - // checking for the WatcherThread and crash_protection first - // since os::malloc can be called when the libjvm.{dll,so} is - // first loaded and we don't have a thread yet. - // try to find the thread after we see that the watcher thread - // exists and has crash protection. - WatcherThread *wt = WatcherThread::watcher_thread(); - if (wt != NULL && wt->has_crash_protection()) { - Thread* thread = ThreadLocalStorage::get_thread_slow(); - if (thread == wt) { - assert(!wt->has_crash_protection(), - "Can't malloc with crash protection from WatcherThread"); - } - } -#endif + // Since os::malloc can be called when the libjvm.{dll,so} is + // first loaded and we don't have a thread yet we must accept NULL also here. + assert(!os::ThreadCrashProtection::is_crash_protected(ThreadLocalStorage::thread()), + "malloc() not allowed when crash protection is set"); if (size == 0) { // return a valid pointer if size is zero diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index e3a0c85ac01ecdc43aa23054dfde4cf0d574c8b9..6e22da3603f4599f973d55be6726d38b355bf4fb 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -1239,7 +1239,7 @@ WatcherThread* WatcherThread::_watcher_thread = NULL; bool WatcherThread::_startable = false; volatile bool WatcherThread::_should_terminate = false; -WatcherThread::WatcherThread() : Thread(), _crash_protection(NULL) { +WatcherThread::WatcherThread() : Thread() { assert(watcher_thread() == NULL, "we can only allocate one WatcherThread"); if (os::create_thread(this, os::watcher_thread)) { _watcher_thread = this; diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp index 7a548498c9dde2f8cdf3ef8b619fa9458f18f63d..3298aeec8ba7321bf3a3bb39e579f8d870b12fa7 100644 --- a/src/share/vm/runtime/thread.hpp +++ b/src/share/vm/runtime/thread.hpp @@ -734,8 +734,6 @@ class WatcherThread: public Thread { static bool _startable; volatile static bool _should_terminate; // updated without holding lock - - os::WatcherThreadCrashProtection* _crash_protection; public: enum SomeConstants { delay_interval = 10 // interrupt delay in milliseconds @@ -762,15 +760,6 @@ class WatcherThread: public Thread { // Only allow start once the VM is sufficiently initialized // Otherwise the first task to enroll will trigger the start static void make_startable(); - - void set_crash_protection(os::WatcherThreadCrashProtection* crash_protection) { - assert(Thread::current()->is_Watcher_thread(), "Can only be set by WatcherThread"); - _crash_protection = crash_protection; - } - - bool has_crash_protection() const { return _crash_protection != NULL; } - os::WatcherThreadCrashProtection* crash_protection() const { return _crash_protection; } - private: int sleep() const; };