digitalmars.D - Understanding GC memory ranges and roots
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (15/15) Jul 06 2020 I'm experimenting with an alternative GC implementation at
- Jacob Carlborg (17/32) Jul 07 2020 The GC (at least the standard GC) works by scanning the roots.
- Steven Schveighoffer (10/33) Jul 07 2020 addRoot and addRange are called when allocations happen outside the
- rikki cattermole (4/6) Jul 07 2020 You won't be able to new the Exception tho.
- Steven Schveighoffer (13/20) Jul 07 2020 there are ways to allocate them on the stack as well, or you can simply
- Atila Neves (2/9) Jul 08 2020 -preview=dip1008
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?
Jul 06 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
Jul 07 2020
On 7/6/20 7:03 PM, Per Nordlöw wrote:I'm experimenting with an alternative GC implementation at https://github.com/nordlow/phobos-next/blob/master/benchmarks/gc-benchmark/so rce/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.addRoot and addRange are called when allocations happen outside the stack or static storage. This might be the global (non-TLS) storage? It could also be something else that the runtime uses (could be on the C heap).How do I catch both the stack and static storage?The stack and Thread Local Storage (i.e. static storage) are scanned using a specialized interface. See here: https://github.com/dlang/druntime/blob/eb279cf69c2e56e38b865409226f22e1d2465e72/src/core/thread/threadbase.d#L1024-L1042And why am I not getting any calls to GC.addRoot()? When is GC.addRoot() supposed to be called and by who?If you are adding prints, you may as well throw an exception, catch it, and print the stack trace if you want to know who's calling what. -Steve
Jul 07 2020
On 07/07/2020 11:50 PM, Steven Schveighoffer wrote:If you are adding prints, you may as well throw an exception, catch it, and print the stack trace if you want to know who's calling what.You won't be able to new the Exception tho. It'll have to be malloc'd ext. In GC -> lock probably hit -> new -> wait on lock
Jul 07 2020
On 7/7/20 6:36 PM, rikki cattermole wrote:On 07/07/2020 11:50 PM, Steven Schveighoffer wrote:there are ways to allocate them on the stack as well, or you can simply initialize a static exception. scope Exception ex = new Exception("nothing"); try { throw ex; } catch(Exception e) { // print stack trace }If you are adding prints, you may as well throw an exception, catch it, and print the stack trace if you want to know who's calling what.You won't be able to new the Exception tho. It'll have to be malloc'd ext.In GC -> lock probably hit -> new -> wait on lockNot sure, possibly printing the stack trace may be a problem as well. But it does seem like it should be doable. -Steve
Jul 07 2020
On Tuesday, 7 July 2020 at 22:36:35 UTC, rikki cattermole wrote:On 07/07/2020 11:50 PM, Steven Schveighoffer wrote:-preview=dip1008If you are adding prints, you may as well throw an exception, catch it, and print the stack trace if you want to know who's calling what.You won't be able to new the Exception tho. It'll have to be malloc'd ext. In GC -> lock probably hit -> new -> wait on lock
Jul 08 2020