Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add benchmarks #1660

Closed
wants to merge 87 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
94a2845
Implement trap info in Lightbeam
eira-fransham Jan 15, 2020
4a8b081
Start using wasm-reader instead of wasmparser for parsing operators
eira-fransham Jan 21, 2020
059a1dc
Update to use wasm-reader, some reductions in allocation, support sou…
eira-fransham Jan 28, 2020
776532c
Error when running out of registers (although we'd hope it should be …
eira-fransham Feb 10, 2020
e4a4ed2
WIP: Update Lightbeam to work with latest Wasmtime
eira-fransham Feb 20, 2020
1b2234a
WIP: Update Lightbeam to use current wasmtime
eira-fransham Feb 20, 2020
0cd0f3a
WIP: Migrate to new system for builtin functions
eira-fransham Feb 21, 2020
a67011b
WIP: Update Lightbeam to work with latest Wasmtime
eira-fransham Feb 27, 2020
b264189
Remove multi_mut
eira-fransham Feb 27, 2020
39824b1
Format
eira-fransham Feb 27, 2020
59a574b
Fix some bugs around arguments, add debuginfo offset tracking
eira-fransham Mar 4, 2020
f1ca383
Complete integration with new Wasmtime
eira-fransham Mar 5, 2020
d7eda3c
Remove commented code
eira-fransham Mar 5, 2020
148aae2
Fix formatting
eira-fransham Mar 5, 2020
3d5abbb
Fix warnings, remove unused dependencies
eira-fransham Mar 13, 2020
a451d59
Fix `iter` if there are too many elements, fix compilation for latest…
eira-fransham Mar 13, 2020
c28386f
Fix float arguments on stack
eira-fransham Mar 24, 2020
f714e19
Remove wasm-reader and trap info work
eira-fransham Mar 27, 2020
85e7765
Allocate stack space _before_ passing arguments, fail if we can't zer…
eira-fransham Mar 30, 2020
a03cf77
Fix stack argument offset calculation
eira-fransham Mar 30, 2020
6ed4828
Fix stack arguments in Lightbeam
eira-fransham Mar 30, 2020
b539f1f
Re-add WASI because it somehow got removed during rebase
eira-fransham Mar 31, 2020
583c18c
Update lockfile
eira-fransham Mar 31, 2020
34c70e2
Workaround for apparent `type_alias_impl_trait`-related bug in rustdoc
eira-fransham Mar 31, 2020
0a464b2
Implement trap info
eira-fransham Mar 31, 2020
cb365c7
Add stress test to testsuite and fix bugs related to it
eira-fransham Apr 9, 2020
533d53f
Merge different branch kinds in order to squish bugs in `BrTable`
eira-fransham Apr 15, 2020
310d56a
Slight refactor and avoid allocating new stack space after passing bl…
eira-fransham Apr 16, 2020
7667a4d
Fix bugs that were found by combining branch types
eira-fransham Apr 23, 2020
aa97072
Implement trap info in Lightbeam
eira-fransham Jan 15, 2020
095473f
Start using wasm-reader instead of wasmparser for parsing operators
eira-fransham Jan 21, 2020
6330b9d
Update to use wasm-reader, some reductions in allocation, support sou…
eira-fransham Jan 28, 2020
79e6c18
Error when running out of registers (although we'd hope it should be …
eira-fransham Feb 10, 2020
233e1d0
WIP: Update Lightbeam to work with latest Wasmtime
eira-fransham Feb 20, 2020
ec0e0b1
WIP: Update Lightbeam to use current wasmtime
eira-fransham Feb 20, 2020
d77b28a
WIP: Migrate to new system for builtin functions
eira-fransham Feb 21, 2020
a7d2e92
WIP: Update Lightbeam to work with latest Wasmtime
eira-fransham Feb 27, 2020
43cda86
Remove multi_mut
eira-fransham Feb 27, 2020
467b474
Format
eira-fransham Feb 27, 2020
3e27fdc
Fix some bugs around arguments, add debuginfo offset tracking
eira-fransham Mar 4, 2020
5e7eeee
Complete integration with new Wasmtime
eira-fransham Mar 5, 2020
6310b7c
Remove commented code
eira-fransham Mar 5, 2020
a721747
Fix formatting
eira-fransham Mar 5, 2020
47bac64
Fix warnings, remove unused dependencies
eira-fransham Mar 13, 2020
e21ab92
Fix `iter` if there are too many elements, fix compilation for latest…
eira-fransham Mar 13, 2020
fe874a0
Fix float arguments on stack
eira-fransham Mar 24, 2020
be128e4
Remove wasm-reader and trap info work
eira-fransham Mar 27, 2020
7cb74a7
Allocate stack space _before_ passing arguments, fail if we can't zer…
eira-fransham Mar 30, 2020
b9454c0
Fix stack argument offset calculation
eira-fransham Mar 30, 2020
e6a6cb2
Fix stack arguments in Lightbeam
eira-fransham Mar 30, 2020
ce42e9a
Re-add WASI because it somehow got removed during rebase
eira-fransham Mar 31, 2020
2e02408
Workaround for apparent `type_alias_impl_trait`-related bug in rustdoc
eira-fransham Mar 31, 2020
bdb68aa
Fix breakages caused by rebase, remove module offset info as it is un…
eira-fransham Apr 23, 2020
d88da37
Add TODO comment explaining `lightbeam::ModuleContext` trait
eira-fransham Apr 23, 2020
07902e0
Merge bytecodealliance/wasmtime master
eira-fransham Apr 23, 2020
2b10bd7
Fix bug with locals
eira-fransham Apr 23, 2020
34877d1
Some fixes, remove unused code, add (currently unused) stack allocati…
eira-fransham Apr 29, 2020
ce58357
Fix some assertions and allow panic-on-error in debug mode for errors…
eira-fransham Apr 29, 2020
4ef8a80
Slight formatting change
eira-fransham May 4, 2020
9d251a6
Make clippy happy
eira-fransham May 5, 2020
a1bada4
Add benchmarks
eira-fransham May 5, 2020
432b31a
Add benchmarks
eira-fransham May 5, 2020
90b8463
Revert change to disable verifier when debug_assertions are disabled
eira-fransham May 6, 2020
b0982f0
Fix issue caused by merge with master
eira-fransham May 6, 2020
92dac2b
Merge branch 'master' into stress-test
eira-fransham May 6, 2020
6e5adc7
WIP: Start using proper stack allocation subsystem
eira-fransham May 11, 2020
87676ac
Fix stack allocation, fully implement "adaptor blocks" for when we ne…
eira-fransham May 14, 2020
1ca3030
Try to reimplement trap info since a wasmtime change broke it
eira-fransham Jun 11, 2020
58ed9d8
Merge remote-tracking branch 'forked/master' into stress-test
eira-fransham Jun 11, 2020
8e6dfdb
Fix warnings, error on multiple return
eira-fransham Jun 12, 2020
19e5180
Merge remote-tracking branch 'forked/master' into stress-test
eira-fransham Jun 12, 2020
d61cf21
Roll spec testsuite back since the latest version tests that modules …
eira-fransham Jun 12, 2020
804fc40
Implement more extending conversions, remove limit on return count
eira-fransham Jun 12, 2020
f02e18b
WIP: Add stack returns so that the new tests pass
eira-fransham Jun 18, 2020
25dda53
WIP: Fix multi-return
eira-fransham Jun 23, 2020
69c57cd
Fix some pretty egregious mistakes in calling convention generation t…
eira-fransham Jul 1, 2020
f4ace0a
Merge remote-tracking branch 'forked/master' into stress-test
eira-fransham Jul 1, 2020
825d3f7
Fix call_indirect to work with new vmctx
eira-fransham Jul 27, 2020
2de9176
Fix test failures
eira-fransham Aug 17, 2020
dcacfb8
Optimize host function call
arkpar Apr 29, 2020
bea47d7
Removed shared VMInterrupts
arkpar May 16, 2020
8aaae88
Fixed windows build
arkpar May 19, 2020
3207302
Fix compilation failure, disable disassembly
eira-fransham Aug 19, 2020
2a19b8f
Add handle method
eira-fransham Aug 21, 2020
e532b7c
WIP: Roll testsuite back
eira-fransham Sep 9, 2020
6c2cb02
Roll testsuite back
eira-fransham Sep 9, 2020
e0ea20b
Update dependencies
eira-fransham Sep 16, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
423 changes: 206 additions & 217 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@ tempfile = "3.1.0"
test-programs = { path = "crates/test-programs" }
wasmtime-fuzzing = { path = "crates/fuzzing" }
wasmtime-runtime = { path = "crates/runtime" }
wast = "14.0.0"

[build-dependencies]
anyhow = "1.0.19"

[profile.release.build-override]
opt-level = 0
[profile.release]
lto = true
codegen-units = 1
panic = "abort"

[workspace]
members = [
Expand All @@ -73,6 +76,7 @@ members = [

[features]
default = ["jitdump", "wasmtime/wat"]
benches = []
lightbeam = [
"wasmtime-environ/lightbeam",
"wasmtime-jit/lightbeam",
Expand Down
278 changes: 278 additions & 0 deletions benches/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
#![cfg(feature = "benches")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to use a hand-rolled harness = false scheme or something like criterion that works on stable?

#![feature(test)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this file be renamed to perhaps spec.rs or something that indicates that it's benchmarking the spec test suite?

FWIW the spec test suite I don't think is really the most interesting of benchmarks, but at least for our own internal tracking and performance monitoring it probably isn't so bad to track!


extern crate test;

use anyhow::{bail, Context as _, Result};
use std::path::Path;
use wasmtime::{Config, Engine, OptLevel, Store, Strategy};
use wasmtime_wast::WastContext;
use wast::{
parser::{self, ParseBuffer},
Wat,
};

macro_rules! mk_test {
($(#[$attrs:meta])* $name:ident, $path:expr, $strategy:expr) => {
mod $name {
use wasmtime::Strategy;

#[bench]
$(#[$attrs])*
fn compile(b: &mut ::test::bench::Bencher) {
crate::bench_compile(b, $path, $strategy).unwrap();
}

#[bench]
$(#[$attrs])*
fn run(b: &mut ::test::bench::Bencher) {
crate::bench_run(b, $path, $strategy).unwrap();
}
}
};
}

include!(concat!(env!("OUT_DIR"), "/wast_testsuite_tests.rs"));

fn bench_compile(b: &mut test::bench::Bencher, wast: &str, strategy: Strategy) -> Result<()> {
let path = Path::new(wast);

let simd = path.iter().any(|s| s == "simd");

let bulk_mem = path.iter().any(|s| s == "bulk-memory-operations");

// Some simd tests assume support for multiple tables, which are introduced
// by reference types.
let reftypes = simd || path.iter().any(|s| s == "reference-types");

let multi_val = path.iter().any(|s| s == "multi-value");

let mut cfg = Config::new();
cfg.wasm_simd(simd)
.wasm_bulk_memory(bulk_mem)
.wasm_reference_types(reftypes)
.wasm_multi_value(multi_val)
.strategy(strategy)?
.cranelift_debug_verifier(cfg!(debug_assertions));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This I think is duplicated with the testing code as well as with the function below, could this all be consolidated into one function, perhaps in the wasmtime-wast crate itself?


// FIXME: https://github.com/bytecodealliance/wasmtime/issues/1186
if simd {
cfg.cranelift_opt_level(OptLevel::None);
}

let store = Store::new(&Engine::new(&cfg));
let mut wast_context = WastContext::new(store);
wast_context.register_spectest()?;

let adjust_wast = |mut err: wast::Error| {
err.set_path(path);
err.set_text(wast);
err
};

let file_contents = std::fs::read_to_string(path)
.with_context(|| format!("failed to read `{}`", path.display()))?;
let buf = ParseBuffer::new(&file_contents).map_err(adjust_wast)?;
let ast = parser::parse::<wast::Wast>(&buf).map_err(adjust_wast)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be deduplicated with the wasmtime-wast crate? Perhaps something where a function to handle each directive is provided and then we say "run this file", or something like that?


let mut modules = Vec::new();

for directive in ast.directives {
use wast::WastDirective::*;

match directive {
Module(mut module) => {
let binary = module.encode()?;

wast_context.module(
module.id.map(|s| &s.name()[..]).as_ref().map(|s| &s[..]),
&binary,
)?;

b.bytes += binary.len() as u64;
modules.push(binary);
}
QuoteModule { span: _, source } => {
let mut module = String::new();
for src in source {
module.push_str(std::str::from_utf8(src)?);
module.push_str(" ");
}
let buf = ParseBuffer::new(&module)?;
let mut wat = parser::parse::<Wat>(&buf)?;
let binary = wat.module.encode()?;
wast_context.module(
wat.module
.id
.map(|s| &s.name()[..])
.as_ref()
.map(|s| &s[..]),
&binary,
)?;

b.bytes += binary.len() as u64;
modules.push(binary);
}
Register {
span: _,
name,
module,
} => {
wast_context.register(module.map(|s| s.name()), name)?;
}
_ => {}
}
}

b.iter(|| {
for bin in &modules {
wast_context.instantiate(bin).unwrap();
}
});

Ok(())
}

fn bench_run(b: &mut test::bench::Bencher, wast: &str, strategy: Strategy) -> Result<()> {
let path = Path::new(wast);

let simd = path.iter().any(|s| s == "simd");

let bulk_mem = path.iter().any(|s| s == "bulk-memory-operations");

// Some simd tests assume support for multiple tables, which are introduced
// by reference types.
let reftypes = simd || path.iter().any(|s| s == "reference-types");

let multi_val = path.iter().any(|s| s == "multi-value");

let mut cfg = Config::new();
cfg.wasm_simd(simd)
.wasm_bulk_memory(bulk_mem)
.wasm_reference_types(reftypes)
.wasm_multi_value(multi_val)
.strategy(strategy)?
.cranelift_debug_verifier(cfg!(debug_assertions));

// FIXME: https://github.com/bytecodealliance/wasmtime/issues/1186
if simd {
cfg.cranelift_opt_level(OptLevel::None);
}

let store = Store::new(&Engine::new(&cfg));
let mut wast_context = WastContext::new(store);
wast_context.register_spectest()?;

let adjust_wast = |mut err: wast::Error| {
err.set_path(path);
err.set_text(wast);
err
};

let file_contents = std::fs::read_to_string(path)
.with_context(|| format!("failed to read `{}`", path.display()))?;
let buf = ParseBuffer::new(&file_contents).map_err(adjust_wast)?;
let ast = parser::parse::<wast::Wast>(&buf).map_err(adjust_wast)?;

let mut execute_directives = Vec::new();
let mut current = None;
let mut dummy_name_id = 0;

for directive in ast.directives {
use wast::{WastDirective::*, WastExecute};

match directive {
Module(mut module) => {
let binary = module.encode()?;

let name = module.id.map(|s| s.name().to_string()).unwrap_or_else(|| {
let name = format!("---dummy-name-{}", dummy_name_id);
dummy_name_id += 1;
name
});
wast_context.module(Some(&name), &binary)?;
current = Some(name);
}
QuoteModule { span: _, source } => {
let mut module = String::new();
for src in source {
module.push_str(std::str::from_utf8(src)?);
module.push_str(" ");
}
let buf = ParseBuffer::new(&module)?;
let mut wat = parser::parse::<Wat>(&buf)?;
let binary = wat.module.encode()?;
let name = wat
.module
.id
.map(|s| s.name().to_string())
.unwrap_or_else(|| {
let name = format!("---dummy-name-{}", dummy_name_id);
dummy_name_id += 1;
name
});
wast_context.module(Some(&name), &binary)?;
current = Some(name);
}
Register {
span: _,
name,
module,
} => {
wast_context.register(module.map(|s| s.name()), name)?;
}
Invoke(call)
| AssertExhaustion { call, .. }
| AssertReturn {
exec: WastExecute::Invoke(call),
..
}
| AssertTrap {
exec: WastExecute::Invoke(call),
..
} => {
use wasmtime::Val;

// Copy/pasted from `wasmtime-wast`
fn runtime_value(v: &wast::Expression<'_>) -> Result<Val> {
use wast::Instruction::*;

if v.instrs.len() != 1 {
bail!("too many instructions in {:?}", v);
}
Ok(match &v.instrs[0] {
I32Const(x) => Val::I32(*x),
I64Const(x) => Val::I64(*x),
F32Const(x) => Val::F32(x.bits),
F64Const(x) => Val::F64(x.bits),
V128Const(x) => Val::V128(u128::from_le_bytes(x.to_le_bytes())),
other => bail!("couldn't convert {:?} to a runtime value", other),
})
}

let values = call
.args
.iter()
.map(runtime_value)
.collect::<Result<Vec<_>>>()?;

execute_directives.push((
call.module
.map(|m| m.name().to_string())
.unwrap_or_else(|| current.clone().unwrap()),
call.name.to_string(),
values,
));
}
_ => {}
}
}

b.iter(|| {
for (mod_name, fn_name, args) in &execute_directives {
wast_context.invoke(Some(mod_name), fn_name, args).unwrap();
}
});

Ok(())
}
8 changes: 3 additions & 5 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ fn main() -> anyhow::Result<()> {
#[cfg(feature = "lightbeam")]
"Lightbeam",
] {
writeln!(out, "#[cfg(test)]")?;
writeln!(out, "#[allow(non_snake_case)]")?;
writeln!(out, "mod {} {{", strategy)?;

Expand Down Expand Up @@ -150,15 +149,14 @@ fn write_testsuite_tests(
let path = path.as_ref();
let testname = extract_name(path);

writeln!(out, "#[test]")?;
writeln!(out, "mk_test! {{")?;
if ignore(testsuite, &testname, strategy) {
writeln!(out, "#[ignore]")?;
}
writeln!(out, "fn r#{}() {{", &testname)?;
writeln!(out, " let _ = env_logger::try_init();")?;
writeln!(
out,
" crate::wast::run_wast(r#\"{}\"#, crate::wast::Strategy::{}).unwrap();",
"r#{}, r#\"{}\"#, Strategy::{}",
&testname,
path.display(),
strategy
)?;
Expand Down
2 changes: 1 addition & 1 deletion crates/environ/src/address_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub struct InstructionAddressMap {
}

/// Function and its instructions addresses mappings.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct FunctionAddressMap {
/// Instructions maps.
/// The array is sorted by the InstructionAddressMap::code_offset field.
Expand Down
2 changes: 1 addition & 1 deletion crates/environ/src/lightbeam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl crate::compilation::Compiler for Lightbeam {
.map_err(|e| CompileError::Codegen(format!("Failed to generate output code: {}", e)))?;

// TODO pass jump table offsets to Compilation::from_buffer() when they
// are implemented in lightbeam -- using empty set of offsets for now.
// are implemented in lightbeam -- using empty set of offsets for now.
// TODO: pass an empty range for the unwind information until lightbeam emits it
let code_section_ranges_and_jt = code_section
.funcs()
Expand Down
1 change: 0 additions & 1 deletion crates/jit/src/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ impl CompiledModule {
};

let finished_functions = FinishedFunctions(finished_functions.into_boxed_slice());

Ok(Self {
module: Arc::new(module),
code: Arc::new(ModuleCode {
Expand Down
3 changes: 0 additions & 3 deletions crates/lightbeam/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ iter-enum = "0.2"
itertools = "0.8.2"
memoffset = "0.5.3"
more-asserts = "0.2.1"
smallvec = "1.0.0"
staticvec = "0.10"
thiserror = "1.0.9"
typemap = "0.3"
wasmparser = "0.57.0"

[dev-dependencies]
Expand Down
Loading