Move function names out of Module (#3789)
* Move function names out of `Module` This commit moves function names in a module out of the `wasmtime_environ::Module` type and into separate sections stored in the final compiled artifact. Spurred on by #3787 to look at module load times I noticed that a huge amount of time was spent in deserializing this map. The `spidermonkey.wasm` file, for example, has a 3MB name section which is a lot of unnecessary data to deserialize at module load time. The names of functions are now split out into their own dedicated section of the compiled artifact and metadata about them is stored in a more compact format at runtime by avoiding a `BTreeMap` and instead using a sorted array. Overall this improves deserialize times by up to 80% for modules with large name sections since the name section is no longer deserialized at load time and it's lazily paged in as names are actually referenced. * Fix a typo * Fix compiled module determinism Need to not only sort afterwards but also first to ensure the data of the name section is consistent.
This commit is contained in:
@@ -664,9 +664,6 @@ pub struct Module {
|
||||
/// The map from passive data index (data segment index space) to index in `passive_data`.
|
||||
pub passive_data_map: BTreeMap<DataIndex, Range<u32>>,
|
||||
|
||||
/// WebAssembly function names.
|
||||
pub func_names: BTreeMap<FuncIndex, String>,
|
||||
|
||||
/// Types declared in the wasm module.
|
||||
pub types: PrimaryMap<TypeIndex, ModuleType>,
|
||||
|
||||
|
||||
@@ -146,8 +146,8 @@ type Reader<'input> = gimli::EndianSlice<'input, gimli::LittleEndian>;
|
||||
#[allow(missing_docs)]
|
||||
pub struct NameSection<'a> {
|
||||
pub module_name: Option<&'a str>,
|
||||
pub func_names: HashMap<u32, &'a str>,
|
||||
pub locals_names: HashMap<u32, HashMap<u32, &'a str>>,
|
||||
pub func_names: HashMap<FuncIndex, &'a str>,
|
||||
pub locals_names: HashMap<FuncIndex, HashMap<u32, &'a str>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@@ -1291,18 +1291,17 @@ and for re-adding support for interface types you can see this issue:
|
||||
if (index as usize) >= self.result.module.functions.len() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Store the name unconditionally, regardless of
|
||||
// whether we're parsing debuginfo, since function
|
||||
// names are almost always present in the
|
||||
// final compilation artifact.
|
||||
let index = FuncIndex::from_u32(index);
|
||||
self.result
|
||||
.module
|
||||
.debuginfo
|
||||
.name_section
|
||||
.func_names
|
||||
.insert(index, name.to_string());
|
||||
if self.tunables.generate_native_debuginfo {
|
||||
self.result
|
||||
.debuginfo
|
||||
.name_section
|
||||
.func_names
|
||||
.insert(index.as_u32(), name);
|
||||
}
|
||||
.insert(index, name);
|
||||
}
|
||||
}
|
||||
wasmparser::Name::Module(module) => {
|
||||
@@ -1332,7 +1331,7 @@ and for re-adding support for interface types you can see this issue:
|
||||
.debuginfo
|
||||
.name_section
|
||||
.locals_names
|
||||
.entry(f.indirect_index)
|
||||
.entry(FuncIndex::from_u32(f.indirect_index))
|
||||
.or_insert(HashMap::new())
|
||||
.insert(index, name);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user