Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8328235: GenShen: Robustify ShenandoahGCSession and fix missing use #407

Closed
wants to merge 52 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
6663406
Robustify ShenandoahGCSession, and fix a missing use for
ysramakrishna Mar 15, 2024
f000340
Read active_generetion() only once in is_is_active_generation() to work
ysramakrishna Mar 20, 2024
bbcaf15
Clean up assertion checking for race.
ysramakrishna Mar 20, 2024
b3ea1aa
Weaken assertion so it passes for now; add comment.
ysramakrishna Mar 20, 2024
47a953f
jcheck cleanup.
ysramakrishna Mar 20, 2024
693fc44
Merge branch 'master' into active_generation
ysramakrishna Mar 20, 2024
a86d3ed
Refine assertion further & modify comment block.
ysramakrishna Mar 20, 2024
03dc8c6
More debugging; much of this code will likely be removed once debugging
ysramakrishna Mar 25, 2024
ef65a4a
Merge branch 'master' into active_generation
ysramakrishna Mar 26, 2024
d37ca96
More assertion checks for gc state vis-a-vis active generation.
ysramakrishna Mar 26, 2024
224de67
Separate scope from active_generation via STW snapshots.
ysramakrishna Mar 28, 2024
3e8c00d
Refine some assertions, add a "force" parameter to override the
ysramakrishna Mar 30, 2024
1729257
Some more special cases that violate the safepoint active_generation
ysramakrishna Mar 30, 2024
56b83a7
Fix typo in assert; simplify implementation a tad.
ysramakrishna Mar 30, 2024
cf02b64
Remove a too strong assertion
ysramakrishna Mar 31, 2024
d61c2f2
More debugging asserts.
ysramakrishna Apr 3, 2024
05eb063
Merge branch 'master' into active_generation
ysramakrishna Apr 3, 2024
d6864bb
Merge branch 'master' into active_generation
ysramakrishna Apr 4, 2024
eb35b2c
Merge branch 'master' into active_generation
ysramakrishna Apr 29, 2024
8af7323
Fix mismerge.
ysramakrishna May 1, 2024
521d536
Strengthen an assert in `is_in_generation()` and remove forcing of
ysramakrishna May 4, 2024
599336f
Relax an over-enthusiastic assert (under new regime).
ysramakrishna May 7, 2024
d5784db
Remove an incorrect gc status setting.
ysramakrishna May 7, 2024
36b0862
Disallow forcing.
ysramakrishna May 8, 2024
99daf9f
Relax an assert that is too strong; still iterating execution paths,
ysramakrishna May 9, 2024
474e8b7
Banish forcing entirely. Fix one case where full gc sets
ysramakrishna May 10, 2024
828f442
jcheck whitespace
ysramakrishna May 10, 2024
658e26e
Clean ups.
ysramakrishna May 10, 2024
4b031ad
Greater separation of gc_generation and active_generation fields of
ysramakrishna May 15, 2024
5e8cab3
Merge branch 'master' into active_generation
ysramakrishna May 16, 2024
6cf64da
Fixed mismerge because of code moving between files in merge from
ysramakrishna May 17, 2024
61848c8
jcheck whitespace
ysramakrishna May 17, 2024
b609d78
Small clean-ups.
ysramakrishna May 21, 2024
70014a9
shenandoah_assert_generations_reconciled() macro instead of a method in
ysramakrishna May 28, 2024
982dcd2
Macro-ize previously inlined shenandoah assert.
ysramakrishna May 28, 2024
9f1e1d6
Remove static _thread field introduced in ShenandoahController, as its
ysramakrishna May 28, 2024
7ee2fe4
jcheck white-space
ysramakrishna May 28, 2024
0541a99
cosmetic
ysramakrishna May 28, 2024
56e35ac
Remove vestigial thread() method in ShenandoahController.
ysramakrishna May 28, 2024
f1f4098
Merge branch 'master' into active_generation
ysramakrishna May 28, 2024
fead6fd
Some asserts to catch a tricky race. These assertions may be too strong
ysramakrishna May 30, 2024
6293498
Merge branch 'master' into active_generation
ysramakrishna May 31, 2024
b2ff5e4
Code called from LRB cannot rely on SGH::_gc_generation and must instead
ysramakrishna Jun 3, 2024
4e6a61e
Merge branch 'master' into active_generation
ysramakrishna Jun 5, 2024
561c2f1
Merge branch 'master' into active_generation
ysramakrishna Jun 10, 2024
b513aba
Merge branch 'master' into active_generation
ysramakrishna Jun 12, 2024
556e5cd
Revert debugging detritus.
ysramakrishna Jun 20, 2024
73ea469
Merge branch 'master' into active_generation
ysramakrishna Jun 20, 2024
b12e17c
Merge branch 'master' into active_generation
ysramakrishna Jun 27, 2024
cbb6000
Merge branch 'master' into active_generation
ysramakrishna Jun 29, 2024
af57394
Fix for the few remaining review comments.
ysramakrishna Jun 29, 2024
c79fea1
Disallow mutator threads from reading the asynchronously updated
ysramakrishna Jun 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp
Original file line number Diff line number Diff line change
@@ -173,6 +173,17 @@ class ShenandoahAsserts {

#define shenandoah_assert_generational() \
assert(ShenandoahHeap::heap()->mode()->is_generational(), "Must be in generational mode here.")

// Some limited sanity checking of the _gc_generation and _active_generation fields of ShenandoahHeap
#define shenandoah_assert_generations_reconciled() \
if (SafepointSynchronize::is_at_safepoint()) { \
ShenandoahHeap* heap = ShenandoahHeap::heap(); \
ShenandoahGeneration* ggen = heap->gc_generation(); \
ShenandoahGeneration* agen = heap->active_generation(); \
assert(agen == ggen, "active_gen(%d) should be reconciled with gc_gen(%d)at safepoint", \
agen->type(), ggen->type()); \
}

#else
#define shenandoah_assert_in_heap(interior_loc, obj)
#define shenandoah_assert_in_heap_or_null(interior_loc, obj)
@@ -226,6 +237,7 @@ class ShenandoahAsserts {
#define shenandoah_assert_heaplocked_or_fullgc_safepoint()
#define shenandoah_assert_control_or_vm_thread()
#define shenandoah_assert_generational()
#define shenandoah_assert_generations_reconciled() \

#endif

2 changes: 1 addition & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp
Original file line number Diff line number Diff line change
@@ -928,7 +928,7 @@ void ShenandoahEvacUpdateCleanupOopStorageRootsClosure::do_oop(oop* p) {
const oop obj = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(obj)) {
if (!_mark_context->is_marked(obj)) {
_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
if (_heap->is_in_active_generation(obj)) {
// TODO: This worries me. Here we are asserting that an unmarked from-space object is 'correct'.
// Normally, I would call this a bogus assert, but there seems to be a legitimate use-case for
4 changes: 2 additions & 2 deletions src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ class ShenandoahConcurrentMarkingTask : public WorkerTask {
// Do not use active_generation() : we must use the gc_generation() set by
// ShenandoahGCScope on the ControllerThread's stack; no safepoint may
// intervene to update active_generation, so we can't
// assert_generations_reconciled() here.
// shenandoah_assert_generations_reconciled() here.
ShenandoahReferenceProcessor* rp = heap->gc_generation()->ref_processor();
assert(rp != nullptr, "need reference processor");
StringDedup::Requests requests;
@@ -116,7 +116,7 @@ class ShenandoahFinalMarkingTask : public WorkerTask {
ShenandoahParallelWorkerSession worker_session(worker_id);
StringDedup::Requests requests;
ShenandoahReferenceProcessor* rp = heap->gc_generation()->ref_processor();
heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();

// First drain remaining SATB buffers.
{
Original file line number Diff line number Diff line change
@@ -132,7 +132,7 @@ void ShenandoahGenerationalEvacuationTask::promote_in_place(ShenandoahHeapRegion
{
const size_t old_garbage_threshold = (ShenandoahHeapRegion::region_size_bytes() * ShenandoahOldGarbageThreshold) / 100;
assert(_heap->gc_generation()->is_mark_complete(), "sanity");
_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
assert(!_heap->is_concurrent_old_mark_in_progress(), "Cannot promote in place during old marking");
assert(region->garbage_before_padded_for_promote() < old_garbage_threshold, "Region " SIZE_FORMAT " has too much garbage for promotion", region->index());
assert(region->is_young(), "Only young regions can be promoted");
@@ -216,7 +216,7 @@ void ShenandoahGenerationalEvacuationTask::promote_humongous(ShenandoahHeapRegio
ShenandoahMarkingContext* marking_context = _heap->marking_context();
oop obj = cast_to_oop(region->bottom());
assert(_heap->gc_generation()->is_mark_complete(), "sanity");
_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
assert(region->is_young(), "Only young regions can be promoted");
assert(region->is_humongous_start(), "Should not promote humongous continuation in isolation");
assert(region->age() >= _heap->age_census()->tenuring_threshold(), "Only promote regions that are sufficiently aged");
Original file line number Diff line number Diff line change
@@ -760,7 +760,7 @@ class ShenandoahGenerationalUpdateHeapRefsTask : public WorkerTask {
ShenandoahHeapRegion* r = _regions->next();
// We update references for global, old, and young collections.
ShenandoahGeneration* const gc_generation = _heap->gc_generation();
_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
assert(gc_generation->is_mark_complete(), "Expected complete marking");
ShenandoahMarkingContext* const ctx = _heap->marking_context();
bool is_mixed = _heap->collection_set()->has_old_regions();
17 changes: 3 additions & 14 deletions src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
Original file line number Diff line number Diff line change
@@ -1587,17 +1587,6 @@ void ShenandoahHeap::set_active_generation() {
_active_generation = _gc_generation;
}

#ifndef PRODUCT
void ShenandoahHeap::assert_generations_reconciled() {
if (SafepointSynchronize::is_at_safepoint()) {
ShenandoahGeneration* ggen = gc_generation();
ShenandoahGeneration* agen = active_generation();
assert(agen == ggen, "active_gen(%d) should be reconciled with gc_gen(%d)at safepoint",
agen->type(), ggen->type());
}
}
#endif

void ShenandoahHeap::on_cycle_start(GCCause::Cause cause, ShenandoahGeneration* generation) {
shenandoah_policy()->record_collection_cause(cause);

@@ -1974,7 +1963,7 @@ void ShenandoahHeap::stw_weak_refs(bool full_gc) {
: ShenandoahPhaseTimings::degen_gc_weakrefs;
ShenandoahTimingsTracker t(phase);
ShenandoahGCWorkerPhase worker_phase(phase);
assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
gc_generation()->ref_processor()->process_references(phase, workers(), false /* concurrent */);
}

@@ -2009,7 +1998,7 @@ void ShenandoahHeap::set_gc_state(uint mask, bool value) {
_gc_state_changed = true;
// Check that if concurrent weak root is set then active_gen isn't null
assert(!is_concurrent_weak_root_in_progress() || active_generation() != nullptr, "Error");
assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
}

void ShenandoahHeap::set_concurrent_young_mark_in_progress(bool in_progress) {
@@ -2303,7 +2292,7 @@ void ShenandoahHeap::sync_pinned_region_status() {
void ShenandoahHeap::assert_pinned_region_status() {
for (size_t i = 0; i < num_regions(); i++) {
ShenandoahHeapRegion* r = get_region(i);
assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
if (gc_generation()->contains(r)) {
assert((r->is_pinned() && r->pin_count() > 0) || (!r->is_pinned() && r->pin_count() == 0),
"Region " SIZE_FORMAT " pinning status is inconsistent", i);
4 changes: 0 additions & 4 deletions src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
Original file line number Diff line number Diff line change
@@ -187,10 +187,6 @@ class ShenandoahHeap : public CollectedHeap {
// a safepoint by the VMThread.
void set_active_generation();

// Some limited sanity checking of the _gc_generation and
// _active_generation fields
void assert_generations_reconciled() PRODUCT_RETURN;

ShenandoahHeuristics* heuristics();

// ---------- Initialization, termination, identification, printing routines
4 changes: 2 additions & 2 deletions src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp
Original file line number Diff line number Diff line change
@@ -319,7 +319,7 @@ void ShenandoahHeapRegion::make_trash_immediate() {
// On this path, we know there are no marked objects in the region,
// tell marking context about it to bypass bitmap resets.
assert(ShenandoahHeap::heap()->gc_generation()->is_mark_complete(), "Marking should be complete here.");
ShenandoahHeap::heap()->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
ShenandoahHeap::heap()->marking_context()->reset_top_bitmap(this);
}

@@ -470,7 +470,7 @@ bool ShenandoahHeapRegion::oop_coalesce_and_fill(bool cancellable) {

// Expect marking to be completed before these threads invoke this service.
assert(heap->gc_generation()->is_mark_complete(), "sanity");
heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();

// All objects above TAMS are considered live even though their mark bits will not be set. Note that young-
// gen evacuations that interrupt a long-running old-gen concurrent mark may promote objects into old-gen
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahMark.cpp
Original file line number Diff line number Diff line change
@@ -152,7 +152,7 @@ void ShenandoahMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint w
// Do not use active_generation() : we must use the gc_generation() set by
// ShenandoahGCScope on the ControllerThread's stack; no safepoint may
// intervene to update active_generation, so we can't
// assert_generations_reconciled() here.
// shenandoah_assert_generations_reconciled() here.
assert(heap->gc_generation()->type() == GENERATION, "Sanity: %d != %d", heap->gc_generation()->type(), GENERATION);
heap->gc_generation()->ref_processor()->set_mark_closure(worker_id, cl);

4 changes: 2 additions & 2 deletions src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp
Original file line number Diff line number Diff line change
@@ -105,7 +105,7 @@ void ShenandoahSTWMark::mark() {

// Weak reference processing
ShenandoahReferenceProcessor* rp = heap->gc_generation()->ref_processor();
heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
assert(heap->gc_generation() == heap->active_generation(), "Should be identical at stw phases");
rp->reset_thread_locals();
rp->set_soft_reference_policy(heap->soft_ref_policy()->should_clear_all_soft_refs());
@@ -175,7 +175,7 @@ void ShenandoahSTWMark::finish_mark(uint worker_id) {
ShenandoahPhaseTimings::Phase phase = _full_gc ? ShenandoahPhaseTimings::full_gc_mark : ShenandoahPhaseTimings::degen_gc_stw_mark;
ShenandoahWorkerTimingsTracker timer(phase, ShenandoahPhaseTimings::ParallelMark, worker_id);
ShenandoahReferenceProcessor* rp = ShenandoahHeap::heap()->gc_generation()->ref_processor();
ShenandoahHeap::heap()->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
StringDedup::Requests requests;

mark_loop(worker_id, &_terminator, rp,
12 changes: 6 additions & 6 deletions src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
Original file line number Diff line number Diff line change
@@ -96,7 +96,7 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure {
if (_heap->mode()->is_generational()) {
_generation = _heap->gc_generation();
assert(_generation != nullptr, "Expected active generation in this mode");
_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
}
}

@@ -192,7 +192,7 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure {
check(ShenandoahAsserts::_safe_oop, obj, obj_reg->has_live() ||
(obj_reg->is_old() && _heap->gc_generation()->is_young()),
"Object must belong to region with live data");
_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
break;
default:
assert(false, "Unhandled liveness verification");
@@ -638,7 +638,7 @@ class ShenandoahVerifierMarkedRegionTask : public WorkerTask {
if (_heap->mode()->is_generational()) {
_generation = _heap->gc_generation();
assert(_generation != nullptr, "Expected active generation in this mode.");
_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
}
};

@@ -880,7 +880,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char* label,
if (_heap->mode()->is_generational()) {
generation = _heap->gc_generation();
guarantee(generation != nullptr, "Need to know which generation to verify.");
_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
} else {
generation = nullptr;
}
@@ -1353,7 +1353,7 @@ void ShenandoahVerifier::verify_rem_set_before_mark() {
ShenandoahOldGeneration* old_generation = _heap->old_generation();
log_debug(gc)("Verifying remembered set at %s mark", old_generation->is_doing_mixed_evacuations() ? "mixed" : "young");

_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
if (old_generation->is_mark_complete() || _heap->gc_generation()->is_global()) {
ctx = _heap->complete_marking_context();
} else {
@@ -1434,7 +1434,7 @@ void ShenandoahVerifier::verify_rem_set_before_update_ref() {

ShenandoahMarkingContext* ctx;

_heap->assert_generations_reconciled();
shenandoah_assert_generations_reconciled();
if (_heap->old_generation()->is_mark_complete() || _heap->gc_generation()->is_global()) {
ctx = _heap->complete_marking_context();
} else {