Skip to content

Commit 8017774

Browse files
zhouwfangia0
andauthored
Improve the performance of function accessors (#723)
CoreMark result: 37.404152 (in 18.937s) Slight performance improvement on Linux compared to [the previous state](#46 (comment)). #46 --------- Co-authored-by: Zhou Fang <[email protected]> Co-authored-by: Julien Cretin <[email protected]>
1 parent 8f846ea commit 8017774

File tree

3 files changed

+9
-27
lines changed

3 files changed

+9
-27
lines changed

crates/interpreter/src/module.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,7 @@ impl<'m> Module<'m> {
116116
}
117117

118118
pub(crate) fn func_type(&self, x: FuncIdx) -> FuncType<'m> {
119-
let mut parser = self.section(SectionId::Function).unwrap();
120-
for i in 0 .. parser.parse_vec().into_ok() {
121-
let y = parser.parse_typeidx().into_ok();
122-
if i == x as usize {
123-
return self.types[y as usize];
124-
}
125-
}
126-
unreachable!()
119+
self.types[self.side_table[x as usize].type_idx]
127120
}
128121

129122
pub(crate) fn table_type(&self, x: TableIdx) -> TableType {
@@ -183,17 +176,9 @@ impl<'m> Module<'m> {
183176
unreachable!()
184177
}
185178

186-
// TODO(dev/fast-interp): Improve the performance of such accessor functions from O(n) to O(1).
187179
pub(crate) fn func(&self, x: FuncIdx) -> (Parser<'m>, &'m [BranchTableEntry]) {
188-
let mut parser = self.section(SectionId::Code).unwrap();
189-
for i in 0 .. parser.parse_vec().into_ok() {
190-
let size = parser.parse_u32().into_ok() as usize;
191-
let parser = parser.split_at(size).into_ok();
192-
if i == x as usize {
193-
return (parser, &self.side_table[i].branch_table);
194-
}
195-
}
196-
unreachable!()
180+
let MetadataEntry { parser_range, branch_table, .. } = &self.side_table[x as usize];
181+
(unsafe { Parser::new(&self.binary[parser_range.clone()]) }, branch_table)
197182
}
198183

199184
pub(crate) fn data(&self, x: DataIdx) -> Parser<'m> {

crates/interpreter/src/side_table.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,22 @@ impl<'m> Metadata<'m> {
4343
self.0[0] as usize
4444
}
4545

46-
pub fn parser(&self, code: &'m [u8]) -> Parser<'m> {
47-
unsafe { Parser::new(&code[self.parser_pos(1) .. self.parser_pos(3)]) }
46+
pub fn parser(&self, module: &'m [u8]) -> Parser<'m> {
47+
unsafe { Parser::new(&module[self.read_u32(1) .. self.read_u32(3)]) }
4848
}
4949

5050
pub fn branch_table(&self) -> &[BranchTableEntry] {
5151
bytemuck::cast_slice(&self.0[5 ..])
5252
}
5353

54-
fn parser_pos(&self, idx: usize) -> usize {
54+
fn read_u32(&self, idx: usize) -> usize {
5555
bytemuck::pod_read_unaligned::<u32>(bytemuck::cast_slice(&self.0[idx .. idx + 2])) as usize
5656
}
5757
}
5858

5959
#[derive(Default, Debug)]
6060
pub struct MetadataEntry {
61-
#[allow(dead_code)]
6261
pub type_idx: usize,
63-
#[allow(dead_code)]
6462
pub parser_range: Range<usize>,
6563
pub branch_table: Vec<BranchTableEntry>,
6664
}

crates/interpreter/src/valid.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct Context<'m> {
4747
impl<'m> Context<'m> {
4848
fn check_module(&mut self, parser: &mut Parser<'m>) -> MResult<Vec<MetadataEntry>, Check> {
4949
check(parser.parse_bytes(8)? == b"\0asm\x01\0\0\0")?;
50+
let module_start = parser.save().as_ptr() as usize;
5051
if let Some(mut parser) = self.check_section(parser, SectionId::Type)? {
5152
let n = parser.parse_vec()?;
5253
self.types.reserve(n);
@@ -128,19 +129,17 @@ impl<'m> Context<'m> {
128129
let mut side_tables = vec![];
129130
if let Some(mut parser) = self.check_section(parser, SectionId::Code)? {
130131
check(self.funcs.len() == imported_funcs + parser.parse_vec()?)?;
131-
let code_start = parser.save().as_ptr() as usize;
132132
for x in imported_funcs .. self.funcs.len() {
133133
let size = parser.parse_u32()? as usize;
134134
let mut parser = parser.split_at(size)?;
135+
let parser_start = parser.save().as_ptr() as usize - module_start;
135136
let t = self.functype(x as FuncIdx).unwrap();
136137
let mut locals = t.params.to_vec();
137138
parser.parse_locals(&mut locals)?;
138-
let parser_start = parser.save().as_ptr() as usize - code_start;
139139
let branch_table = Expr::check_body(self, &mut parser, &refs, locals, t.results)?;
140-
let parser_end = parser.save().as_ptr() as usize - code_start;
141140
side_tables.push(MetadataEntry {
142141
type_idx: self.funcs[x] as usize,
143-
parser_range: Range { start: parser_start, end: parser_end },
142+
parser_range: Range { start: parser_start, end: parser_start + size },
144143
branch_table,
145144
});
146145
check(parser.is_empty())?;

0 commit comments

Comments
 (0)