Right, I specifically mentioned two-space collection for this reason (though I guess I should have been more precise that it doesn't forbid bump pointer allocation, just means you may leak entire semispaces for a while).
The most common incarnation of Bartlett is a semispace mostly-copying collector with bump pointer allocation. You never leak a whole space. The only requirement is that the spaces are a discontiguous bag of pages. Note that in proper GC terminology this is the right way to say it - a space is not a contiguous region but rather an abstract bag of heap locations, though usually it's a bag of very large pages, like 64KB in WebKit. You'd want discontiguous spaces anyway if you want to support dynamic heap growing/shrinking or other features like pinning (for fast FFI), etc. It's usually only either academic collectors, or collectors in one-VM-per-process systems like server VMs, that can even afford to make a space be a contiguous region of virtual memory. So, Bartlett ends up incurring zero net overhead for embeddable VM environments like a browser engine.
Presumably you still leak individual pages if you have stuck stack pointers though?
I guess around turns of the event loop you can probably get precise compaction though, since nothing's on the stack.
Edit: I didn't think that it was correct that all production-quality semispaces are scattered throughout the address space and indeed it's not (though I probably misunderstood you): SpiderMonkey uses a contiguous-in-memory nursery.