A simple solution is to explicitly store the type of each stack entry. Then you don't need a stack map; if the type is "reference" then the entry is a GC root. This approach is particularly handy for debugging, because you can easily display the (typed) contents of the stack.
If you really want to use stack maps, a simple solution is to generate a stack map to go with every instruction. You do this by keeping track of the stack contents while compiling, or by taking a second pass over the compiled instructions. Then when looking for GC roots, for each frame on the stack, you use the map that goes with the current instruction.