RFR: 8255019: Shenandoah: Split STW and concurrent mark into separate classes [v24]

Aleksey Shipilev shade at openjdk.java.net
Tue Jan 5 14:11:06 UTC 2021


On Tue, 5 Jan 2021 13:43:06 GMT, Zhengyu Gu <zgu at openjdk.org> wrote:

>> This is the first part of refactoring, that aims to isolate three Shenandoah GC modes (concurrent, degenerated and full gc).
>> 
>> Shenandoah started with two GC modes, concurrent and full gc, with minimal shared code, mainly in mark phase. After introducing degenerated GC, it shared quite large portion of code with concurrent GC, with the concept that degenerated GC can simply pick up remaining work of concurrent GC in STW mode.
>> 
>> It was not a big problem at that time, since concurrent GC also processed roots STW. Since Shenandoah gradually moved root processing into concurrent phase, code started to diverge, that made code hard to reason and maintain.
>> 
>> First step, I would like to split STW and concurrent mark, so that:
>> 1) Code has to special case for STW and concurrent mark.
>> 2) STW mark does not need to rendezvous workers between root mark and the rest of mark
>> 3) STW mark does not need to activate SATB barrier and drain SATB buffers.
>> 4) STW mark does not need to remark some of roots.
>> 
>> The patch mainly just shuffles code.  Creates a base class ShenandoahMark, and moved shared code (from current shenandoahConcurrentMark) into this base class. I did 'git mv shenandoahConcurrentMark.inline.hpp  shenandoahMark.inline.hpp, but git does not seem to reflect that.
>> 
>> A few changes:
>> 1) Moved task queue set from ShenandoahConcurrentMark to ShenandoahHeap. ShenandoahMark and its subclasses are stateless. Instead, mark states are maintained in task queue, mark bitmap and SATB buffers, so that they can be created on demand.
>> 2) Split ShenandoahConcurrentRootScanner template to ShenandoahConcurrentRootScanner and ShenandoahSTWRootScanner
>> 3) Split code inside op_final_mark code into finish_mark and prepare_evacuation helper functions.
>> 4) Made ShenandoahMarkCompact stack allocated (as well as ShenandoahConcurrentGC and ShenandoahDegeneratedGC in upcoming refactoring)
>
> Zhengyu Gu has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 31 commits:
> 
>  - Merge
>  - Update copyright years
>  - Merge
>  - Merge branch 'master' into JDK-8255019-sh-mark
>  - Concurrent mark does not expect forwarded objects
>  - Merge branch 'master' into JDK-8255019-sh-mark
>  - Merge branch 'master' into JDK-8255019-sh-mark
>  - Silent valgrind on potential memory leak
>  - Merge branch 'master' into JDK-8255019-sh-mark
>  - Removed ShenandoahConcurrentMark parameter from concurrent GC entry/op, etc.
>  - ... and 21 more: https://git.openjdk.java.net/jdk/compare/a6c08813...b7390c08

First read review follows.

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp line 161:

> 159:     // threads, and performance-wise it doesn't really matter. Adds about 1ms to
> 160:     // full-gc.
> 161:     {

This seems to revert JDK-8258490?

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp line 168:

> 166:       while (satb_mq_set.apply_closure_to_completed_buffer(&cl));
> 167:       bool do_nmethods = heap->unload_classes() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading();
> 168:       assert(!heap->has_forwarded_objects(), "Not expected");

Do you need to move this assert?

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp line 314:

> 312:                                                                     ShenandoahReferenceProcessor* rp,
> 313:                                                                     ShenandoahPhaseTimings::Phase phase,
> 314:                                                                     uint nworkers) :

This indenting seems wrong? The original one was correct, I think.

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp line 325:

> 323:   ShenandoahConcurrentWorkerSession worker_session(worker_id);
> 324:   ShenandoahObjToScanQueue* q = _queue_set->queue(worker_id);
> 325:   ShenandoahMarkResolveRefsClosure cl(q, _rp);

Why `ShenandoahMarkRefsClosure` -> `ShenandoahMarkResolveRefsClosure` change?

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp line 335:

> 333:   ShenandoahReferenceProcessor* rp = _heap->ref_processor();
> 334:   task_queues()->reserve(workers->active_workers());
> 335:   ShenandoahMarkConcurrentRootsTask task(task_queues(), rp,  ShenandoahPhaseTimings::conc_mark_roots, workers->active_workers());

Excess space: `rp,  ShenandoahPhaseTimings`.

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp line 344:

> 342:   uint nworkers = workers->active_workers();
> 343:   task_queues()->reserve(nworkers);
> 344:   TaskTerminator terminator(nworkers, task_queues());

There is another `TaskTerminator` right below it, is it correct?

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp line 58:

> 56:   // TODO: where to put them
> 57:   static void update_roots(ShenandoahPhaseTimings::Phase root_phase);
> 58:   static void update_thread_roots(ShenandoahPhaseTimings::Phase root_phase);

Sounds like these better to be shared in `ShenandoahMark`?

src/hotspot/share/gc/shenandoah/shenandoahMark.cpp line 38:

> 36: #include "gc/shenandoah/shenandoahUtils.hpp"
> 37: #include "gc/shenandoah/shenandoahVerifier.hpp"
> 38: 

Excess newline?

src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp line 306:

> 304: ShenandoahHeap* ShenandoahMark::heap() const {
> 305:   return _heap;
> 306: }

Do we really need this method? `ShenandoahHeap::heap()` is supposed to be as fast.

src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp line 249:

> 247:   rp->set_soft_reference_policy(true); // forcefully purge all soft references
> 248: 
> 249: 

Excess newline?

src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp line 2:

> 1: /*
> 2:  * Copyright (c) 2019, 2019, Red Hat, Inc. All rights reserved.

Odd change: 2020 -> 2019.

src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp line 81:

> 79:   task_queues()->reserve(nworkers);
> 80: 
> 81: 

Excess new-line, drop one.

src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp line 96:

> 94:   TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats());
> 95:   TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
> 96: 

Excess newline

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

Changes requested by shade (Reviewer).

PR: https://git.openjdk.java.net/jdk/pull/1009



More information about the hotspot-gc-dev mailing list