change Module::define_function to take TrapSink instances

Experience with the `define_function` API has shown that returning
borrowed slices of `TrapSite` is not ideal: the returned slice
represents a borrow on the entire `Module`, which makes calling back
into methods taking `&mut self` a bit tricky.

To eliminate the problem, let's require the callers of `define_function`
to provide `TrapSink` instances.  This style of API enables them to
control when and how traps are collected, and makes the `object` and
`faerie` backends simpler/more efficient by not having to worry about
trap collection.
This commit is contained in:
Nathan Froyd
2020-03-24 09:46:25 -04:00
parent 222a73c150
commit dcabb55776
11 changed files with 97 additions and 272 deletions

View File

@@ -1,4 +1,5 @@
use cranelift::prelude::*;
use cranelift_codegen::binemit::NullTrapSink;
use cranelift_module::{default_libcall_names, Linkage, Module};
use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
use std::mem;
@@ -38,7 +39,10 @@ fn main() {
bcx.seal_all_blocks();
bcx.finalize();
}
module.define_function(func_a, &mut ctx).unwrap();
let mut trap_sink = NullTrapSink {};
module
.define_function(func_a, &mut ctx, &mut trap_sink)
.unwrap();
module.clear_context(&mut ctx);
ctx.func.signature = sig_b;
@@ -60,7 +64,9 @@ fn main() {
bcx.seal_all_blocks();
bcx.finalize();
}
module.define_function(func_b, &mut ctx).unwrap();
module
.define_function(func_b, &mut ctx, &mut trap_sink)
.unwrap();
module.clear_context(&mut ctx);
// Perform linking.

View File

@@ -2,13 +2,13 @@
use crate::memory::Memory;
use cranelift_codegen::binemit::{
Addend, CodeOffset, NullTrapSink, Reloc, RelocSink, Stackmap, StackmapSink,
Addend, CodeOffset, Reloc, RelocSink, Stackmap, StackmapSink, TrapSink,
};
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::{self, ir, settings};
use cranelift_module::{
Backend, DataContext, DataDescription, DataId, FuncId, Init, Linkage, ModuleNamespace,
ModuleResult, TrapSite,
ModuleResult,
};
use cranelift_native;
#[cfg(not(windows))]
@@ -271,14 +271,18 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
// Nothing to do.
}
fn define_function(
fn define_function<TS>(
&mut self,
_id: FuncId,
name: &str,
ctx: &cranelift_codegen::Context,
_namespace: &ModuleNamespace<Self>,
code_size: u32,
) -> ModuleResult<(Self::CompiledFunction, &[TrapSite])> {
trap_sink: &mut TS,
) -> ModuleResult<Self::CompiledFunction>
where
TS: TrapSink,
{
let size = code_size as usize;
let ptr = self
.memory
@@ -289,28 +293,22 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
self.record_function_for_perf(ptr, size, name);
let mut reloc_sink = SimpleJITRelocSink::new();
// Ignore traps for now. For now, frontends should just avoid generating code
// that traps.
let mut trap_sink = NullTrapSink {};
let mut stackmap_sink = SimpleJITStackmapSink::new();
unsafe {
ctx.emit_to_memory(
&*self.isa,
ptr,
&mut reloc_sink,
&mut trap_sink,
trap_sink,
&mut stackmap_sink,
)
};
Ok((
Self::CompiledFunction {
code: ptr,
size,
relocs: reloc_sink.relocs,
},
&[],
))
Ok(Self::CompiledFunction {
code: ptr,
size,
relocs: reloc_sink.relocs,
})
}
fn define_function_bytes(
@@ -319,8 +317,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
name: &str,
bytes: &[u8],
_namespace: &ModuleNamespace<Self>,
_traps: Vec<TrapSite>,
) -> ModuleResult<(Self::CompiledFunction, &[TrapSite])> {
) -> ModuleResult<Self::CompiledFunction> {
let size = bytes.len();
let ptr = self
.memory
@@ -334,14 +331,11 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, size);
}
Ok((
Self::CompiledFunction {
code: ptr,
size,
relocs: vec![],
},
&[],
))
Ok(Self::CompiledFunction {
code: ptr,
size,
relocs: vec![],
})
}
fn define_data(

View File

@@ -1,3 +1,4 @@
use cranelift_codegen::binemit::NullTrapSink;
use cranelift_codegen::ir::*;
use cranelift_codegen::isa::CallConv;
use cranelift_codegen::{ir::types::I16, Context};
@@ -46,7 +47,10 @@ fn define_simple_function(module: &mut Module<SimpleJITBackend>) -> FuncId {
bcx.ins().return_(&[]);
}
module.define_function(func_id, &mut ctx).unwrap();
let mut trap_sink = NullTrapSink {};
module
.define_function(func_id, &mut ctx, &mut trap_sink)
.unwrap();
func_id
}
@@ -191,7 +195,10 @@ fn libcall_function() {
bcx.ins().return_(&[]);
}
module.define_function(func_id, &mut ctx).unwrap();
let mut trap_sink = NullTrapSink {};
module
.define_function(func_id, &mut ctx, &mut trap_sink)
.unwrap();
module.finalize_definitions();
}