Skip to content

Commit 8c09d40

Browse files
author
William Kemper
committed
8348268: Test gc/shenandoah/TestResizeTLAB.java#compact: fatal error: Before Updating References: Thread C2 CompilerThread1: expected gc-state 9, actual 21
Reviewed-by: shade
1 parent e7157d1 commit 8c09d40

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,10 @@ void ShenandoahBarrierSet::on_thread_attach(Thread *thread) {
113113
assert(queue.buffer() == nullptr, "SATB queue should not have a buffer");
114114
assert(queue.index() == 0, "SATB queue index should be zero");
115115
queue.set_active(_satb_mark_queue_set.is_active());
116+
117+
ShenandoahThreadLocalData::set_gc_state(thread, _heap->gc_state());
118+
116119
if (thread->is_Java_thread()) {
117-
ShenandoahThreadLocalData::set_gc_state(thread, _heap->gc_state());
118120
ShenandoahThreadLocalData::initialize_gclab(thread);
119121

120122
BarrierSetNMethod* bs_nm = barrier_set_nmethod();

src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,11 +1262,18 @@ void ShenandoahHeap::evacuate_collection_set(bool concurrent) {
12621262
}
12631263

12641264
void ShenandoahHeap::concurrent_prepare_for_update_refs() {
1265-
// It's possible that evacuation succeeded, but we could still be cancelled when we get here.
1266-
// A cancellation at this point means the degenerated cycle must resume from update-refs.
1267-
set_gc_state_concurrent(EVACUATION, false);
1268-
set_gc_state_concurrent(WEAK_ROOTS, false);
1269-
set_gc_state_concurrent(UPDATE_REFS, true);
1265+
{
1266+
// Java threads take this lock while they are being attached and added to the list of thread.
1267+
// If another thread holds this lock before we update the gc state, it will receive a stale
1268+
// gc state, but they will have been added to the list of java threads and so will be corrected
1269+
// by the following handshake.
1270+
MutexLocker lock(Threads_lock);
1271+
1272+
// A cancellation at this point means the degenerated cycle must resume from update-refs.
1273+
set_gc_state_concurrent(EVACUATION, false);
1274+
set_gc_state_concurrent(WEAK_ROOTS, false);
1275+
set_gc_state_concurrent(UPDATE_REFS, true);
1276+
}
12701277

12711278
// This will propagate the gc state and retire gclabs and plabs for threads that require it.
12721279
ShenandoahPrepareForUpdateRefs prepare_for_update_refs(_gc_state.raw_value());
@@ -2025,6 +2032,12 @@ void ShenandoahHeap::set_gc_state_at_safepoint(uint mask, bool value) {
20252032
}
20262033

20272034
void ShenandoahHeap::set_gc_state_concurrent(uint mask, bool value) {
2035+
// Holding the thread lock here assures that any thread created after we change the gc
2036+
// state will have the correct state. It also prevents attaching threads from seeing
2037+
// an inconsistent state. See ShenandoahBarrierSet::on_thread_attach for reference. Established
2038+
// threads will use their thread local copy of the gc state (changed by a handshake, or on a
2039+
// safepoint).
2040+
assert(Threads_lock->is_locked(), "Must hold thread lock for concurrent gc state change");
20282041
_gc_state.set_cond(mask, value);
20292042
}
20302043

0 commit comments

Comments
 (0)