RFR: 8224663: Parallel GC: Use WorkGang (5: ScavengeRootsTask)

Leo Korinth leo.korinth at oracle.com
Tue Aug 6 08:17:15 UTC 2019



On 05/08/2019 23:51, Kim Barrett wrote:
>> On Aug 5, 2019, at 11:41 AM, Leo Korinth <leo.korinth at oracle.com> wrote:
>>
>> Hi!
>>
>> On 20/07/2019 04:12, Kim Barrett wrote:
>>>> On May 27, 2019, at 12:30 PM, Leo Korinth <leo.korinth at oracle.com> wrote:
>>>>
>>>> Hi,
>>>>
>>>> Here is the fifth patch in a proposed patch series of eight that
>>>> removes gcTaskManager and uses the WorkGang abstraction instead.
>>>>
>>>> ScavengeRootsTask, ThreadRootsTask and OldToYoungRootsTask is replaced
>>>> with ScavengeRootsTask. Code is basically the same, the major
>>>> difference is that roots are visited using EnumClaimer and
>>>> Threads::possibly_parallel_threads_do. Here we can reuse the RootType
>>>> and EnumClaimer from patch number two.
>>>>
>>>> The reason "case threads:" was removed is that the code is dead. That
>>>> part is confusing as the code is done (in parallel from the calling
>>>> function).
>>>>
>>>> Enhancement:
>>>>   https://bugs.openjdk.java.net/browse/JDK-8224663
>>>>
>>>> Webrev:
>>>> http://cr.openjdk.java.net/~lkorinth/workgang/0/_8224663-Parallel-GC-Use-WorkGang-5-ScavengeRootsTask/
>>>>   http://cr.openjdk.java.net/~lkorinth/workgang/0/all/
>>>>
>>>> Testing (on the whole patch series):
>>>>   mach5 remote-build-and-test --build-profiles linux-x64,linux-x64-debug,macosx-x64,solaris-sparcv9,windows-x64 --test open/test/hotspot/jtreg/:hotspot_gc -a -XX:+UseParallelGC
>>>>   gc test suite
>>>>
>>>> Thanks,
>>>> Leo
>>> 8224663-Parallel-GC-Use-WorkGang-5-ScavengeRootsTask
>>> 8224663-Parallel-GC-Use-WorkGang-5-ScavengeRootsTask-fixup-1
>>> 8224663-Parallel-GC-Use-WorkGang-5-ScavengeRootsTask-fixup-2
>>> Looks good, other than a couple formatting nits and some stale comments.
>>> ------------------------------------------------------------------------------
>>> src/hotspot/share/gc/parallel/psScavenge.cpp
>>> 55 #if INCLUDE_JVMCI
>>> 56 #include "jvmci/jvmci.hpp"
>>> 57 #endif
>>> Conditional includes go at the end, per the style guide. There are
>>> probably counter-examples :)
>>
>> Will correct my "fix".
>>
>>> ------------------------------------------------------------------------------
>>> src/hotspot/share/gc/parallel/psScavenge.cpp
>>> 337 };
>>> 338 //
>>> 339 // OldToYoungRootsTask
>>> Add a blank line between the class and the block comment.
>>
>> Will fix.
>>
>>> ------------------------------------------------------------------------------
>>> 393   ScavengeRootsTask(
>>> 394     PSOldGen* old_gen,
>>> 395     HeapWord* gen_top,
>>> 396     uint active_workers,
>>> 397     bool is_empty) :
>>> It's more usual to line these up with the "(" with the first parameter
>>> on the same line as the function name.
>>
>> Will fix.
>>
>>> ------------------------------------------------------------------------------
>>> src/hotspot/share/gc/parallel/psScavenge.cpp
>>> 339 // OldToYoungRootsTask
>>> 340 //
>>> 341 // This task is used to scan old to young roots in parallel
>>> This comment seems like it needs some update, and maybe is misplaced?
>>> This seems like it's really a description of scavenge_contents_parallel,
>>> in conjunction with the old task creation model.
>>
>> The comment is taken (without changes) from psTasks.hpp and describes the first part (OldToYoungRootsTask). The new task ScavengeRootsTask now does three things from the old code:
>> - OldToYoungRootsTask (where the comment is from)
>> - ScavengeRootsTask
>> - StealTask (depending on thread count)
>>
>> I guess the problem could be bad naming from my side, maybe the name of ScavengeRootsTask ought to reflect this "merge". Maybe I should rename the task ScavengeRootsTask and maybe I should extract the method old_to_young_roots_task() and place the comment there? Maybe the comment is not needed at all?
>>
>> How would you prefer to have it?
> 
> OldToYoungRootsTask basically consisted of the call to
> PSCardTable::scavenge_contents_parallel, and this comment really seems
> to be about how that function works.  Maybe it should be moved there,
> and tidied up for that new location.

