On 6/19/23 12:13 PM, axricard wrote:
I'm doing some experiments with ldc2 GC, by instrumenting it and printing basic information (what is allocated and freed)My first tests are made on this sample : ```cat test2.dimport core.memory; class Bar { int bar; } class Foo { this() { this.bar = new Bar; } Bar bar; } void func() { Foo f2 = new Foo; } int main() { Foo f = new Foo; func(); GC.collect(); return 0; } ```When trying to run the instrumented druntime, I get a strange behavior : the first collection (done with GC.collect) doesn't sweep anything (in particular, it doesn't sweep memory allocated in _func()_). The whole sweeping is done when program finish, at cleanup. I don't understand why : memory allocated in _func()_ shouldn't be accessible from any root at first collection, right ?```╰─> /instrumented-ldc2 -g -O0 test2.d --disable-gc2stack --disable-d-passes --of test2 && ./test2 "--DRT-gcopt=cleanup:collect fork:0 parallel:0 verbose:2"[test2.d:26] new 'test2.Foo' (24 bytes) => p = 0x7f3a0454d000 [test2.d:10] new 'test2.Bar' (20 bytes) => p = 0x7f3a0454d020 [test2.d:21] new 'test2.Foo' (24 bytes) => p = 0x7f3a0454d040 [test2.d:10] new 'test2.Bar' (20 bytes) => p = 0x7f3a0454d060 ============ COLLECTION ============= ============= MARKING ============== marking range: [0x7fff22337a60..0x7fff22339000] (0x15a0) range: [0x7f3a0454d000..0x7f3a0454d020] (0x20) range: [0x7f3a0454d040..0x7f3a0454d060] (0x20) marking range: [0x7f3a0464d720..0x7f3a0464d8b9] (0x199) marking range: [0x46c610..0x47b3b8] (0xeda8) ============= SWEEPING ============== ===================================================== ============ COLLECTION ============= ============= MARKING ============== marking range: [0x46c610..0x47b3b8] (0xeda8) ============= SWEEPING ==============Freeing test2.Foo (test2.d:26; 24 bytes) (0x7f3a0454d000). AGE : 1/2 Freeing test2.Bar (test2.d:10; 20 bytes) (0x7f3a0454d020). AGE : 1/2 Freeing test2.Foo (test2.d:21; 24 bytes) (0x7f3a0454d040). AGE : 1/2 Freeing test2.Bar (test2.d:10; 20 bytes) (0x7f3a0454d060). AGE : 1/2===================================================== ```
In general, the language does not guarantee when the GC will collect your item.
In this specific case, most likely it's a stale register or stack reference. One way I usually use to ensure such things is to call a function that destroys the existing stack:
```d
void clobber()
{
int[2048] x;
}
```
Calling this function will clear out 2048x4 bytes of data to 0 on the stack.
-Steve
