Question about garbage collection specification

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Jun 15 09:03:31 PDT 2015


On 6/15/15 11:18 AM, Dmitry Olshansky wrote:
> On 15-Jun-2015 15:49, Steven Schveighoffer wrote:
>> On 6/15/15 8:08 AM, Dmitry Olshansky wrote:
>>> On 13-Jun-2015 14:32, rsw0x wrote:
>>>> http://dlang.org/garbage.html
>>>>
>>>> Do not take advantage of alignment of pointers to store bit flags in
>>>> the
>>>> low order bits:
>>>> p = cast(void*)(cast(int)p | 1);  // error: undefined behavior
>>>>
>>>> if this restriction is actually imposed - why does
>>>> std.bitmanip.tagged{ClassRef,Pointer} even exist?
>>>
>>> AFAIK the restriction was that pointers _themselves_ have to be stored
>>> at word-aligned addresses. This allows GC to scan memory cheaper w/o
>>> considering if some misaligned address may contain a pointer.
>>
>> That doesn't make sense. Why would you want to do this?
>>
>
> What exactly? Storing pointer at misaligned memory location - no good
> reason whatsoever. As in how it may happen - explicitly tightly packed
> structs with align(1) might end up doing this.
>
>  From http://dlang.org/phobos/core_memory.html which seems to be more
> recent:
>
> Implementations are free to assume that GC pointers are only stored on
> word boundaries. Unaligned pointers may be ignored entirely.

Right, and that's already assumed in (and would be ignored by) the 
current GC. What's NOT assumed (and I have no idea how we could make 
this assumption) is that interior pointers that point at parts of a 
larger struct/type/etc aren't valid GC pointers, and so the GC can 
ignore those too.

For example:

void *p = &someGCInt;
p++; // equivalent to p = cast(void *)(cast(size_t)p | 1);

The documentation above implies that if p is the only pointer to 
someGCInt, the GC may collect it. I think this is not possible for us to 
claim, even if we wanted to, given D's type system.

>> The only rational thing I can think of is that you wouldn't want to
>> store the result in an *actual* int pointer (lest it be used thinking it
>> was valid without masking out the lower bits). But the example is
>> storing it in a void *...
>>
>
> The example doesn't show what memory location that p refers to thus it's
> not possible to say if it's valid.

The whole premise (as stated in the doc right before the example) is 
that you know the low order bits are 0 :) this is the complete basis of 
std.bitmanip.taggedPtr. It's quite genius I think, and the fact that it 
works with GC (and IMO, any possible GC you could create for D) without 
issue is awesome. We should not be attaching a scarlet comment to the 
docs to warn people away from it.

-Steve


More information about the Digitalmars-d mailing list