RFR: 8075215: SATB buffer processing found reclaimed humongous object

Bengt Rutisson bengt.rutisson at oracle.com
Thu Apr 30 12:17:07 UTC 2015

Hi Kim,

On 2015-04-28 19:55, Kim Barrett wrote:
> Please review this fix for a problem with eager reclaim of humongous
> objects.
> The elements of SATB buffers are being processed in the same way as
> elements of the mark queue and when scanning objects (e.g. by calling
> CMTask::deal_with_reference).  That no longer works because SATB
> buffers may contain references to reclaimed humongous objects.
> Scrubbing the SATB buffers after eager reclaim of humongous objects
> would extend the pause.  We instead take advantage of the tests needed
> for deciding whether a reference needs to be marked being sufficient
> to also filter out stale references to reclaimed humongous objects.
> We just need to be more circumspect when processing the SATB buffers
> and not assume (and assert) the entries are valid objects until those
> tests have been applied, unlike in other cases.
> To support this new behavior:
> - CMTask::deal_with_reference is now split into an outer part that
> performs tests on an object to determine whether it needs to be shaded
> grey, and an inner part that performs the shading.
> - SATB buffer is changed to perform similar tests on possibly stale
> pointers, and once verified to be interesting, then call the shared
> inner part to perform the shading.  To enable the new SATB buffer
> processing, the closure involved is changed from an ObectClosure to a
> new SATBBufferClosure.
> Also made ObjPtrQueue::apply_closure_and_empty() public to eliminate
> the need for some friends.
> CR:
> https://bugs.openjdk.java.net/browse/JDK-8075215
> Webrev:
> http://cr.openjdk.java.net/~kbarrett/8075215/webrev.00/

Over all the fix looks good. Nice work!

A couple of minor style questions. Feel free to ignore them:


2588   CMSATBBufferClosure _cm_satb;

Do you mind calling the variable _cm_satb_cl instead? I think that is 
more consistent with the other two closures declared in the same place, 
_cm_cl and _code_cl.

2594   G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task) :
2595     _cm_satb(task, g1h), _cm_cl(g1h, g1h->concurrent_mark(), task),
2596     _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations),

To me this looks like two instance variables are being initialized when 
in fact there are three. I would prefer a line break between the first 
and the second, i.e:

   G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task) :
     _cm_satb(task, g1h),
     _cm_cl(g1h, g1h->concurrent_mark(), task),
     _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations),


  292 inline void CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
  293   if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, 
_card_bm)) {
  341   }
  342 }

I think I would prefer an early exit rather than having the whole method 
nested one indentation level. So, something like:

inline void CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
   bool marked = _cm->par_mark_and_count(obj, hr, _marked_bytes_array, 
   if (!marked) {
      // Another thread beat us to this object.


// If G1SATBBufferEnqueueingThresholdPercent == 0 we could skip filtering.

Do you want to fix this too in a separate change? In that case, will you 
file a bug to track that?


> Testing:
> Aurora ad hoc GC Nightly and VM quicktests with G1 as the collector
> local jtreg with G1 as the collector
> local refworkload with G1 as the collector

More information about the hotspot-gc-dev mailing list