RFR (XL): 8202845: Refactor reference processing for improved parallelism

Kim Barrett kim.barrett at oracle.com
Tue Jun 12 16:20:44 UTC 2018


> On Jun 6, 2018, at 1:13 PM, Thomas Schatzl <thomas.schatzl at oracle.com> wrote:
> 
> I thought marks_oops_alive is an unnecessary quirk of the collectors
> that found its way into the reference processing interface; its purpose
> is to indicate whether the gc should perform stealing at the end of a
> phase, as the complete closures drain the stacks completely by
> themselves anyway.
> 
> Stealing or not should be part of the complete closure (i.e. the gc,
> and attempted by default by the gc) imho (it "completes" the phase),
> like G1 does.
> 
> I fixed it though.

marks_oops_alive is another piece (really an entirely different
mechanism) of the avoidance of stealing and the termination protocol
when the keep_alive closure won't be marking any previously unmarked
objects, so (maybe) won't be generating any potentially stealable
work.  It seems to me to be a better approach than sometimes not
calling the complete_gc closure (the other mechanism, used by
process_phase2), since it puts the decision on the specific collector
that knows how its keep_alive and complete_gc closures interact.  See
further discussion below.

> New webrevs:
> http://cr.openjdk.java.net/~tschatzl/8202845/webrev.0_to_1 (diff)
> http://cr.openjdk.java.net/~tschatzl/8202845/webrev.1 (full)
> Testing:
> hs-tier1-5,jdk-tier-1-3 (with +/-ParallelRefProcEnabled)
> 
> Thanks for your quick review,
>  Thomas

Sorry this one took longer.

------------------------------------------------------------------------------
src/hotspot/share/gc/shared/referenceProcessor.cpp
 315   if (log_is_enabled(Trace, gc, ref)) {
 324   if (log_is_enabled(Trace, gc, ref)) {

s/log_is_enabled/log_develop_is_enabled/

------------------------------------------------------------------------------
src/hotspot/share/gc/shared/referenceProcessor.cpp
 571     complete_gc.do_void();

I think this is unavoidable (at least for now), but I'm wondering if
this is a performance issue for other than G1-young collections.

In the phases where marks_oops_alive is false (like this one), for the
other collectors (and G1 concurrent and full GC, I think), there won't
be anything to steal. Starting the stealing process (and its
associated termination protocol) is a waste of time in those cases.

ParallelScavange and ParallelCompaction both avoid creating the
stealing tasks if marks_oops_alive is false.  CMS avoids calling
do_work_stealing when marks_oops_alive is false.  ParNew doesn't seem
to look at that bit though.

G1 concurrent and full GCs also don't seem to look at that bit, and so
I think will be negatively affected.  Maybe this is a job for another
RFE.

Some comment revision might be called for though.  It would be nice to
not have to re-discover (no pun intended) all this again.

------------------------------------------------------------------------------
src/hotspot/share/gc/shared/referenceProcessor.cpp 
 457   // Close the reachable set
 458   complete_gc->do_void();

Same issues here for PhantomReferences as earlier for
Soft/Weak/FinalReferences.  And I think the same solution; pay
attention to the marks_oops_alive bit.

------------------------------------------------------------------------------
src/hotspot/share/gc/shared/referenceProcessor.cpp 
 595     : ProcessTask(ref_processor, true /* marks_oops_alive */, phase_times) { }

For PhantomReferences, marks_oops_alive should be false, for the same
reason as for soft/weak/final.

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




More information about the hotspot-gc-dev mailing list