5 ms·
Because of i386. i386 has not enough registers to be able to efficiently divide them into pointer-only and non-pointer-only. For stack case it is often worthwhi
by dfox 16y ago
Because of i386. i386 has not enough registers to be able to efficiently divide them into pointer-only and non-pointer-only. For stack case it is often worthwhile to use calling convention reasonably similar to what C/OS uses, but examining that mess is not practical for GC, so it's better to just scan stack conservatively (which is by the way done by many other generational GCs).
Edit: also you can implement conservative scan of stack and registers on Unix without writing single line of assembly code by scanning result of getcontext(), or even almost completely portably by scanning result of setjmp() + some heuristics for finding stack in memory.
- kingkilr 16y agoIt's still possible, PyPy for example post-processes the assembly in the generated binary in order to identify registers that can contain GC pointers (ones into the heap).
- ssp 16y ago.NET is statically typed though, so it's possible to make a static determination at each GC point which registers and stack locations contain pointers.
- dfox 16y agoPossible, but probably not practical. And especially in case of .NET which offers pretty tight integration with unmanaged code, you can have various stack frames with layout completely out of your control on stack (I'm not sure whenever such stack frames must be scanned for pointers, but they will certainly complicate any attempts to analyze stack structure).
- ssp 16y agoPossible, but probably not practical. It has certainly been done in various Java implementations. HotSpot I'm pretty sure does precise garbage collection. Native stacks don't need to be scanned for pointers, but the VM must of course keep track of which parts of the stack are native.
- barrkel 16y agoWhat you do is stop the world for a moment, set a GC due flag, and then wait for threads to come to GC-safe points. At GC safe points, the set of live registers and stack locations is definitely known.
- dfox 16y agoThis does not work when you can have threads executing arbitrary native code, that can do some non-GC related work for essentially unbounded time, which is certainly case with .NET. In JVM any native code tends to be prepared to cope with this somehow, but .NET is explicitly designed to be able to seamlessly interoperate with random COM and legacy native libraries, so you cannot guarantee that such native code will get back to GC safe point in any bounded amount of time. Edit: you can do stop-the-world GC at any point of program whan you scan stack conservatively, GC-safe points are only needed for precise scanning of stack and registers, so this is problem only when you want to be fully precise. Fully precise GC is certainly better when it is possible, but conservative scan works mostly well enough.
- barrkel 16y agoArbitrary native code is just fine - all you need to do is catch it when it returns back into the CLR. Native code can't (legally) have access to any managed memory that isn't already pinned. Since you (by you, I mean the CLR) control the call point to native code, you control the return point too - you can patch the instructions after the call if necessary.
- thedigitalengel 16y agoWhat happens if the native code enters, say, an infinite loop?
- ssp 16y agoYou can just consider native code a GC point. When executing native code, the registers don't need to be scanned, and you can keep track of what parts of the stack are native by noting the state of the stack before entering the native code.
- barrkel 16y agoThe rule with .NET is that any pointers passed out into native code needs to be pinned (so it won't move) with unsafe code (fixed statement in C#) or accessed via a GCHandle.
- dumael 16y agoEh, as long as you know/control the calling convention and control the compiler you can produce stack maps which allow you to identify pointers.