Skip to content

Commit

Permalink
pref: improve parser performance
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <[email protected]>
  • Loading branch information
explodingcamera committed Feb 24, 2024
1 parent 1313cc0 commit dea9327
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 28 deletions.
20 changes: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 12 additions & 6 deletions crates/benchmarks/benches/selfhosted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,19 @@ fn run_wasmer(wasm: &[u8]) {

const TINYWASM: &[u8] = include_bytes!("../../../examples/rust/out/tinywasm.wasm");
fn criterion_benchmark(c: &mut Criterion) {
let twasm = util::wasm_to_twasm(TINYWASM);
{
let mut group = c.benchmark_group("selfhosted-parse");
group.bench_function("tinywasm", |b| b.iter(|| util::wasm_to_twasm(TINYWASM)));
}

let mut group = c.benchmark_group("selfhosted");
group.bench_function("native", |b| b.iter(run_native));
group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm)));
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(TINYWASM)));
group.bench_function("wasmer", |b| b.iter(|| run_wasmer(TINYWASM)));
{
let twasm = util::wasm_to_twasm(TINYWASM);
let mut group = c.benchmark_group("selfhosted");
// group.bench_function("native", |b| b.iter(run_native));
group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm)));
// group.bench_function("wasmi", |b| b.iter(|| run_wasmi(TINYWASM)));
// group.bench_function("wasmer", |b| b.iter(|| run_wasmer(TINYWASM)));
}
}

criterion_group!(
Expand Down
47 changes: 35 additions & 12 deletions crates/parser/src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ pub(crate) fn convert_module_code(
}

let body_reader = func.get_operators_reader()?;
let body = process_operators(body_reader.original_position(), body_reader.into_iter(), validator)?;
let body = process_operators(body_reader, validator)?;

Ok(CodeSection { locals: locals.into_boxed_slice(), body })
}
Expand Down Expand Up @@ -228,28 +228,47 @@ pub(crate) fn process_const_operator(op: wasmparser::Operator<'_>) -> Result<Con
}
}

pub(crate) fn process_operators<'a>(
mut offset: usize,
ops: impl Iterator<Item = Result<wasmparser::Operator<'a>, wasmparser::BinaryReaderError>>,
pub(crate) fn process_operators(
ops: OperatorsReader<'_>,
mut validator: FuncValidator<ValidatorResources>,
) -> Result<Box<[Instruction]>> {
let mut instructions = Vec::new();
let mut labels_ptrs = Vec::new(); // indexes into the instructions array
let mut instructions = Vec::with_capacity(1024);
let mut labels_ptrs = Vec::with_capacity(32);
// indexes into the instructions array
let mut offset = ops.original_position();

for op in ops {
log::debug!("op: {:?}", op);
let op = match op {
Ok(op) => op,
Err(e) => {
cold();
log::error!("Error while processing operators: {:?}", e);
return Err(crate::ParseError::UnsupportedOperator("Error while processing operators".to_string()));
}
};

let op = op?;
validator.op(offset, &op)?;
match validator.op(offset, &op) {
Ok(_) => (),
Err(e) => {
cold();
log::error!("Error while processing operators: {:?}", e);
return Err(crate::ParseError::UnsupportedOperator("Error while processing operators".to_string()));
}
}
offset += 1;

use wasmparser::Operator::*;
let res = match op {
BrTable { targets } => {
let def = targets.default();
let targets = targets.targets().collect::<Result<Vec<u32>, wasmparser::BinaryReaderError>>()?;
instructions.push(Instruction::BrTable(def, targets.len()));
instructions.extend(targets.into_iter().map(Instruction::BrLabel));

let instrs = targets
.targets()
.map(|t| t.map(Instruction::BrLabel))
.collect::<Result<Vec<Instruction>, wasmparser::BinaryReaderError>>()?;

instructions.push(Instruction::BrTable(def, instrs.len()));
instructions.extend(instrs);
continue;
}
Unreachable => Instruction::Unreachable,
Expand Down Expand Up @@ -510,6 +529,7 @@ pub(crate) fn process_operators<'a>(
TableSize { table } => Instruction::TableSize(table),
TableFill { table } => Instruction::TableFill(table),
op => {
cold();
log::error!("Unsupported instruction: {:?}", op);
return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported instruction: {:?}", op)));
}
Expand All @@ -524,3 +544,6 @@ pub(crate) fn process_operators<'a>(
validator.finish(offset)?;
Ok(instructions.into_boxed_slice())
}

#[cold]
fn cold() {}
2 changes: 2 additions & 0 deletions examples/rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@

This is a seperate crate that generates WebAssembly from Rust code.
It is used by the `wasm-rust` example.

Requires the `wasm32-unknown-unknown` target to be installed.
2 changes: 2 additions & 0 deletions examples/rust/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel="nightly-2024-02-11"

0 comments on commit dea9327

Please sign in to comment.