[D-runtime] Proposed changes to GC interface

Steve Schveighoffer schveiguy at yahoo.com
Fri Aug 6 12:34:41 PDT 2010


>
>From: Sean Kelly <sean at invisibleduck.org>

[snip]

>
>gc_alloc() and gc_allocn() would become the default GC allocator routines and 
>would set any necessary flags based on the supplied type, store the pointer 
>bitmap, initialize the block based on ti.init[], etc.

OK, but why do we need bitmaps/bits if we can just store that info in the 
TypeInfo?  I mean, gc_allocn is pretty much the same as lifetime's 
_d_newArrayT.  It uses the bits set in the typeinfo to determine the NO_SCAN 
flag.  Why can't the GC use those bits?

I'd think that bits are only useful for small blocks where the cost of storing 
the TypeInfo pointer is greater than 10% overhead.  But if you need to go from 
block -> typeinfo, this may be a requirement (see questions below).

In addition to these, if the GC is going to handle appending, then it should 
handle how the length is stored.  This means, we need functions to get and set 
the length to support append and the capacity/assumeSafeAppend functions.

Note that dmd currently allocates classes via _d_newClass, but allocates 
individual structs via _d_newArrayT.  This is a major change that needs to be 
made on the compiler side (it's sort of overdue anyways).

>gc_malloc() will remain as-is because I suspect there will always be a need for 

>using D as a "better C."  If this becomes an array of structs the user would be 

>responsible for supplying the TypeInfo later (or finalizer or whatever).

Yes, any special handling of the block on delete needs to be handled by the 
user.  There should be functions to attach handlers for collection on that 
block.

>gc_qalloc() should be rendered largely useless by the addition of gc_alloc() and 
>
>gc_allocn(), since the need for gc_qalloc() was mostly to efficiently do stuff 
>in lifetime.d that would instead be handled by the GC.  Steve, is this 
accurate?

I'd say yes, but I'd strongly suggest then that we expose the out parameter for 
gc_malloc that returns the *actual* block size allocated that I added to support 
qalloc.  Anyone whose doing direct gc allocations will certainly like to have 
that bit of info especially since it costs nothing to provide it.  In reality, I 
didn't care about the entire BlkInfo, I only cared about the allocated length.  
Using BlkInfo was easy, especially since I needed the bits to be stored (in 
fact, if you look at qalloc, it simply copies the input parameter bits to the 
result).

>gc_realloc() has never seen much use and promises to become increasingly more 
>complicated as TypeInfo is added, etc.  I'd prefer to just drop it and let the 
>user call gc_extend() if he wants to resize memory in place.  This would require 
>
>allowing gc_extend() to be used on sub-page sized blocks, but this seems 
>reasonable anyway.  If I have a 150 byte array in a 256 byte block I should be 
>allowed to extend it to 256 bytes.  Doing so is basically a no-op, but it frees 

>the user from having to query the block size to determine how to handle an array 
>
>append operation, for example.

I don't think gc_extend's semantics should be changed.  If one wants to extend 
into the block, one should just get the capacity and use the block.  This of 
course is only on blocks that are allocated via gc_malloc.  Blocks allocated via 
gc_alloc[n] should only be extendable via the runtime functions to keep the 
TypeInfo sane.

>Finally, I really want to change the APPENDABLE bit to 
>NO_APPEND/STATIC/SINGLE/whatever since the default (zero value) behavior should 

>be that an allocated block is not an array.

I think there is a misunderstanding here.  a 0 APPENDABLE bit means it's not 
appendable (i.e. not an array).  Isn't that what you want?

Overall I think this is a good idea.  I think actually it's probably necessary 
to integrate the precise scanning and array append stuff together.

Some things to think about, while they're fresh in my mind:
If someone appends to an array with a different typeinfo than it was originally 
allocated with, what happens?
What happens when you do a new array of void[]?
Should you be able to retrieve the typeinfo a block was allocated with?
Dare I say it, but this is going to once again separate Tango from phobos, since 
Tango does not use druntime even though Tango uses an old version of druntime.  
Should we care?  I say no, I strongly believe Tango is stuck on D1 forever.

-Steve



      


More information about the D-runtime mailing list