--- old/src/share/vm/runtime/thread.cpp 2015-10-08 22:16:04.839893882 +0200 +++ new/src/share/vm/runtime/thread.cpp 2015-10-08 22:16:04.786895148 +0200 @@ -95,6 +95,7 @@ #include "utilities/macros.hpp" #include "utilities/preserveException.hpp" #if INCLUDE_ALL_GCS +#include "gc/shenandoah/shenandoahConcurrentThread.hpp" #include "gc/cms/concurrentMarkSweepThread.hpp" #include "gc/g1/concurrentMarkThread.inline.hpp" #include "gc/parallel/pcTasks.hpp" @@ -262,6 +263,8 @@ _MutexEvent = ParkEvent::Allocate(this); _MuxEvent = ParkEvent::Allocate(this); + _evacuating = false; + #ifdef CHECK_UNHANDLED_OOPS if (CheckUnhandledOops) { _unhandled_oops = new UnhandledOops(this); @@ -1265,6 +1268,7 @@ } void WatcherThread::run() { + assert(this == watcher_thread(), "just checking"); this->record_stack_base_and_size(); @@ -1471,13 +1475,15 @@ #if INCLUDE_ALL_GCS SATBMarkQueueSet JavaThread::_satb_mark_queue_set; DirtyCardQueueSet JavaThread::_dirty_card_queue_set; +bool JavaThread::_evacuation_in_progress_global = false; #endif // INCLUDE_ALL_GCS JavaThread::JavaThread(bool is_attaching_via_jni) : Thread() #if INCLUDE_ALL_GCS , _satb_mark_queue(&_satb_mark_queue_set), - _dirty_card_queue(&_dirty_card_queue_set) + _dirty_card_queue(&_dirty_card_queue_set), + _evacuation_in_progress(_evacuation_in_progress_global) #endif // INCLUDE_ALL_GCS { initialize(); @@ -1535,7 +1541,8 @@ Thread() #if INCLUDE_ALL_GCS , _satb_mark_queue(&_satb_mark_queue_set), - _dirty_card_queue(&_dirty_card_queue_set) + _dirty_card_queue(&_dirty_card_queue_set), + _evacuation_in_progress(_evacuation_in_progress_global) #endif // INCLUDE_ALL_GCS { initialize(); @@ -1670,7 +1677,7 @@ static void ensure_join(JavaThread* thread) { // We do not need to grap the Threads_lock, since we are operating on ourself. - Handle threadObj(thread, thread->threadObj()); + Handle threadObj(thread, oopDesc::bs()->write_barrier(thread->threadObj())); assert(threadObj.not_null(), "java thread object must exist"); ObjectLocker lock(threadObj, thread); // Ignore pending exception (ThreadDeath), since we are exiting anyway @@ -1864,9 +1871,12 @@ // from the list of active threads. We must do this after any deferred // card marks have been flushed (above) so that any entries that are // added to the thread's dirty card queue as a result are not lost. - if (UseG1GC) { + if (UseG1GC || UseShenandoahGC) { flush_barrier_queues(); } + if (UseShenandoahGC && UseTLAB) { + gclab().make_parsable(true); + } #endif // INCLUDE_ALL_GCS // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread @@ -1901,6 +1911,21 @@ // active field set to true. assert(dirty_queue.is_active(), "dirty card queue should be active"); } + +bool JavaThread::evacuation_in_progress() const { + return _evacuation_in_progress; +} + +void JavaThread::set_evacuation_in_progress(bool in_prog) { + _evacuation_in_progress = in_prog; +} + +void JavaThread::set_evacuation_in_progress_all_threads(bool in_prog) { + _evacuation_in_progress_global = in_prog; + for (JavaThread* t = Threads::first(); t; t = t->next()) { + t->set_evacuation_in_progress(in_prog); + } +} #endif // INCLUDE_ALL_GCS void JavaThread::cleanup_failed_attach_current_thread() { @@ -1930,9 +1955,12 @@ } #if INCLUDE_ALL_GCS - if (UseG1GC) { + if (UseG1GC || UseShenandoahGC) { flush_barrier_queues(); } + if (UseShenandoahGC && UseTLAB) { + gclab().make_parsable(true); + } #endif // INCLUDE_ALL_GCS Threads::remove(this); @@ -2881,6 +2909,7 @@ oop thread_group = java_lang_Thread::threadGroup(thread_obj); if (thread_group != NULL) { typeArrayOop name = java_lang_ThreadGroup::name(thread_group); + name = typeArrayOop(oopDesc::bs()->read_barrier(name)); // ThreadGroup.name can be null if (name != NULL) { const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); @@ -2900,6 +2929,7 @@ oop parent = java_lang_ThreadGroup::parent(thread_group); if (parent != NULL) { typeArrayOop name = java_lang_ThreadGroup::name(parent); + name = typeArrayOop(oopDesc::bs()->read_barrier(name)); // ThreadGroup.name can be null if (name != NULL) { const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); @@ -3512,9 +3542,11 @@ // Support for ConcurrentMarkSweep. This should be cleaned up // and better encapsulated. The ugly nested if test would go away // once things are properly refactored. XXX YSR - if (UseConcMarkSweepGC || UseG1GC) { + if (UseConcMarkSweepGC || UseG1GC || UseShenandoahGC) { if (UseConcMarkSweepGC) { ConcurrentMarkSweepThread::makeSurrogateLockerThread(CHECK_JNI_ERR); + } else if (UseShenandoahGC) { + ShenandoahConcurrentThread::makeSurrogateLockerThread(CHECK_JNI_ERR); } else { ConcurrentMarkThread::makeSurrogateLockerThread(CHECK_JNI_ERR); } @@ -3923,6 +3955,9 @@ thread->exit(true); + // Stop GC threads. + Universe::heap()->shutdown(); + // Stop VM thread. { // 4945125 The vm thread comes to a safepoint during exit.