RFR: 8351091: Shenandoah: global marking context completeness is not accurately maintained

William Kemper wkemper at openjdk.org
Tue Mar 4 21:26:04 UTC 2025


On Tue, 4 Mar 2025 08:34:16 GMT, Xiaolong Peng <xpeng at openjdk.org> wrote:

> With the JEP 404: Generational Shenandoah implementation, there are generation specific marking completeness flags introduced, and the global marking context completeness flag is not updated at all after initialization, hence the global marking context completeness is not accurate anymore. This may cause expected behavior: [ShenandoahHeap::complete_marking_context()](https://github.com/openjdk/jdk/pull/23886/files#diff-d5ddf298c36b1c91bf33f9bff7bedcc063074edd68c298817f1fdf39d2ed970fL642) should throw assert error if the global marking context completeness flag is false, but now it always return the marking context even it marking is not complete, this may hide bugs where we expect the global/generational marking to be completed.
> 
> This change PR fix the bug in global marking context completeness flag, and update all the places using `ShenandoahHeap::complete_marking_context()` to use proper API.
> 
> ### Test
> - [x] hotspot_gc_shenandoah
> - [x] Tier 1
> - [ ]  Tier 2

Changes requested by wkemper (Reviewer).

src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp line 2837:

> 2835:   } else if (affiliation == OLD_GENERATION) {
> 2836:     return old_generation();
> 2837:   } else if (affiliation == FREE) {

I don't think it makes sense to connect `FREE` regions to the global generation in this way. Free regions are _not_ affiliated with any generation. I think in some of these cases where you want to find the mark context, it would be possible to take it from a `_generation` member variable.

src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp line 337:

> 335:   // If generation is young and referent is in old, marking context of the old
> 336:   // may or may not be complete, we can safely drop the reference when old gen mark is complete.
> 337:   if (_generation->is_young() && referent_region->is_old()) {

Have you seen this happen? The reference processor for each generation is only supposed to discover references for which the referent is in the collected generation. See `ShenandoahReferenceProcessor::should_discover`:

  if (!heap->is_in_active_generation(referent)) {
    log_trace(gc,ref)("Referent outside of active generation: " PTR_FORMAT, p2i(referent));
    return false;
  }

-------------

PR Review: https://git.openjdk.org/jdk/pull/23886#pullrequestreview-2658463721
PR Review Comment: https://git.openjdk.org/jdk/pull/23886#discussion_r1979938123
PR Review Comment: https://git.openjdk.org/jdk/pull/23886#discussion_r1979932540


More information about the shenandoah-dev mailing list