One trick you can use (which Chromium+Oilpan uses) is to only GC in between turns of the event loop. In that case, your set of roots is exactly equal to the accessible global variables plus everything accessible from the DOM (including event handlers). In particular, nothing is on the stack, so there is no need to introspect stack frames.