Metering for LLVM.

This commit is contained in:
losfair
2019-05-31 15:36:08 +08:00
parent fd8675324c
commit b834b4ff36
6 changed files with 138 additions and 24 deletions

View File

@ -113,6 +113,8 @@ pub struct Intrinsics {
pub memory_size_static_import: FunctionValue,
pub memory_size_shared_import: FunctionValue,
pub breakpoint: FunctionValue,
pub throw_trap: FunctionValue,
pub ctx_ptr_ty: PointerType,
@ -163,7 +165,7 @@ impl Intrinsics {
let stack_lower_bound_ty = i8_ty;
let memory_base_ty = i8_ty;
let memory_bound_ty = void_ty;
let internals_ty = void_ty;
let internals_ty = i64_ty;
let local_function_ty = i8_ptr_ty;
let anyfunc_ty = context.struct_type(
@ -250,6 +252,8 @@ impl Intrinsics {
let ret_i1_take_i1_i1 = i1_ty.fn_type(&[i1_ty_basic, i1_ty_basic], false);
let ret_i32_take_ctx_i64_i32 = i32_ty.fn_type(&[ctx_ptr_ty.as_basic_type_enum(), i64_ty_basic, i32_ty_basic], false);
Self {
ctlz_i32: module.add_function("llvm.ctlz.i32", ret_i32_take_i32_i1, None),
ctlz_i64: module.add_function("llvm.ctlz.i64", ret_i64_take_i64_i1, None),
@ -382,6 +386,11 @@ impl Intrinsics {
ret_i32_take_ctx_i32,
None,
),
breakpoint: module.add_function(
"vm.breakpoint",
ret_i32_take_ctx_i64_i32,
None,
),
throw_trap: module.add_function(
"vm.exception.trap",
void_ty.fn_type(&[i32_ty_basic], false),
@ -432,6 +441,7 @@ pub struct CtxType<'a> {
cached_tables: HashMap<TableIndex, TableCache>,
cached_sigindices: HashMap<SigIndex, IntValue>,
cached_globals: HashMap<GlobalIndex, GlobalCache>,
cached_internals: HashMap<usize, PointerValue>,
cached_imported_functions: HashMap<ImportedFuncIndex, ImportedFuncCache>,
_phantom: PhantomData<&'a FunctionValue>,
@ -457,6 +467,7 @@ impl<'a> CtxType<'a> {
cached_tables: HashMap::new(),
cached_sigindices: HashMap::new(),
cached_globals: HashMap::new(),
cached_internals: HashMap::new(),
cached_imported_functions: HashMap::new(),
_phantom: PhantomData,
@ -680,6 +691,33 @@ impl<'a> CtxType<'a> {
})
}
pub fn internal_pointer(&mut self, index: usize, intrinsics: &Intrinsics) -> PointerValue {
let (cached_internals, ctx_ptr_value, _info, cache_builder) = (
&mut self.cached_internals,
self.ctx_ptr_value,
self.info,
&self.cache_builder,
);
*cached_internals.entry(index).or_insert_with(|| {
let array_ptr_ptr = unsafe {
cache_builder.build_struct_gep(
ctx_ptr_value,
offset_to_index(Ctx::offset_internals()),
"internals_array_ptr_ptr",
)
};
let array_ptr = cache_builder.build_load(array_ptr_ptr, "internals_array_ptr").into_pointer_value();
let const_index = intrinsics.i32_ty.const_int(index as u64, false);
unsafe {
cache_builder.build_in_bounds_gep(
array_ptr,
&[const_index],
"element_ptr",
)
}
})
}
pub fn global_cache(&mut self, index: GlobalIndex, intrinsics: &Intrinsics) -> GlobalCache {
let (cached_globals, ctx_ptr_value, info, cache_builder) = (
&mut self.cached_globals,