RFR (M) 8138762: Refactor setup of evacuation closures in G1

Mikael Gerdin mikael.gerdin at oracle.com
Fri Oct 2 15:29:40 UTC 2015


Hi all,

I've grown tired of the way the closures are set up in G1ParTask, where 
3 different sets of closures are allocated on the stack and then 
pointers to them are passed to the root processor depending on the type 
of GC we are doing.

My suggested solution to this is to introduce an interface for a policy 
object which is queried by the root processor for different closures:
   32 class G1RootClosureSet : public CHeapObj<mtGC> {
   33
   34 public:
   35   // Closures to process raw oops in the root set.
   36   virtual OopClosure* weak_oops() = 0;
   37   virtual OopClosure* strong_oops() = 0;
   38
   39   // Closures to process CLDs in the root set.
   40   virtual CLDClosure* weak_clds() = 0;
   41   virtual CLDClosure* strong_clds() = 0;
   42
   43   // Applied to the CLDs reachable from the thread stacks.
   44   virtual CLDClosure* thread_root_clds() = 0;
   45   // Applied to the weakly reachable CLDs when all strongly reachable
   46   // CLDs are guaranteed to have been processed.
   47   virtual CLDClosure* second_pass_weak_clds() = 0;
   48
   49   virtual CodeBlobClosure* strong_codeblobs() = 0;
   50   virtual CodeBlobClosure* weak_codeblobs() = 0;
   51   // Applied to the code blobs reachable from the thread stacks.
   52   virtual CodeBlobClosure* thread_root_codeblobs() = 0;
   53 };

This policy object is then instantiated by a factory method which 
decides on which implementation to create depending on the type of the 
current gc. The policy object is stored in the par scan thread state and 
is used later on when the reference processing code use the same closures.

For G1MarkSweep and verification I've kept the external api of the root 
processor the same and wrap the closures before passing them on inside 
the root processor.

--

I've split the change into two different webrevs.
The first one moves a bunch of code out from g1CollectedHeap.cpp to 
become externally visible.
I also noticed that g1CodeBlobClosure.hpp is missing include guards.
To make room for the closure set in the par scan state I remove the 
unused g1 rem set pointer in this first webrev.

http://cr.openjdk.java.net/~mgerdin/8138762_1/webrev.0/

--

The second webrev contains the actual change.
I decided to separate the interface headers and the actual 
implementations of the closure sets in two separate files.
g1RootClosureSet.hpp contains the interface and g1EvacuationClosures.hpp 
contains the implementations used by a G1 evacuation pause.

http://cr.openjdk.java.net/~mgerdin/8138762_2/webrev.0/

--

The full webrev is available at:
http://cr.openjdk.java.net/~mgerdin/8138762_full/webrev.0/

Testing:
JPRT
Performance (aurora.se G1 workloads on Solaris x64)
Kitchensink,runThese,vm.gc.testlist,vm.g1classunload.testlist

I appreciate any feedback, if you have suggestions for different class 
names I'm happy to change them, I had some trouble coming up with good ones.

Thanks
/Mikael



More information about the hotspot-gc-dev mailing list