Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Well, with conservative-on-stack GC you lose the ability to do bump allocation in the nursery for all objects (since you can't update all roots when you tenure objects, so you can't move them, so you can't do two-space stop-and-copy), which is to my mind a pretty severe drawback.

You're right that you can do some optimizations such as reassociation of pointer arithmetic, but I'm not sure how much they matter in practice—I'd be quite surprised if they outweighed the advantage of being able to allocate in ~5 instructions [1].

That said, in a practical sense I'm certain the advantage of being able to use the mature optimizations in the LLVM JIT outweighs the disadvantages of having to use conservative GC (and as I understand Azul is working on precise GC support for LLVM). Given their constraints I think they did a great job.

[1] Edit: I've been informed that the fast path in JSC is around this for pulling a bin off the free list. I should be more precise: what I mean is that you can stay on the fast path more often. You can always allocate very quickly, only falling off the fast path if the nursery fills up. Of course, falling off a malloc fast path is rare anyhow, so this isn't likely to be that much of a difference in practice…



Both MPS and SBCL, which are Bartlett-style collectors, use bump pointer allocation. They divide the heap into pages, and bump allocate into pages. At collection time, when a page is the target of an ambiguous pointer, it is pinned and promoted in place. A pinned page is not used for allocation the next round. The downside is that unless the ambiguous pointers are transient, a page may be pinned and unusuable for allocation for awhile.


JavaScriptCore also has bump-pointer allocation, as mentioned by the post. We don't use it for all things but we think our tradeoff choices are pretty good.


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.


If you use a block a structured heap, which is convenient for other reasons (GHC uses one), you just leak parts of entire semispaces. :)


Not if you compact, which you can't (fully) do if you have stuck pointers in a conservative collector.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: