RFR: 8254028: G1 incorrectly updates scan_top for collection set regions during preparation of evacuation

Stefan Johansson sjohanss at openjdk.java.net
Fri Oct 9 08:30:18 UTC 2020


On Thu, 8 Oct 2020 18:45:49 GMT, Stefan Johansson <sjohanss at openjdk.org> wrote:

>> Hi all,
>> 
>>   can I have reviews for this change that makes values of G1RemSetScanState::_scan_top for regions in the initial
>>   collection set consistent with ones in optional collection set?
>> So currently G1RemSetScanState::_scan_top is top() for regions in the initial collection set although they will never
>> be scanned as enforced when dropping the remsets onto the card table. For the optional collection set, G1 sets scan_top
>> manually to NULL when selecting the next few optional regions (using G1RemSet::exclude_region_from_scan()).  When
>> debugging this discrepancy recently posed some slight surprise for me, so I would like to change this. Also there is
>> some risk that future code that relies on that property will be surprised.  Testing: tier1-4; lots of kitchensink runs
>> with JDK-8254164.
>> Thanks,
>>   Thomas
>
> I'm not to fond of the comment saying this is not really needed. After the fix for
> [JDK-8252752](https://bugs.openjdk.java.net/browse/JDK-8252752) `prepare_region_for_scan()` don't do anything with
> regions in the collection-set so I would prefer if we instead filtered those regions at the call-site.  In
> `G1PrepareRegionsClosure::do_heap_region(HeapRegion* hr)` we could add:  ++
>       // Pepare regions not in the collection set for scanning.
>       if (!hr->in_collection_set())  {
>         _g1h->rem_set()->prepare_region_for_scan(hr);
>       }
> 
> This way we don't need to check for collection-set regions in the assert either. What do you think?

> I considered changing the caller as suggested, but this adds additional
> (unspoken) requirements on it:

But it also makes the code clearer showing that we don't do any thing for collection-set regions in this call.

> - the caller needs to know that the initialization of the corresponding
scan_top field is NULL (or something to that effect).
> - and that this is the only preparation work performed in that method.
> (I.e. there might be future things to do)

But I do agree that it's nice to assert that the collection-set regions are in the correct state. And if we want to
prepare for future preparation that also do stuff for the collection-set regions I think we should go back to the old
if-else like this: ++ if (r->in_collection_set()) {
  // Regions in the collection-set should not be scanned.
  assert(_scan_state->scan_top(hrm_index) == NULL,
         "scan_top of region %u is unexpectedly " PTR_FORMAT,
         hrm_index, p2i(_scan_state->scan_top(hrm_index)));
} else if(r->is_old_or_humongous_or_archive()) {
  // Prepare all other regions for scanning.
  _scan_state->set_scan_top(hrm_index, r->top());
} else {
  assert(r->is_free(), "Region %u should be free but is %s",
         hrm_index, r->get_type_str());
}

I think this satisfies both our wishes, do you agree?

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

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



More information about the hotspot-gc-dev mailing list