RFR: Use PLABs for old gen allocations, including promotions. [v2]

Roman Kennke rkennke at openjdk.java.net
Fri Apr 16 14:40:53 UTC 2021


On Wed, 14 Apr 2021 18:05:22 GMT, Bernd Mathiske <bmathiske at openjdk.org> wrote:

>> Introducing a 3rd kind of LAB for generational mode: "PLAB".
>> 
>> Shenandoah already has TLABs and GCLABs. The latter pertain firmly to young gen and allocations in old gen are so far always shared allocations, without LAB. With this PR, old gen allocations go through LABs as well and we separate those from the other two kinds. In other words, each generation has its separate GC-decicated LAB. 
>> 
>> When not in generational mode, GCLABs work as before and PLABs are never used.
>> 
>> The new diagnostic flag -XX:-ShenandoahUsePLAB can be used to turn off PLAB use, so that all old gen allocations are shared as before this PR. By default PLABs will be used.
>> 
>> Note that In source code, the type of both GCLABs and PLABs is "PLAB*", sonce GCLABs already had that type, but variable references and other value-level identifiers are consistently named "gclab" and "plab".
>> 
>> In ShenandoahFreeSet::allocate_single() there is a notable additional change that can easily be reverted if needed. Instead of fitting the intended allocation into any free or occupied region that can hold it, we now search for an occupied region in the same generation first, before considering free regions. The idea is to pack regions more densely as long as they have space left. This provides more opportunity for region borrowing between generations, should the need arise. For single-generational Shenandoah, it should not make a huge difference, right? Or is it crucial to find any free slot hit in that search loop ASAP?
>> 
>> Full collections need to set empty/trash regions that they compact into to non-FREE. For now, they will be made "YOUNG". (See the second commit.)
>
> Bernd Mathiske has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Register filler objects for unsuccessful non-LAB evacuations.

Nice progress! I have a few questions/comments.

src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp line 125:

> 123:       result = allocate_with_affiliation(FREE, req, in_new_region);
> 124:       if (result != NULL) {
> 125:         return result;

I am not sure about this. What must not happen here is that we mix new allocations and evacuations into the same region. That is because we need to update references in evacuated objects later, but not for new objects (we're guaranteed to only store to-space refs into new objects). I guess it's similar for promotions: we do need to update refs in promoted objects. That means we can mix promotions and evacuations, but cannot mix either of them with new allocations. Can you clarify this?

src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp line 430:

> 428: 
> 429:   assert(r->is_empty(), "Region must be empty after flipping from mutator to GC.");
> 430:   r->set_affiliation(FREE);

Why is this block needed now?

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

> 880:   return plab->allocate(size);
> 881: }
> 882: 

Is this a full (or almost full) copy of allocate_from_gclab_slow() ? Maybe this warrants some refactoring/sharing?

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

PR: https://git.openjdk.java.net/shenandoah/pull/30


More information about the shenandoah-dev mailing list