Understanding GC memory ranges and roots

Jacob Carlborg doob at me.com
Tue Jul 7 09:29:51 UTC 2020


On Monday, 6 July 2020 at 23:03:36 UTC, Per Nordlöw wrote:
> I'm experimenting with an alternative GC implementation at
>
> https://github.com/nordlow/phobos-next/blob/master/benchmarks/gc-benchmark/source/segregated_gc.d
>
> I now wonder if the parameters passed by `GC.addRange` and 
> `GC.addRoot` are the only memory entry blocks I need to 
> implement to correctly scan the stack and static memory storage?
>
> I doesn't seem like that because when I add prints to these 
> functions the only call I get is
>
> addRange(0x556d8d118ea0, 93200, nil)
>
> Is this the stack or the static storage?
> I'm guessing static storage because printing the address of the 
> first variable in a function prints 0x7ffe094fa014 which is 
> very different from 0x556d8d118ea0.
>
> How do I catch both the stack and static storage?
>
> And why am I not getting any calls to GC.addRoot()? When is 
> GC.addRoot() supposed to be called and by who?

The GC (at least the standard GC) works by scanning the roots. 
The roots are, IIRC, stack variables, global variables and TLS 
variables. Any memory that is reached through the roots is 
preserved, the rest of the memory (that has been allocated by the 
GC) is collected.

`GC.addRoot` and `GC.addRange` are part of the user facing API. 
It's intended to be called by users. For example, if you allocate 
some GC memory and pass that to a C library. if you don't keep 
any references in the D code to that memory it will be collected, 
even though it might be used by the C library. In this case, 
`GC.addRoot` can be called to add additional roots to those 
mentioned above.

I think you need to implemented acquiring the roots yourself. You 
can have a look at the current GC implementations.

--
/Jacob Carlborg


More information about the Digitalmars-d mailing list