Best approach for memory management in a compiler

Hi,

I have a compiler project in C that I would like to port to Rust. My current compiler uses custom memory allocator. The strategy I use is that all memory is allocated by a pooling allocator, and then freed at once when the compiler is done. There is no intermediate freeing of memory. How can I best implement this in Rust?

Thanks and Regards
Dibyendu

You may want to use a crate like bumpalo.

1 Like

I see. Is there anything in the standard library that I can use?

You can also write a custom memory allocator for Rust that does the same

Fyi, the rustc uses Rust's plain'ol global allocators with jemalloc impl and does perform intermediate freeing when needed. I agree managing allocations in C is painful, but in Rust it's smooth as bread and butter due to the ownership semantics. Why don't you follow the practice of the rustc?

In general, this strategy will be a bit harder to take advantage of in Rust. In C, you can just never worry about use-after-free. But in Rust, the compiler does the worrying for you, so you can't avoid it as easily. That doesn't mean we can't ask Rust to explicitly ignore it, though!

I don't think changing the global allocator will really fix this problem, as that's a behind-the-scenes change. Rust types will still think in terms of ownership.


With that said, what about using explicit leak methods? Box::leak turns an allocated box into a static reference which you can copy around and will last forever.

Vec::leak is unstable, but vec.into_boxed_slice().leak() will have the exact same effect: you just leak the memory, and then get a permanent reference to it.

Since most allocations in rust are either Vecs or Boxs, I think using this everywhere should be fairly reasonable. If you need shared mutability, then just use a Box<RefCell<...>>, and leak that to get &'static RefCell<...> which you can mutate from multiple places.

This way you'll be able to still get Rust's safety, while having the freedom of leak-based memory management.

Another alternative might be to use an arena, like typed-arena. This would be slightly more expensive, and you'd have to keep track of the arena everywhere, but you would be able to free everything in one go without ending the program. If you want to avoid actually leaking memory, this might be a good idea.

I'd argue doing this, but in a one-thing-at-a-time kind of way. First, migrate from C to Rust, keeping the same memory strategy. Second, start switching from leaking to ownership by just not leaking boxes.

Rust's compile-time checks make refactoring quite nice, so moving things one at a time from Box::leak to just storing Boxes should be pretty possible.

2 Likes

Thank you for the feedback. I will look at the various options suggested.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.