[D-runtime] Precise garbage collection

Rainer Schuetze r.sagitario at gmx.de
Fri Jun 21 23:49:46 PDT 2013


On 21.06.2013 23:57, Steven Schveighoffer wrote:
>
> 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.

I think I understand the reasoning for the design and do not mean to 
change it. It shows that there are cases where you want to have the 
liberty to place your data anywhere within the allocation. Having a 
single TypeInfo to describe that is too limiting.


>
> 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.

I was a bit surprised to find the special casing for shared/non-shared 
arrays in the array appending code, given the fact that the absence of 
"shared" does not guarantee it is not shared. I'm not sure whether we 
have to still guarantee memory safety in the case of undeclared sharing, 
but I'd be a bit more comfortable if we could (if it doesn't involve a 
global lock). I don't have a better solution, though.

>
> 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.

Yeah, allocating an array of simd vectors very much require an alignment 
of 16. And structs with alignment specificatons assume to be allocated 
with that alignment aswell.

>
> 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?)

Yes, emplacing just starts with the resulting offset. (I'll have to 
double check whether the initial 2 or 4 pointer bits are actually 
cleared, though).


More information about the D-runtime mailing list