Skip to content

Commit 4b449e0

Browse files
committed
wasmparser: improve visit_operator performance
- The BinaryReader can visit_operator by itself again, with no need for OperatorsReader or extra state, when the visitor implements the FrameStack trait. Validation uses this to avoid duplicating the frame stack. - OperatorsReader keeps an internal FrameStack and can be created from its allocations (and turned back into them), avoiding the need to allocate a stack of frames.
1 parent 6ed1788 commit 4b449e0

File tree

19 files changed

+1561
-1338
lines changed

19 files changed

+1561
-1338
lines changed

crates/wasm-encoder/src/reencode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ pub mod utils {
15941594
reencoder: &mut T,
15951595
const_expr: wasmparser::ConstExpr,
15961596
) -> Result<crate::ConstExpr, Error<T::Error>> {
1597-
let mut ops = const_expr.get_operators_reader();
1597+
let mut ops = const_expr.get_operators_reader(Default::default());
15981598
let mut bytes = Vec::new();
15991599

16001600
while !ops.is_end_then_eof() {
@@ -1740,7 +1740,7 @@ pub mod utils {
17401740
func: wasmparser::FunctionBody<'_>,
17411741
) -> Result<(), Error<T::Error>> {
17421742
let mut f = reencoder.new_function_with_parsed_locals(&func)?;
1743-
let mut reader = func.get_operators_reader()?;
1743+
let mut reader = func.get_operators_reader(Default::default())?;
17441744
while !reader.eof() {
17451745
f.instruction(&reencoder.parse_instruction(&mut reader)?);
17461746
}

crates/wasm-mutate/src/mutators/codemotion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl CodemotionMutator {
7575
for fidx in (function_to_mutate..function_count).chain(0..function_to_mutate) {
7676
config.consume_fuel(1)?;
7777
let reader = all_readers[fidx as usize].clone();
78-
let operatorreader = reader.get_operators_reader()?;
78+
let operatorreader = reader.get_operators_reader(Default::default())?;
7979

8080
let operators = operatorreader
8181
.into_iter_with_offsets()

crates/wasm-mutate/src/mutators/modify_const_exprs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<'cfg, 'wasm> Reencode for InitTranslator<'cfg, 'wasm> {
6262
return reencode::utils::const_expr(self, e);
6363
}
6464

65-
let mut reader = e.get_operators_reader();
65+
let mut reader = e.get_operators_reader(Default::default());
6666

6767
if !self.config.reduce {
6868
// FIXME: implement non-reducing mutations for constant expressions.

crates/wasm-mutate/src/mutators/peephole.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl PeepholeMutator {
122122
}
123123

124124
let reader = readers[function_to_mutate as usize].clone();
125-
let operatorreader = reader.get_operators_reader()?;
125+
let operatorreader = reader.get_operators_reader(Default::default())?;
126126
let mut localsreader = reader.get_locals_reader()?;
127127
let operators = operatorreader
128128
.into_iter_with_offsets()
@@ -490,7 +490,7 @@ macro_rules! match_code_mutation {
490490
});
491491
}
492492
Payload::CodeSectionEntry(reader) => {
493-
let operatorsreader = reader.get_operators_reader().unwrap();
493+
let operatorsreader = reader.get_operators_reader(Default::default()).unwrap();
494494
let range = operatorsreader.get_binary_reader().range();
495495
let operators = operatorsreader
496496
.into_iter_with_offsets()

crates/wasm-mutate/src/mutators/peephole/dfg.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,7 +1314,7 @@ mod tests {
13141314
match payload {
13151315
wasmparser::Payload::CodeSectionEntry(reader) => {
13161316
let operators = reader
1317-
.get_operators_reader()
1317+
.get_operators_reader(Default::default())
13181318
.unwrap()
13191319
.into_iter_with_offsets()
13201320
.collect::<wasmparser::Result<Vec<OperatorAndByteOffset>>>()
@@ -1370,7 +1370,7 @@ mod tests {
13701370
match payload {
13711371
wasmparser::Payload::CodeSectionEntry(reader) => {
13721372
let operators = reader
1373-
.get_operators_reader()
1373+
.get_operators_reader(Default::default())
13741374
.unwrap()
13751375
.into_iter_with_offsets()
13761376
.collect::<wasmparser::Result<Vec<OperatorAndByteOffset>>>()
@@ -1452,7 +1452,7 @@ mod tests {
14521452
match payload {
14531453
wasmparser::Payload::CodeSectionEntry(reader) => {
14541454
let operators = reader
1455-
.get_operators_reader()
1455+
.get_operators_reader(Default::default())
14561456
.unwrap()
14571457
.into_iter_with_offsets()
14581458
.collect::<wasmparser::Result<Vec<OperatorAndByteOffset>>>()
@@ -1509,7 +1509,7 @@ mod tests {
15091509
match payload {
15101510
wasmparser::Payload::CodeSectionEntry(reader) => {
15111511
let operators = reader
1512-
.get_operators_reader()
1512+
.get_operators_reader(Default::default())
15131513
.unwrap()
15141514
.into_iter_with_offsets()
15151515
.collect::<wasmparser::Result<Vec<OperatorAndByteOffset>>>()

crates/wasmparser/benches/benchmark.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ fn collect_test_files(path: &Path, list: &mut Vec<BenchmarkInput>) -> Result<()>
8080
/// so that we can report better errors in case of failures.
8181
fn read_all_wasm(wasm: &[u8]) -> Result<()> {
8282
use Payload::*;
83+
let mut allocs = wasmparser::OperatorsReaderAllocations::default();
8384
for item in Parser::new(0).parse_all(wasm) {
8485
match item? {
8586
TypeSection(s) => {
@@ -114,9 +115,14 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
114115
}
115116
GlobalSection(s) => {
116117
for item in s {
117-
for op in item?.init_expr.get_operators_reader() {
118+
let mut ops = item?
119+
.init_expr
120+
.get_operators_reader(std::mem::take(&mut allocs))
121+
.into_iter();
122+
for op in ops.by_ref() {
118123
op?;
119124
}
125+
allocs = ops.into_allocations();
120126
}
121127
}
122128
ExportSection(s) => {
@@ -128,9 +134,13 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
128134
for item in s {
129135
let item = item?;
130136
if let ElementKind::Active { offset_expr, .. } = item.kind {
131-
for op in offset_expr.get_operators_reader() {
137+
let mut ops = offset_expr
138+
.get_operators_reader(std::mem::take(&mut allocs))
139+
.into_iter();
140+
for op in ops.by_ref() {
132141
op?;
133142
}
143+
allocs = ops.into_allocations();
134144
}
135145
match item.items {
136146
wasmparser::ElementItems::Functions(r) => {
@@ -150,9 +160,13 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
150160
for item in s {
151161
let item = item?;
152162
if let DataKind::Active { offset_expr, .. } = item.kind {
153-
for op in offset_expr.get_operators_reader() {
163+
let mut ops = offset_expr
164+
.get_operators_reader(std::mem::take(&mut allocs))
165+
.into_iter();
166+
for op in ops.by_ref() {
154167
op?;
155168
}
169+
allocs = ops.into_allocations();
156170
}
157171
}
158172
}
@@ -161,11 +175,12 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
161175
for item in locals.by_ref() {
162176
let _ = item?;
163177
}
164-
let mut ops = locals.into_operators_reader();
178+
let mut ops = locals.into_operators_reader(std::mem::take(&mut allocs));
165179
while !ops.eof() {
166180
ops.visit_operator(&mut NopVisit)?;
167181
}
168182
ops.finish()?;
183+
allocs = ops.into_allocations();
169184
}
170185

171186
// Component sections

crates/wasmparser/src/arity.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
use crate::prelude::*;
1717
use crate::{
18-
BinaryReaderError, BlockType, BrTable, CompositeInnerType, ContType, FrameKind, FuncType,
19-
Operator, OperatorsReader, RefType, Result, ResumeTable, SubType, TryTable, ValType,
18+
BlockType, BrTable, CompositeInnerType, ContType, FrameKind, FuncType, Operator, RefType,
19+
ResumeTable, SubType, TryTable, ValType,
2020
};
2121

2222
/// To compute the arity (param and result counts) of "variable-arity"
@@ -70,15 +70,6 @@ pub trait ModuleArity {
7070
}
7171
}
7272

73-
impl OperatorsReader<'_> {
74-
/// Read the next operator and compute its arity (param and result counts)
75-
pub fn operator_arity(&self, module: &impl ModuleArity) -> Result<(u32, u32)> {
76-
self.clone().read()?.operator_arity(module).ok_or_else(|| {
77-
BinaryReaderError::new("operator arity is unknown", self.original_position())
78-
})
79-
}
80-
}
81-
8273
impl Operator<'_> {
8374
/// Compute the arity (param and result counts) of the operator, given
8475
/// an impl ModuleArity, which stores the necessary module state.

0 commit comments

Comments
 (0)