From 80f824e7080ca6339de9ec5c391a17a00d85e86d Mon Sep 17 00:00:00 2001 From: losfair Date: Wed, 26 Feb 2020 01:45:11 +0800 Subject: [PATCH] Auto-release trampolines. --- lib/runtime-core/src/typed_func.rs | 32 ++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 6a3558f6d..152302bf4 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -360,11 +360,25 @@ impl<'a> ErasedFunc<'a> { (signature.params().len() + 1) as u32, // +vmctx ); let ptr = builder - .append_global() + .insert_global() .expect("cannot bump-allocate global trampoline memory"); + struct AutoRelease { + ptr: NonNull, + } + + impl Drop for AutoRelease { + fn drop(&mut self) { + unsafe { + TrampolineBufferBuilder::remove_global(self.ptr); + } + } + } + + impl Kind for AutoRelease {} + ErasedFunc { - inner: Box::new(Host(())), + inner: Box::new(AutoRelease { ptr }), func: ptr.cast::(), func_env: None, vmctx: ptr::null_mut(), @@ -941,4 +955,18 @@ mod tests { }, }; } + + #[test] + fn test_many_new_polymorphics() { + use crate::types::{FuncSig, Type}; + + // Check that generating a lot (1M) of polymorphic functions doesn't use up the executable buffer. + for _ in 0..1000000 { + let arglist = vec![Type::I32; 100]; + ErasedFunc::new_polymorphic( + Arc::new(FuncSig::new(arglist, vec![Type::I32])), + |_, _| unreachable!(), + ); + } + } }