[D-runtime] Precise garbage collection

Steven Schveighoffer schveiguy at yahoo.com
Fri Jun 21 14:57:59 PDT 2013


On Jun 21, 2013, at 5:37 PM, Rainer Schuetze <r.sagitario at gmx.de> wrote:

> The size value itself is only a small issue, the larger one is the address of the array data moves depending on the size of the allocation, so the pointer info needs to be placed at some offset sometimes. My first implementation actually figured this out in the GC, but I think this leaks too much implementation details of the array into the GC. So I changed it to use gc_emplace instead.

In case I didn't explain it well in the documentation/comments, the reason for this is because when you append to a PAGE or larger sized block, the GC can tack on additional pages and get to add more memory for free (without moving the existing data).  If the "size" field was at the end, then it would have to move to the new page.

This can be a problem if you have two threads looking at the block at the same time.  One can get the block info, release the GC lock, then the other could extend the block.  By the time the first thread comes back to look at the "end" of the block (which is checked while holding a different lock), the block info is no longer valid, and it would look at the wrong place.  I think for unshared blocks, there would be no problem, but block can become shared/unshared via a cast, and that would cause problems.

This could probably be done better, but that is the reasoning.  I will note that it was really never a problem for things like classes because a class block would never be marked as APPENDABLE.

The choice of 16 bytes was recommended by "people who know" :)  I initially thought 8 would be fine but was told that wasn't a good idea.

In any case, an abstraction like gc_emplace is a good idea.  You do, however, have to ignore that "size" field at the front when scanning (I'm assuming you are doing that?)

-Steve


More information about the D-runtime mailing list