-
Notifications
You must be signed in to change notification settings - Fork 824
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
821 additions
and
23 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,4 +8,20 @@ authors = ["The Wasmer Engineering Team <[email protected]>"] | |
edition = "2018" | ||
|
||
[dependencies] | ||
wasmer-runtime-core = { path = "../runtime-core", version = "0.4.2" } | ||
wasmer-runtime-core = { path = "../runtime-core" } | ||
wasmer-clif-backend = { path = "../clif-backend", version = "0.4.2" } | ||
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.4.2", optional = true } | ||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.4.2", optional = true } | ||
|
||
[dev-dependencies] | ||
wabt = "0.7.4" | ||
criterion = "0.2" | ||
|
||
[features] | ||
clif = [] | ||
llvm = ["wasmer-llvm-backend"] | ||
singlepass = ["wasmer-singlepass-backend"] | ||
|
||
[[bench]] | ||
name = "metering_benchmark" | ||
harness = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
#[macro_use] | ||
extern crate criterion; | ||
|
||
use criterion::black_box; | ||
use criterion::{Benchmark, Criterion}; | ||
|
||
use wabt::wat2wasm; | ||
|
||
use wasmer_middleware_common::metering::Metering; | ||
use wasmer_runtime_core::vm::Ctx; | ||
use wasmer_runtime_core::{backend::Compiler, compile_with, imports, Func}; | ||
|
||
//export function add_to(x: i32, y: i32): i32 { | ||
// for(var i = 0; i < x; i++){ | ||
// if(i % 1 == 0){ | ||
// y += i; | ||
// } else { | ||
// y *= i | ||
// } | ||
// } | ||
// return y; | ||
//} | ||
static WAT: &'static str = r#" | ||
(module | ||
(type $t0 (func (param i32 i32) (result i32))) | ||
(type $t1 (func)) | ||
(func $add_to (export "add_to") (type $t0) (param $p0 i32) (param $p1 i32) (result i32) | ||
(local $l0 i32) | ||
block $B0 | ||
i32.const 0 | ||
set_local $l0 | ||
loop $L1 | ||
get_local $l0 | ||
get_local $p0 | ||
i32.lt_s | ||
i32.eqz | ||
br_if $B0 | ||
get_local $l0 | ||
i32.const 1 | ||
i32.rem_s | ||
i32.const 0 | ||
i32.eq | ||
if $I2 | ||
get_local $p1 | ||
get_local $l0 | ||
i32.add | ||
set_local $p1 | ||
else | ||
get_local $p1 | ||
get_local $l0 | ||
i32.mul | ||
set_local $p1 | ||
end | ||
get_local $l0 | ||
i32.const 1 | ||
i32.add | ||
set_local $l0 | ||
br $L1 | ||
unreachable | ||
end | ||
unreachable | ||
end | ||
get_local $p1) | ||
(func $f1 (type $t1)) | ||
(table $table (export "table") 1 anyfunc) | ||
(memory $memory (export "memory") 0) | ||
(global $g0 i32 (i32.const 8)) | ||
(elem (i32.const 0) $f1)) | ||
"#; | ||
|
||
static WAT_GAS: &'static str = r#" | ||
(module | ||
(type $t0 (func (param i32 i32) (result i32))) | ||
(type $t1 (func)) | ||
(type $t2 (func (param i32))) | ||
(import "env" "gas" (func $env.gas (type $t2))) | ||
(func $add_to (type $t0) (param $p0 i32) (param $p1 i32) (result i32) | ||
(local $l0 i32) | ||
i32.const 3 | ||
call $env.gas | ||
block $B0 | ||
i32.const 5 | ||
call $env.gas | ||
i32.const 0 | ||
set_local $l0 | ||
loop $L1 | ||
i32.const 18 | ||
call $env.gas | ||
get_local $l0 | ||
get_local $p0 | ||
i32.lt_s | ||
i32.eqz | ||
br_if $B0 | ||
get_local $l0 | ||
i32.const 1 | ||
i32.rem_s | ||
i32.const 0 | ||
i32.eq | ||
if $I2 | ||
i32.const 5 | ||
call $env.gas | ||
get_local $p1 | ||
get_local $l0 | ||
i32.add | ||
set_local $p1 | ||
else | ||
i32.const 5 | ||
call $env.gas | ||
get_local $p1 | ||
get_local $l0 | ||
i32.mul | ||
set_local $p1 | ||
end | ||
get_local $l0 | ||
i32.const 1 | ||
i32.add | ||
set_local $l0 | ||
br $L1 | ||
unreachable | ||
end | ||
unreachable | ||
end | ||
get_local $p1) | ||
(func $f2 (type $t1) | ||
i32.const 1 | ||
call $env.gas) | ||
(table $table 1 anyfunc) | ||
(memory $memory 0) | ||
(global $g0 i32 (i32.const 8)) | ||
(export "memory" (memory 0)) | ||
(export "table" (table 0)) | ||
(export "add_to" (func $add_to)) | ||
(elem (i32.const 0) $f2)) | ||
"#; | ||
|
||
#[cfg(feature = "llvm")] | ||
fn get_compiler(limit: u64, metering: bool) -> impl Compiler { | ||
use wasmer_llvm_backend::code::LLVMModuleCodeGenerator; | ||
use wasmer_runtime_core::codegen::{MiddlewareChain, StreamingCompiler}; | ||
let c: StreamingCompiler<LLVMModuleCodeGenerator, _, _, _, _> = | ||
StreamingCompiler::new(move || { | ||
let mut chain = MiddlewareChain::new(); | ||
if metering { | ||
chain.push(Metering::new(limit)); | ||
} | ||
chain | ||
}); | ||
|
||
c | ||
} | ||
|
||
#[cfg(feature = "singlepass")] | ||
fn get_compiler(limit: u64, metering: bool) -> impl Compiler { | ||
use wasmer_runtime_core::codegen::{MiddlewareChain, StreamingCompiler}; | ||
use wasmer_singlepass_backend::ModuleCodeGenerator as SinglePassMCG; | ||
let c: StreamingCompiler<SinglePassMCG, _, _, _, _> = StreamingCompiler::new(move || { | ||
let mut chain = MiddlewareChain::new(); | ||
if metering { | ||
chain.push(Metering::new(limit)); | ||
} | ||
chain | ||
}); | ||
c | ||
} | ||
|
||
#[cfg(not(any(feature = "llvm", feature = "clif", feature = "singlepass")))] | ||
fn get_compiler(_limit: u64, metering: bool) -> impl Compiler { | ||
panic!("compiler not specified, activate a compiler via features"); | ||
use wasmer_clif_backend::CraneliftCompiler; | ||
CraneliftCompiler::new() | ||
} | ||
|
||
#[cfg(feature = "clif")] | ||
fn get_compiler(_limit: u64, metering: bool) -> impl Compiler { | ||
panic!("cranelift does not implement metering"); | ||
use wasmer_clif_backend::CraneliftCompiler; | ||
CraneliftCompiler::new() | ||
} | ||
|
||
fn gas(ctx: &mut Ctx, gas_amount: u32) { | ||
use wasmer_middleware_common::metering; | ||
let used = metering::get_points_used_ctx(ctx); | ||
metering::set_points_used_ctx(ctx, used + u64::from(gas_amount)); | ||
() | ||
} | ||
|
||
fn bench_metering(c: &mut Criterion) { | ||
use wasmer_middleware_common::metering; | ||
|
||
c.bench( | ||
"Meter", | ||
Benchmark::new("No Metering", |b| { | ||
let compiler = get_compiler(0, false); | ||
let wasm_binary = wat2wasm(WAT).unwrap(); | ||
let module = compile_with(&wasm_binary, &compiler).unwrap(); | ||
let import_object = imports! {}; | ||
let mut instance = module.instantiate(&import_object).unwrap(); | ||
let add_to: Func<(i32, i32), i32> = instance.func("add_to").unwrap(); | ||
b.iter(|| black_box(add_to.call(100, 4))) | ||
}) | ||
.with_function("Gas Metering", |b| { | ||
let compiler = get_compiler(0, false); | ||
let gas_wasm_binary = wat2wasm(WAT_GAS).unwrap(); | ||
let gas_module = compile_with(&gas_wasm_binary, &compiler).unwrap(); | ||
let gas_import_object = imports! { | ||
"env" => { | ||
"gas" => Func::new(gas), | ||
}, | ||
}; | ||
let mut gas_instance = gas_module.instantiate(&gas_import_object).unwrap(); | ||
let gas_add_to: Func<(i32, i32), i32> = gas_instance.func("add_to").unwrap(); | ||
b.iter(|| black_box(gas_add_to.call(100, 4))) | ||
}) | ||
.with_function("Built-in Metering", |b| { | ||
let metering_compiler = get_compiler(std::u64::MAX, true); | ||
let wasm_binary = wat2wasm(WAT).unwrap(); | ||
let metering_module = compile_with(&wasm_binary, &metering_compiler).unwrap(); | ||
let metering_import_object = imports! {}; | ||
let mut metering_instance = metering_module | ||
.instantiate(&metering_import_object) | ||
.unwrap(); | ||
metering::set_points_used(&mut metering_instance, 0u64); | ||
let metering_add_to: Func<(i32, i32), i32> = metering_instance.func("add_to").unwrap(); | ||
b.iter(|| black_box(metering_add_to.call(100, 4))) | ||
}), | ||
); | ||
} | ||
|
||
criterion_group!(benches, bench_metering); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] | ||
|
||
pub mod call_trace; | ||
pub mod metering; |
Oops, something went wrong.