RFR: Single marking bitmap and bitmap cleaning refactoring

Roman Kennke rkennke at redhat.com
Thu Sep 13 10:11:08 UTC 2018


This is cool!

IIRC, one more major reason to keep complete and next bitmap is the
ability to scan the heap. This is especially important for 'external'
i.e. non-GC heap scans like heapdump code. However, I believe we made
this non-scanning and traversing so it should be immune to this. All
GC-internal heapscans are under our control and we don't need to do that
while bitmap is incomplete, so yeah, the patch should be good.

It's also good in that it saves us space later, if we ever want to
implement concurrent weakref processing, which requires a second bitmap
(heh). Without this patch this would mean 4 bitmaps.

So yeah, please go!

Thanks,
Roman


> http://cr.openjdk.java.net/~shade/shenandoah/single-mark-bitmap/webrev.01/
> 
> This includes two logically separate changes that are still better to come together.
> 
> 1. Single marking bitmap
> 
> We have wondered multiple times recently if we actually need two bitmaps: "next"
> bitmap and "complete" bitmap. It looks like we do not, and we can save about
> 1.5% of heap space hoarded by the second bitmap.
> 
> There are two major reasons why would you'd like to have two bitmaps.
> 
> First, the separation of incomplete (next) and complete bitmaps to isolate bugs,
> where we mistakenly assume the bitmap is complete mid-marking. This might as
> well be achieved by tracking the "completeness" flag, and rewriting the
> accessors to bitmap with complete_marking_ctx (asserting), and marking_ctx
> (non-asserting).
> 
> Second, the bitmap resets: we maintain "complete" bitmap, while cleaning up
> "next" bitmap after the cycle. This helps to have the clean bitmap before
> starting the cycle, and having complete marking available for us otherwise. We
> can avoid the whole thing by carrying complete bitmap at all times after the
> cycle, and only resetting in before the cycle starts. (This might also improve
> temporal locality of bitmap accesses, but I am not holding my breath).
> 
> It looks that rewiring the bitmaps this way makes traversal cleanups much more
> generic. In fact, we don't have to have traversal-special bitmap resets anymore.
> It also simplifies asserts, error reporting, and internal profiling code.
> 
> 
> 2. Refactor bitmap cleanup
> 
> Current TAMS machinery is heavily interconnected with bitmap cleanups. For
> example, on many paths we resist dropping the TAMS before bitmap cleanups,
> because bitmap cleanup would "optimize" and only clear bitmaps up to TAMS. This
> can be simplified if we directly track the top-bitmap pointer, which describes
> what bitmap parts might be dirty, and use that on cleanup path.
> 
> This way, we can drop all the mess about cleaning up bitmaps on region recycling
> for Traversal. The change additionally verifies that bitmaps are indeed cleared
> properly.
> 
> Motivational GC log on Serial:
> 
> # Before
> GC(7) Pause Init Traversal 1.065ms
> GC(7) Concurrent traversal 87104M->87611M(102400M) 1.052ms
> GC(7) Pause Final Traversal 0.387ms
> GC(7) Concurrent cleanup 87611M->2267M(102400M) 16.964ms   // <--- !
> 
> # After
> GC(7) Concurrent reset 87095M->87095M(102400M) 0.812ms
> GC(7) Pause Init Traversal 1.090ms
> GC(7) Concurrent traversal 87147M->87555M(102400M) 0.956ms
> GC(7) Pause Final Traversal 0.363ms
> GC(7) Concurrent cleanup 87555M->2055M(102400M) 0.344ms
> 
> Testing: tier3_gc_shenandoah {fastdebug|release}, eyeballing gc logs
> 
> Thanks,
> -Aleksey
> 




More information about the shenandoah-dev mailing list