A simple solution is to explicitly store the type of each stack entry. Then you do not need a stack card; if the type is a "reference", then the entry is the root of the GC. This approach is especially convenient for debugging, as you can easily display the (typed) contents of the stack.
If you really want to use stack cards, a simple solution is to create a stack card for each instruction. You do this by tracking the contents of the stack during compilation or by performing a second pass on compiled instructions. Then, when searching for GC roots, for each frame on the stack, you use the card that comes with the current instruction.
Russell Zahniser
source share