Skip to content

Commit 94c7252

Browse files
authored
Use SecondaryMaps in FuncTranslationState (#11352)
These maps are all keyed on entities, and should all be fairly dense and/or small, so we can use `SecondaryMap`s to get fast lookups and avoid hashing.
1 parent 69fecf4 commit 94c7252

File tree

1 file changed

+36
-26
lines changed

1 file changed

+36
-26
lines changed

crates/cranelift/src/translate/state.rs

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use crate::func_environ::FuncEnvironment;
77
use crate::translate::Heap;
88
use crate::translate::environ::GlobalVariable;
99
use cranelift_codegen::ir::{self, Block, Inst, Value};
10-
use std::collections::hash_map::{Entry::Occupied, Entry::Vacant, HashMap};
10+
use cranelift_entity::SecondaryMap;
11+
use cranelift_entity::packed_option::PackedOption;
1112
use std::vec::Vec;
1213
use wasmtime_environ::{FuncIndex, GlobalIndex, MemoryIndex, TypeIndex, WasmResult};
1314

@@ -226,20 +227,20 @@ pub struct FuncTranslationState {
226227
pub(crate) reachable: bool,
227228

228229
// Map of global variables that have already been created by `FuncEnvironment::make_global`.
229-
globals: HashMap<GlobalIndex, GlobalVariable>,
230+
globals: SecondaryMap<GlobalIndex, Option<GlobalVariable>>,
230231

231232
// Map of heaps that have been created by `FuncEnvironment::make_heap`.
232-
memory_to_heap: HashMap<MemoryIndex, Heap>,
233+
memory_to_heap: SecondaryMap<MemoryIndex, PackedOption<Heap>>,
233234

234235
// Map of indirect call signatures that have been created by
235236
// `FuncEnvironment::make_indirect_sig()`.
236237
// Stores both the signature reference and the number of WebAssembly arguments
237-
signatures: HashMap<TypeIndex, (ir::SigRef, usize)>,
238+
signatures: SecondaryMap<TypeIndex, Option<(ir::SigRef, usize)>>,
238239

239240
// Imported and local functions that have been created by
240241
// `FuncEnvironment::make_direct_func()`.
241242
// Stores both the function reference and the number of WebAssembly arguments
242-
functions: HashMap<FuncIndex, (ir::FuncRef, usize)>,
243+
functions: SecondaryMap<FuncIndex, Option<(ir::FuncRef, usize)>>,
243244
}
244245

245246
// Public methods that are exposed to non- API consumers.
@@ -258,10 +259,10 @@ impl FuncTranslationState {
258259
stack: Vec::new(),
259260
control_stack: Vec::new(),
260261
reachable: true,
261-
globals: HashMap::new(),
262-
memory_to_heap: HashMap::new(),
263-
signatures: HashMap::new(),
264-
functions: HashMap::new(),
262+
globals: SecondaryMap::new(),
263+
memory_to_heap: SecondaryMap::new(),
264+
signatures: SecondaryMap::new(),
265+
functions: SecondaryMap::new(),
265266
}
266267
}
267268

@@ -473,9 +474,13 @@ impl FuncTranslationState {
473474
environ: &mut FuncEnvironment<'_>,
474475
) -> WasmResult<GlobalVariable> {
475476
let index = GlobalIndex::from_u32(index);
476-
match self.globals.entry(index) {
477-
Occupied(entry) => Ok(*entry.get()),
478-
Vacant(entry) => Ok(*entry.insert(environ.make_global(func, index)?)),
477+
match self.globals[index] {
478+
Some(g) => Ok(g),
479+
None => {
480+
let g = environ.make_global(func, index)?;
481+
self.globals[index] = Some(g);
482+
Ok(g)
483+
}
479484
}
480485
}
481486

@@ -488,9 +493,13 @@ impl FuncTranslationState {
488493
environ: &mut FuncEnvironment<'_>,
489494
) -> WasmResult<Heap> {
490495
let index = MemoryIndex::from_u32(index);
491-
match self.memory_to_heap.entry(index) {
492-
Occupied(entry) => Ok(*entry.get()),
493-
Vacant(entry) => Ok(*entry.insert(environ.make_heap(func, index)?)),
496+
match self.memory_to_heap[index].expand() {
497+
Some(heap) => Ok(heap),
498+
None => {
499+
let heap = environ.make_heap(func, index)?;
500+
self.memory_to_heap[index] = Some(heap).into();
501+
Ok(heap)
502+
}
494503
}
495504
}
496505

@@ -505,11 +514,13 @@ impl FuncTranslationState {
505514
environ: &mut FuncEnvironment<'_>,
506515
) -> WasmResult<(ir::SigRef, usize)> {
507516
let index = TypeIndex::from_u32(index);
508-
match self.signatures.entry(index) {
509-
Occupied(entry) => Ok(*entry.get()),
510-
Vacant(entry) => {
517+
match self.signatures[index] {
518+
Some((sig, num_params)) => Ok((sig, num_params)),
519+
None => {
511520
let sig = environ.make_indirect_sig(func, index)?;
512-
Ok(*entry.insert((sig, num_wasm_parameters(environ, &func.dfg.signatures[sig]))))
521+
let num_params = num_wasm_parameters(environ, &func.dfg.signatures[sig]);
522+
self.signatures[index] = Some((sig, num_params));
523+
Ok((sig, num_params))
513524
}
514525
}
515526
}
@@ -525,15 +536,14 @@ impl FuncTranslationState {
525536
environ: &mut FuncEnvironment<'_>,
526537
) -> WasmResult<(ir::FuncRef, usize)> {
527538
let index = FuncIndex::from_u32(index);
528-
match self.functions.entry(index) {
529-
Occupied(entry) => Ok(*entry.get()),
530-
Vacant(entry) => {
539+
match self.functions[index] {
540+
Some((fref, num_args)) => Ok((fref, num_args)),
541+
None => {
531542
let fref = environ.make_direct_func(func, index)?;
532543
let sig = func.dfg.ext_funcs[fref].signature;
533-
Ok(*entry.insert((
534-
fref,
535-
num_wasm_parameters(environ, &func.dfg.signatures[sig]),
536-
)))
544+
let num_args = num_wasm_parameters(environ, &func.dfg.signatures[sig]);
545+
self.functions[index] = Some((fref, num_args));
546+
Ok((fref, num_args))
537547
}
538548
}
539549
}

0 commit comments

Comments
 (0)