How the GC distinguishes code from data
Steven Schveighoffer
schveiguy at yahoo.com
Fri Jan 7 13:47:48 PST 2011
On Fri, 07 Jan 2011 16:39:20 -0500, %u <wfunction at hotmail.com> wrote:
>> None what so ever.
>
> Huh.. then what about what is said in this link?
> http://d.puremagic.com/issues/show_bug.cgi?id=5326#c1
>
> I was told that void[] could contain references, but that ubyte[] would
> not, and
> that the GC would need to scan the former but not the latter. Is that
> wrong?
First, you should understand that the GC does not know what data is in a
memory block. It has no idea that the block is a void[] or a ubyte[] or a
class instance or whatever it is. All it knows is that it's data. What
makes it scan a block is a bit set on the block indicating that it
contains pointers. This bit is set by the higher-level runtime routines
(like the ones that create an array) which use the TypeInfo to determine
whether to set the NO_SCAN bit or not.
Second, memory that is not part of D's allocation is *not* scanned or
marked, no matter where it is. Essentially the mark routine goes like
this (pseudocode):
foreach(root; roots)
if(root.hasPointers) // notice this has nothing to do with type
foreach(pointer; root)
if(pointer.pointsAt.GCHeapBlock)
pointer.heapBlock.mark = true;
while(changesWereMade)
foreach(heapBlock; heap)
if(heapBlock.hasPointers)
foreach(pointer; heapBlock)
if(pointer.pointsAt.GCHeapBlock)
{
pointer.heapBlock.mark = true;
changesWereMade = true;
}
// free memory
foreach(heapBlock; heap)
if(!heapBlock.mark)
free(heapBlock)
So essentially, you can see if you allocated memory for example with
malloc, and you didn't add it as a root, it's neither scanned nor marked.
It does not participate whatsoever with the collection cycle, no matter
what the type of the data is.
Now, you should also realize that just because an array is a void[]
doesn't necessarily make it marked as containing pointers. It is quite
possible to implicitly cast a ubyte[] to a void[], and this does not
change the NO_SCAN bit in the memory block. Data *allocated* as a void[]
(which I highly recommend *not* doing) will be conservatively marked as
containing pointers. This is probably where you get the notion that
void[] contains pointers.
-Steve
More information about the Digitalmars-d-learn
mailing list