RFR: Refactor to group marking bitmap and TAMS structure in one class ShenandoahMarkingContext

Aleksey Shipilev shade at redhat.com
Tue Jul 17 20:49:31 UTC 2018


On 07/17/2018 10:20 PM, Roman Kennke wrote:
> This is a long overdue refactoring. It groups the two structures
> involved in marking (bitmap + TAMS) into one class
> ShenandoahMarkingContext. This allows for some interesting improvements:
> - Easy to keep in sync (e.g. simpler swapping and reasoning-about)
> - Can keep actual arrays const
> - Can pass around the context (see upcoming patch)
> - Code related to marking and other bookkeeping is now grouped together
> in one class
> - Reduce duplications next vs. complete versions of methods
> 
> The code now makes obvious where we have extra dereferences. I felt the
> itch to reduce XX_marking_context() calls in a bunch of places, but
> wanted to keep this a mechanical refactoring as much as possible.
> Upcoming patch resolves some of the hottest indirections. In any case,
> it's not worse than it was before (it only looks worse).
> 
> Testing: tier3_gc_shenandoah ok
> 
> http://cr.openjdk.java.net/~rkennke/refactor-marking-context/webrev.00/

Looks cute!

 *) This method is probably "swap_mark_contexts" now:
  1994 void ShenandoahHeap::swap_mark_bitmaps() {

 *) ShIsAlive, ShForwardedIsAlive, ShIsMarkedNextClosure closures are also performance-sensitive...

 *) context()->mark_bit_map()->clear_range_large(...) can probably be put in utility method, e.g.
context()->clear_bitmap(...) or something. In fact, mark_bit_map() should only be used when
something wants the naked bitmap, e.g. Verifier.

 *) Seems to me, you can use local variables a lot to both simplify the code, and micro-optimize. E.g.:

  if (heap->is_bitmap_slice_committed(region)) {
    if (_traversal_set.is_in(i)) {
      heap->next_marking_context()->set_top_at_mark_start(region->region_number(), region->top());
      region->clear_live_data();
      assert(heap->next_marking_context()->is_bitmap_clear_range(region->bottom(), region->end()),
"bitmap for traversal regions must be cleared");
    } else {
      // Everything outside the traversal set is always considered live.
      heap->next_marking_context()->set_top_at_mark_start(region->region_number(), region->bottom());
    }
  }

...is:

  ShenandoahMarkingContext* ctx = heap->next_marking_context();
  if (heap->is_bitmap_slice_committed(region)) {
    if (_traversal_set.is_in(i)) {
      ctx->set_top_at_mark_start(region->region_number(), region->top());
      region->clear_live_data();
      assert(ctx->is_bitmap_clear_range(region->bottom(), region->end()), "bitmap for traversal
regions must be cleared");
    } else {
      // Everything outside the traversal set is always considered live.
      ctx->set_top_at_mark_start(region->region_number(), region->bottom());
    }
  }

Thanks,
-Aleksey



More information about the shenandoah-dev mailing list