-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cranelift_jit
: the JITModule::free_memory
method should take &mut self
#9280
Comments
To illustrate why the workaround is annoying: it requires creating a #[derive(Clone)]
pub struct ModuleData(Arc<JITModule>);
impl Drop for ModuleData {
fn drop(&mut self) {
// get_mut returns None if we are not the last Arc, so the JITModule
// shouldn't be dropped yet.
let Some(module) = Arc::get_mut(&mut self.0) else {
return;
};
// If this fails we'd rather just return and leak some memory than
// panic.
let Ok(builder) =
JITBuilder::new(cranelift_module::default_libcall_names())
else {
return;
};
// Swap in an empty JITModule so that we can take ownership
// so that we can call `free_memory` on the old one.
// The new one hasn't allocated anything so it will just get dropped
// normally.
let mut other = JITModule::new(builder);
std::mem::swap(&mut other, module);
// SAFETY: We only give out functions that hold a ModuleData and
// therefore an Arc to this module. By `get_mut`, we know that we are
// the last Arc to this memory and hence it is safe to free its
// memory. New Arcs cannot have been created in the meantime because
// that requires access to the last Arc, which we know that we have.
unsafe { other.free_memory() };
}
} |
The canonical solution for this is wrapping let Some(module) = Arc::get_mut(&mut self.0) else {
return;
};
unsafe {
let module = ManuallyDrop::take(module);
module.free_memory();
} In this case given that |
Oh that sounds reasonable! Thanks! |
I've got it working. Feel free to close this, though it might still be useful. I'll leave that decision up to you. If you want this I'd be happy to attempt a PR. |
Currently, the
free_memory
method onJITModule
takesself
. This makes some sense, because the whole thing is then invalidated. However, it is preventing me from (easily) making a wrapper type that frees the memory on drop:The above is simplified from what I'm actually trying to do because the above is obviously unsafe. I was trying to do this:
where all functions that I give out would have a
MyJIT
, so that the memory automatically gets dropped once the last function that uses it would drop the memory.I can work around this by swapping in a new
JITModule
, but that doesn't seem ideal. Sincefree_memory
is alreadyunsafe
, I think it's alright to let it take&mut self
and allow people to build safe abstractions over it.The text was updated successfully, but these errors were encountered: