Card mark steal (dotnet/coreclr#25986)
authorPeter Sollich <petersol@microsoft.com>
Wed, 23 Oct 2019 11:56:43 +0000 (13:56 +0200)
committerGitHub <noreply@github.com>
Wed, 23 Oct 2019 11:56:43 +0000 (13:56 +0200)
commitf2e9d9c9e28641970d56bedaddcc6feeff9e3b78
tree71f0041c5055156feb5cc26c12ffdb19bc5ef6b2
parent85bbdd0fcbb893fa2210d31fd2f7cb29ec807977
Card mark steal (dotnet/coreclr#25986)

Implement card marking stealing for better work balance in Server GC.

One of the last stages in the mark_phase is to mark objects referenced from older generations. This stage is often slow compared to the other stages, and it is also often somewhat unbalanced, i.e. some GC threads finish their work significantly sooner than others. The change also applies to the relocate_phase, but that phase usually takes significantly less time.

This change implements thread-safe enumeration of older generations by dividing them into chunks (2 MB in 64-bits, 1 MB in 32-bits), and arranges it so threads finishing work early will help on other heaps. Each thread grabs a chunk and then looks through the card table section corresponding to this chunk. When it's done with a chunk, it grabs the next one and so on.
There are changes at multiple levels:

- at the top level, mark_phase and relocate_phase contain changes to check for work already done for both the heap associated with the thread and other heaps.
- these routines call mark_through_cards_for_segments and mark_through_cards_for_large_objects which contain code to walk through the older generations in chunks.
 - ultimately card_marking_enumerator::move_next implements the thread safe enumeration, supplying chunks, and gc_heap::find_next_chunk supplies a chunk where all card bits are set.

Commit migrated from https://github.com/dotnet/coreclr/commit/5ca444ce55137d60f2fb033d8a110ce8b3e70df3
src/coreclr/src/gc/gc.cpp
src/coreclr/src/gc/gcpriv.h
src/coreclr/src/inc/log.h
src/coreclr/src/inc/stresslog.h