Retrofitting legacy code with custom allocator

Hi All,

I am trying to automatically change allocator for some standard library containers in an existing codebase. For example, I have identified some Vec that I want to change its initialization from Vec::new to Vec::new_in(CustomAlloc). I have two proposals here.

  1. Do it at the source code level. Change the allocation site. And also rewrite all functions/struct that might use it to be allocator generic. For example, from fn f(x:Vec<T>) to fn f<A:Allocator>(x:Vec<T, A>).
  2. Do it at the MIR level. Add a MIR pass that modifies the type of all relevant Vec<T> to be Vec<T, CustomAlloc>.

Both seem laborious. Is there a more lightweight approach here?

1 Like

Did you consider replacing global allocator? If not, and you want to do more nuanced replacement, there will be some labour involved one way or another.

Perhaps, it will be sufficient to have a typedef, accompanied with a use declaration in each file.

// my_alloc.rs
pub type Vec<T> = std::vec::Vec<T, CustomAllocator>;

// some.rs
use my_alloc::Vec;

I believe one can replace macros like vec![] in a similar way.

2 Likes

Thanks for the reply! But the more tricky thing here is that, I only want to modify the allocator for some Vec, but not all. With a typedef, I still need to change all the following type annotations.

I am wondering if is there any method at the MIR level to track down where the vec is used and change the Vec with Vec::new_in() with a specific allocator.

If you want to change only some Vec based on some heirustic, unless you are able to express that via code (e.g. "change all uses in this module"), there's no real way to get around the fact that you will have to evaluate every single vec to see which allocator it should use.

1 Like