OpenJDK / jdk / jdk
changeset 46484:688e3a206b86
8180599: Possibly miss to iterate monitors on thread exit
Summary: Move thread-local monitors to global lists before thread is removed from global threads list, to ensure all monitors get scanned
Reviewed-by: dholmes, rehn
author | rkennke |
---|---|
date | Fri, 19 May 2017 12:14:38 +0200 |
parents | 94ffd2984ec9 |
children | f10c8f2b4651 |
files | hotspot/src/share/vm/runtime/synchronizer.cpp hotspot/src/share/vm/runtime/thread.cpp |
diffstat | 2 files changed, 13 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp Fri May 19 06:50:58 2017 +0000 +++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Fri May 19 12:14:38 2017 +0200 @@ -1283,14 +1283,14 @@ // a global gOmInUseList under the global list lock so these // will continue to be scanned. // -// We currently call omFlush() from the Thread:: dtor _after the thread +// We currently call omFlush() from Threads::remove() _before the thread // has been excised from the thread list and is no longer a mutator. -// That means that omFlush() can run concurrently with a safepoint and -// the scavenge operator. Calling omFlush() from JavaThread::exit() might -// be a better choice as we could safely reason that that the JVM is -// not at a safepoint at the time of the call, and thus there could -// be not inopportune interleavings between omFlush() and the scavenge -// operator. +// This means that omFlush() can not run concurrently with a safepoint and +// interleave with the scavenge operator. In particular, this ensures that +// the thread's monitors are scanned by a GC safepoint, either via +// Thread::oops_do() (if safepoint happens before omFlush()) or via +// ObjectSynchronizer::oops_do() (if it happens after omFlush() and the thread's +// monitors have been transferred to the global in-use list). void ObjectSynchronizer::omFlush(Thread * Self) { ObjectMonitor * list = Self->omFreeList; // Null-terminated SLL @@ -1338,6 +1338,8 @@ tail->FreeNext = gFreeList; gFreeList = list; gMonitorFreeCount += tally; + assert(Self->omFreeCount == tally, "free-count off"); + Self->omFreeCount = 0; } if (inUseTail != NULL) {
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri May 19 06:50:58 2017 +0000 +++ b/hotspot/src/share/vm/runtime/thread.cpp Fri May 19 12:14:38 2017 +0200 @@ -336,9 +336,6 @@ Thread::~Thread() { - // Reclaim the objectmonitors from the omFreeList of the moribund thread. - ObjectSynchronizer::omFlush(this); - EVENT_THREAD_DESTRUCT(this); // stack_base can be NULL if the thread is never started or exited before @@ -4251,6 +4248,10 @@ } void Threads::remove(JavaThread* p) { + + // Reclaim the objectmonitors from the omInUseList and omFreeList of the moribund thread. + ObjectSynchronizer::omFlush(p); + // Extra scope needed for Thread_lock, so we can check // that we do not remove thread without safepoint code notice { MutexLocker ml(Threads_lock);