This can go really bad, for example in systems that keep caches/repositories of preallocated things for faster re-use. If they are anchored at global variables, or near global, then you need to treat those preallocated things special. You can't just go and move them every time even when knowing you will never collect them.
Generally, GC works better if you don't do tricks/optimizations with memory allocation and let just everything flow freely into the heap. If you do have to optimize allocation you generally have to teach your GC about your hack.
I'm kind of a fan of out-of-process, same-system caches for this reason.
I wonder how they decide which objects are rooted only by the stack. Is it part of the write barrier, or computed at mark time?
https://github.com/lua/lua/blob/6f1c033d72af8fe65bb67e17a242...