# HG changeset patch # Parent 714dea8cd74c9b2da6d9acbc4d256c3f73a0d664 diff -r 714dea8cd74c -r 6c9b488bd20f src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentThread.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentThread.cpp Wed Jan 04 14:36:38 2017 +0100 +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentThread.cpp Wed Jan 11 13:04:12 2017 +0100 @@ -71,8 +71,7 @@ } else if (heap->shenandoahPolicy()->should_start_concurrent_mark(heap->used(), heap->capacity())) { service_normal_cycle(); if (heap->is_evacuation_in_progress()) { - MutexLocker mu(Threads_lock); - heap->set_evacuation_in_progress(false); + heap->set_evacuation_in_progress_concurrently(false); } } else { Thread::current()->_ParkEvent->park(10); diff -r 714dea8cd74c -r 6c9b488bd20f src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp Wed Jan 04 14:36:38 2017 +0100 +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp Wed Jan 11 13:04:12 2017 +0100 @@ -1900,8 +1900,22 @@ JavaThread::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress); } +void ShenandoahHeap::set_evacuation_in_progress_concurrently(bool in_progress) { + // Note: it is important to first release the _evacuation_in_progress flag here, + // so that Java threads can get out of oom_during_evacuation() and reach a safepoint, + // in case a VM task is pending. + set_evacuation_in_progress(in_progress); + MutexLocker mu(Threads_lock); + JavaThread::set_evacuation_in_progress_all_threads(in_progress); +} + +void ShenandoahHeap::set_evacuation_in_progress_at_safepoint(bool in_progress) { + assert(SafepointSynchronize::is_at_safepoint(), "Only call this at safepoint"); + set_evacuation_in_progress(in_progress); + JavaThread::set_evacuation_in_progress_all_threads(in_progress); +} + void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) { - JavaThread::set_evacuation_in_progress_all_threads(in_progress); _evacuation_in_progress = in_progress ? 1 : 0; OrderAccess::fence(); } diff -r 714dea8cd74c -r 6c9b488bd20f src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp Wed Jan 04 14:36:38 2017 +0100 +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp Wed Jan 11 13:04:12 2017 +0100 @@ -285,8 +285,13 @@ void prepare_for_concurrent_evacuation(); void evacuate_and_update_roots(); + +private: + void set_evacuation_in_progress(bool in_progress); +public: inline bool is_evacuation_in_progress(); - void set_evacuation_in_progress(bool in_progress); + void set_evacuation_in_progress_concurrently(bool in_progress); + void set_evacuation_in_progress_at_safepoint(bool in_progress); void set_full_gc_in_progress(bool in_progress); bool is_full_gc_in_progress() const; diff -r 714dea8cd74c -r 6c9b488bd20f src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.cpp Wed Jan 04 14:36:38 2017 +0100 +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahMarkCompact.cpp Wed Jan 11 13:04:12 2017 +0100 @@ -119,7 +119,7 @@ // b. Cancel evacuation, if in progress if (_heap->is_evacuation_in_progress()) { - _heap->set_evacuation_in_progress(false); + _heap->set_evacuation_in_progress_at_safepoint(false); } assert(!_heap->is_evacuation_in_progress(), "sanity"); diff -r 714dea8cd74c -r 6c9b488bd20f src/share/vm/gc_implementation/shenandoah/vm_operations_shenandoah.cpp --- a/src/share/vm/gc_implementation/shenandoah/vm_operations_shenandoah.cpp Wed Jan 04 14:36:38 2017 +0100 +++ b/src/share/vm/gc_implementation/shenandoah/vm_operations_shenandoah.cpp Wed Jan 11 13:04:12 2017 +0100 @@ -114,7 +114,7 @@ sh->prepare_for_concurrent_evacuation(); sh->shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::prepare_evac); - sh->set_evacuation_in_progress(true); + sh->set_evacuation_in_progress_at_safepoint(true); // From here on, we need to update references. sh->set_need_update_refs(true); @@ -123,9 +123,6 @@ sh->evacuate_and_update_roots(); sh->shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::init_evac); - if (sh->cancelled_concgc()) { - sh->set_evacuation_in_progress(false); - } } else { GCTraceTime time("Cancel concurrent Mark", ShenandoahLogInfo, true, sh->gc_timer(), sh->tracer()->gc_id()); sh->concurrentMark()->cancel();