Cleanup & fix memory leaks.

This commit is contained in:
losfair 2019-06-27 01:04:59 +08:00
parent 63f9818cf6
commit f048dc2ff6
3 changed files with 46 additions and 59 deletions

View File

@ -329,10 +329,11 @@ impl InstanceImage {
#[cfg(all(unix, target_arch = "x86_64"))] #[cfg(all(unix, target_arch = "x86_64"))]
pub mod x64 { pub mod x64 {
use super::*; use super::*;
use crate::alternative_stack::run_on_alternative_stack; use crate::alternative_stack::{catch_unsafe_unwind, run_on_alternative_stack};
use crate::structures::TypedIndex; use crate::structures::TypedIndex;
use crate::types::LocalGlobalIndex; use crate::types::LocalGlobalIndex;
use crate::vm::Ctx; use crate::vm::Ctx;
use std::any::Any;
use std::ops::Bound::Excluded; use std::ops::Bound::Excluded;
pub fn new_machine_state() -> MachineState { pub fn new_machine_state() -> MachineState {
@ -345,25 +346,13 @@ pub mod x64 {
} }
} }
pub unsafe fn invoke_call_return_on_stack_raw_image(
msm: &ModuleStateMap,
code_base: usize,
image_raw: Vec<u8>,
vmctx: &mut Ctx,
) -> u64 {
use bincode::deserialize;
let image: InstanceImage = deserialize(&image_raw).unwrap();
drop(image_raw); // free up memory
invoke_call_return_on_stack(msm, code_base, image, vmctx)
}
#[warn(unused_variables)] #[warn(unused_variables)]
pub unsafe fn invoke_call_return_on_stack( pub unsafe fn invoke_call_return_on_stack(
msm: &ModuleStateMap, msm: &ModuleStateMap,
code_base: usize, code_base: usize,
image: InstanceImage, image: InstanceImage,
vmctx: &mut Ctx, vmctx: &mut Ctx,
) -> u64 { ) -> Result<u64, Box<dyn Any>> {
let mut stack: Vec<u64> = vec![0; 1048576 * 8 / 8]; // 8MB stack let mut stack: Vec<u64> = vec![0; 1048576 * 8 / 8]; // 8MB stack
let mut stack_offset: usize = stack.len(); let mut stack_offset: usize = stack.len();
@ -523,10 +512,12 @@ pub mod x64 {
drop(image); // free up host memory drop(image); // free up host memory
run_on_alternative_stack( catch_unsafe_unwind(|| {
stack.as_mut_ptr().offset(stack.len() as isize), run_on_alternative_stack(
stack.as_mut_ptr().offset(stack_offset as isize), stack.as_mut_ptr().offset(stack.len() as isize),
) stack.as_mut_ptr().offset(stack_offset as isize),
)
})
} }
pub fn build_instance_image( pub fn build_instance_image(

View File

@ -1,8 +1,7 @@
use crate::alternative_stack::begin_unsafe_unwind; use crate::alternative_stack::begin_unsafe_unwind;
use crate::import::{ImportObject, Namespace}; use crate::import::{ImportObject, Namespace};
use crate::trampoline::{CallContext, TrampolineBuffer, TrampolineBufferBuilder}; use crate::trampoline::{CallContext, TrampolineBufferBuilder};
use crate::vm::Ctx; use crate::vm::Ctx;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
static INTERRUPTED: AtomicBool = AtomicBool::new(false); static INTERRUPTED: AtomicBool = AtomicBool::new(false);
@ -19,40 +18,39 @@ pub fn get_and_reset_interrupted() -> bool {
INTERRUPTED.swap(false, Ordering::SeqCst) INTERRUPTED.swap(false, Ordering::SeqCst)
} }
struct ImportContext {
_trampolines: Rc<TrampolineBuffer>,
}
impl ImportContext {
fn new(trampolines: Rc<TrampolineBuffer>) -> ImportContext {
ImportContext {
_trampolines: trampolines,
}
}
}
pub fn patch_import_object(x: &mut ImportObject) { pub fn patch_import_object(x: &mut ImportObject) {
let mut builder = TrampolineBufferBuilder::new(); struct Intrinsics {
suspend: fn(&mut Ctx),
check_interrupt: fn(&mut Ctx),
}
let idx_suspend = lazy_static! {
builder.add_context_rsp_state_preserving_trampoline(suspend, ::std::ptr::null()); static ref INTRINSICS: Intrinsics = {
let idx_check_interrupt = let mut builder = TrampolineBufferBuilder::new();
builder.add_context_rsp_state_preserving_trampoline(check_interrupt, ::std::ptr::null()); let idx_suspend =
let trampolines = builder.build(); builder.add_context_rsp_state_preserving_trampoline(suspend, ::std::ptr::null());
let idx_check_interrupt = builder
.add_context_rsp_state_preserving_trampoline(check_interrupt, ::std::ptr::null());
let trampolines = builder.build();
let suspend_indirect: fn(&mut Ctx) = let ret = Intrinsics {
unsafe { ::std::mem::transmute(trampolines.get_trampoline(idx_suspend)) }; suspend: unsafe { ::std::mem::transmute(trampolines.get_trampoline(idx_suspend)) },
let check_interrupt_indirect: fn(&mut Ctx) = check_interrupt: unsafe {
unsafe { ::std::mem::transmute(trampolines.get_trampoline(idx_check_interrupt)) }; ::std::mem::transmute(trampolines.get_trampoline(idx_check_interrupt))
},
let trampolines = Rc::new(trampolines); };
::std::mem::forget(trampolines);
// FIXME: Memory leak! ret
::std::mem::forget(ImportContext::new(trampolines.clone())); };
}
let mut ns = Namespace::new(); let mut ns = Namespace::new();
ns.insert("suspend", func!(suspend_indirect));
ns.insert("check_interrupt", func!(check_interrupt_indirect)); let suspend_fn = INTRINSICS.suspend;
let check_interrupt_fn = INTRINSICS.check_interrupt;
ns.insert("suspend", func!(suspend_fn));
ns.insert("check_interrupt", func!(check_interrupt_fn));
x.register("wasmer_suspend", ns); x.register("wasmer_suspend", ns);
} }
@ -97,9 +95,8 @@ unsafe fn do_suspend(ctx: &mut Ctx, mut stack: *const u64) -> ! {
{ {
use colored::*; use colored::*;
eprintln!("\n{}", "Suspending instance.".green().bold()); eprintln!("{}", "Suspending instance.".green().bold());
} }
es_image.print_backtrace_if_needed();
build_instance_image(ctx, es_image) build_instance_image(ctx, es_image)
}; };

View File

@ -542,14 +542,13 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
let code_base = let code_base =
instance.module.runnable_module.get_code().unwrap().as_ptr() instance.module.runnable_module.get_code().unwrap().as_ptr()
as usize; as usize;
catch_unsafe_unwind(|| { invoke_call_return_on_stack(
invoke_call_return_on_stack( &msm,
&msm, code_base,
code_base, image,
image, instance.context_mut(),
instance.context_mut(), )
); .map(|_| ())
})
} else { } else {
catch_unsafe_unwind(|| start_raw(instance.context_mut())) catch_unsafe_unwind(|| start_raw(instance.context_mut()))
}; };