3 ms·
Good point, definetly better for debugging, iirc the reason for the array was that the shadow-stack array was part of my calling convention. The GC-heap argume
by whizzter 8mo ago
Good point, definetly better for debugging, iirc the reason for the array was that the shadow-stack array was part of my calling convention.
The GC-heap arguments to called functions with moveable pointers in the GC was indirected through the passed GC-chain ptr, ie you passed a pointer to the N:th element in the caller's shadow-stack that was then the 1:st heap based argument to the callee.
The benefit of that was the callee didn't need to copy over it's incoming arguments to a new shadow-stack (thus increasing a fixed costs of more arguments) but could just link the previous array and IFF there was any gc-action then pointers "visible" to both the caller(albeit expired) and callee would be correctly moved around.
I guess a "virtual" type as a head and members being an aliasing union could work well enough.
struct { StackVTab vtab; union { struct { TypeA *localA; TypeB *localB; ... }; void *rawPtrs[LOCALCOUNT]; }; } heapmembers;
As for closures that's trickier, locals visible to a nested function/closure needs to be moved to on-heap objects unless you do more or less recursive lifetime analysis (but that stuff quickly becomes expensive and/or indeterminate).