Okay. Will try to do that.

> 
>>> src/hotspot/share/gc/parallel/psScavenge.cpp
>>> 446     // If active_workers can exceed 1, add a StrealTask.
>>> 447     // PSPromotionManager::drain_stacks_depth() does not fully drain its
>>> 448     // stacks and expects a StealTask to complete the draining if
>>> 449     // ParallelGCThreads is > 1.
>>> Stale comment now?
>>
>> I believe the comment is still valid, the logic is meant to be the same. Do you think the comment is better if I s/Str?ealTask/steal_task() or have I missed something? Because no change in the behaviour was done on purpose.
> 
> Oh, I see.  The comment's reference to PSPM::drain_stacks_depth()
> really should be to the call to drain_stacks(false) earlier in the function
> containing the comment.  (Which were in different functions before
> your changes, so yay for better co-location of code and comments.)
> [pre-existing]
> 
> There's no such thing as a StealTask anymore.  It should be referring
> to steal_task().
> 
> In workgang nomenclature, scavenge_roots_task and steal_task are
> perhaps misnamed.  They aren't tasks, they are helper work functions.
> Maybe they should be called scavenge_roots_work and steal_work?

You are probably right.

> 
> I don't remember if there were similar possible naming issues
> elsewhere in this cluster of changes.  And you should verify the
> naming convention with someone else before making any changes in
> response to this comment.
> 

I have named all these "*_work" functions "*_task" consistently through 
all patches to reflect the old usage of the code :-(, I will rename them 
if Thomas agree, is that okay with you Thomas?

>>> src/hotspot/share/gc/parallel/psScavenge.cpp
>>> 438     for (Parallel::RootType::Value root_type; _enum_claimer.try_claim(root_type); /* empty */) {
>>> 439       scavenge_roots_task(root_type, worker_id);
>>> 440     }
>>> For the future, maybe serial processing phases should be moved
>>> earlier.  OK to leave it for now to maintain correlation with the old
>>> code.
>>
>> Sorry Kim, I do not understand what you suggest here. Are you referring to the order of the members of enum ParallelRootType, and thus the order in which they are dispatched (in parallel)?
> 
> I was wondering if the serial subtasks in scavenge_roots_task might
> not be better scheduled before card_table->scavenge_contents_parallel().
> But now that I better understand how the latter works, I no longer
> think so.
> 
> I think we already talked about the order of the ParallelRootType enumerators
> and how that might be important for scheduling, and agreed that could be
> looked at later.

Okay, will not change then.

> 
> And finally, a couple more minor things that I missed earlier, both pre-existing.
> 
> ------------------------------------------------------------------------------
> src/hotspot/share/gc/parallel/psScavenge.cpp
> 416       assert(!_old_gen->object_space()->is_empty(),
> 417         "Should not be called is there is no work");
> 418       assert(_old_gen != NULL, "Sanity");
> 
> [pre-existing]
> Checking _old_gen != NULL after already using it in the previous
> assert is kind of pointless.  These asserts should be reordered.

Yes, the order should obviously be changed. Nice catch!

> 
> ------------------------------------------------------------------------------
> src/hotspot/share/gc/parallel/psScavenge.cpp
> 381 // to the start of stride 0 in slice 1.
> 
> [pre-existing]
> s/stride/stripe/

Will fix.

Thanks,
Leo

> 
> ------------------------------------------------------------------------------
> 
> 



More information about the hotspot-gc-dev mailing list