Hacker News new | ask | show | jobs
by ameliaquining 1676 days ago
Strictly speaking, Rust doesn't need this as a built-in language feature, because its design allows it to be implemented as a third-party library: https://docs.rs/bumpalo

The biggest problem is that there's some awkwardness around RAII; I'm not sure whether that could have been avoided with a different approach.

Of course, ideally you'd want it to be compatible with the standard-library APIs that allocate. This is implemented, but is not yet at the point where they're sure they won't want to make backwards-incompatible changes to it, so you can only use it on nightly. https://doc.rust-lang.org/stable/std/alloc/trait.Allocator.h...

Or are you suggesting that the choice of allocator should be dynamically scoped, so that allocations that occur while the bump allocator is alive automatically use it even if they're in code that doesn't know about it? I think it's not possible for that to be memory-safe; all allocations using the bump allocator need to know about its lifetime, so that they can be sure not to outlive it, which would cause use-after-free bugs. I'm assuming that Odin just makes the programmer responsible for this, and if they get it wrong then memory corruption might occur; for a memory-safe language like Rust, that's not acceptable.

1 comments

It actually is possible to have decoupled allocation in a memory safe way. We have an open proposal for this in [0], for Vale. TL;DR: Have some bits in the malloc header which instruct the language on which deallocator function to use.

I've never used Odin, so I don't know whether/how they'd keep it safe.

[0]: https://docs.google.com/document/d/1243br9VVluZN0ZD9MVKSQMAw...

Hmm. It seems the way this prevents use-after-free is by having the allocator's destructor check at runtime whether everything in it has already been dropped, and if not, abort the process. With bumpalo's default API (which seems to be designed to have the lowest possible per-allocation runtime overhead), that wouldn't work, because it deliberately doesn't keep track of whether the things in it have been dropped (and also because there's no header to store the bits in).

On the other hand, if you required an API along the lines of bumpalo::boxed, and also were willing to add a bit more runtime overhead on top of that (for the tracking bits and the allocation count), then this could be done in Rust as a third-party library. Each executable that transitively depended on it would have to opt in with #[global_allocator], though. Also, I personally would rather have an API where the compiler makes sure I don't screw this up, than one where the runtime crashes my program if I do; this is generally a common sentiment in Rust, and points towards a bumpalo-style API.