--- old/src/share/vm/gc_implementation/shared/suspendibleThreadSet.cpp 2015-05-07 18:07:49.869760936 -0400 +++ new/src/share/vm/gc_implementation/shared/suspendibleThreadSet.cpp 2015-05-07 18:07:48.441679245 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -33,16 +33,20 @@ double SuspendibleThreadSet::_suspend_all_start = 0.0; void SuspendibleThreadSet::join() { + assert(!Thread::current()->is_suspendible_thread(), "Thread already joined"); MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag); while (_suspend_all) { ml.wait(Mutex::_no_safepoint_check_flag); } _nthreads++; + DEBUG_ONLY(Thread::current()->set_suspendible_thread();) } void SuspendibleThreadSet::leave() { + assert(Thread::current()->is_suspendible_thread(), "Thread not joined"); MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag); assert(_nthreads > 0, "Invalid"); + DEBUG_ONLY(Thread::current()->clear_suspendible_thread();) _nthreads--; if (_suspend_all) { ml.notify_all(); @@ -50,6 +54,7 @@ } void SuspendibleThreadSet::yield() { + assert(Thread::current()->is_suspendible_thread(), "Must have joined"); if (_suspend_all) { MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag); if (_suspend_all) { --- old/src/share/vm/runtime/thread.cpp 2015-05-07 18:07:53.705980388 -0400 +++ new/src/share/vm/runtime/thread.cpp 2015-05-07 18:07:52.521912652 -0400 @@ -190,6 +190,7 @@ set_stack_size(0); set_self_raw_id(0); set_lgrp_id(-1); + DEBUG_ONLY(clear_suspendible_thread();) // allocated data structures set_osthread(NULL); --- old/src/share/vm/runtime/thread.hpp 2015-05-07 18:07:58.322244465 -0400 +++ new/src/share/vm/runtime/thread.hpp 2015-05-07 18:07:56.454137596 -0400 @@ -206,11 +206,25 @@ private: int _num_nested_signal; + DEBUG_ONLY(bool _suspendible_thread;) + public: void enter_signal_handler() { _num_nested_signal++; } void leave_signal_handler() { _num_nested_signal--; } bool is_inside_signal_handler() const { return _num_nested_signal > 0; } +#ifdef ASSERT + void set_suspendible_thread() { + _suspendible_thread = true; + } + + void clear_suspendible_thread() { + _suspendible_thread = false; + } + + bool is_suspendible_thread() { return _suspendible_thread; } +#endif + private: // Active_handles points to a block of handles JNIHandleBlock* _active_handles;