Further compress the in-memory representation of address maps (#2324)
This commit reduces the size of `InstructionAddressMap` from 24 bytes to 8 bytes by dropping the `code_len` field and reducing `code_offset` to `u32` instead of `usize`. The intention is to primarily make the in-memory version take up less space, and the hunch is that the `code_len` is largely not necessary since most entries in this map are always adjacent to one another. The `code_len` field is now implied by the `code_offset` field of the next entry in the map. This isn't as big of an improvement to serialized module size as #2321 or #2322, primarily because of the switch to variable-length encoding. Despite this though it shaves about 10MB off the encoded size of the module from #2318
This commit is contained in:
@@ -102,7 +102,7 @@ fn build_function_lookup(
|
||||
let mut ranges_index = BTreeMap::new();
|
||||
let mut current_range = Vec::new();
|
||||
let mut last_gen_inst_empty = false;
|
||||
for t in &ft.instructions {
|
||||
for (i, t) in ft.instructions.iter().enumerate() {
|
||||
if t.srcloc.is_default() {
|
||||
continue;
|
||||
}
|
||||
@@ -111,8 +111,11 @@ fn build_function_lookup(
|
||||
assert_le!(fn_start, offset);
|
||||
assert_le!(offset, fn_end);
|
||||
|
||||
let inst_gen_start = t.code_offset;
|
||||
let inst_gen_end = t.code_offset + t.code_len;
|
||||
let inst_gen_start = t.code_offset as usize;
|
||||
let inst_gen_end = match ft.instructions.get(i + 1) {
|
||||
Some(i) => i.code_offset as usize,
|
||||
None => ft.body_len as usize,
|
||||
};
|
||||
|
||||
if last_wasm_pos > offset {
|
||||
// Start new range.
|
||||
@@ -149,7 +152,7 @@ fn build_function_lookup(
|
||||
}
|
||||
last_wasm_pos = offset;
|
||||
}
|
||||
let last_gen_addr = ft.body_offset + ft.body_len;
|
||||
let last_gen_addr = ft.body_offset + ft.body_len as usize;
|
||||
ranges_index.insert(range_wasm_start, ranges.len());
|
||||
ranges.push(Range {
|
||||
wasm_start: range_wasm_start,
|
||||
@@ -193,13 +196,13 @@ fn build_function_addr_map(
|
||||
for (_, f) in funcs {
|
||||
let ft = &f.address_map;
|
||||
let mut fn_map = Vec::new();
|
||||
for t in &ft.instructions {
|
||||
for t in ft.instructions.iter() {
|
||||
if t.srcloc.is_default() {
|
||||
continue;
|
||||
}
|
||||
let offset = get_wasm_code_offset(t.srcloc, code_section_offset);
|
||||
fn_map.push(AddressMap {
|
||||
generated: t.code_offset,
|
||||
generated: t.code_offset as usize,
|
||||
wasm: offset,
|
||||
});
|
||||
}
|
||||
@@ -213,7 +216,7 @@ fn build_function_addr_map(
|
||||
|
||||
map.push(FunctionMap {
|
||||
offset: ft.body_offset,
|
||||
len: ft.body_len,
|
||||
len: ft.body_len as usize,
|
||||
wasm_start: get_wasm_code_offset(ft.start_srcloc, code_section_offset),
|
||||
wasm_end: get_wasm_code_offset(ft.end_srcloc, code_section_offset),
|
||||
addresses: fn_map.into_boxed_slice(),
|
||||
@@ -605,6 +608,7 @@ mod tests {
|
||||
use super::{build_function_lookup, get_wasm_code_offset, AddressTransform};
|
||||
use gimli::write::Address;
|
||||
use std::iter::FromIterator;
|
||||
use std::mem;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
use wasmtime_environ::ir::SourceLoc;
|
||||
use wasmtime_environ::{CompiledFunction, WasmFileInfo};
|
||||
@@ -626,14 +630,21 @@ mod tests {
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(wasm_offset + 2),
|
||||
code_offset: 5,
|
||||
code_len: 3,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
code_offset: 8,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(wasm_offset + 7),
|
||||
code_offset: 15,
|
||||
code_len: 8,
|
||||
},
|
||||
],
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
code_offset: 23,
|
||||
},
|
||||
]
|
||||
.into(),
|
||||
start_srcloc: SourceLoc::new(wasm_offset),
|
||||
end_srcloc: SourceLoc::new(wasm_offset + 10),
|
||||
body_offset: 0,
|
||||
@@ -678,11 +689,16 @@ mod tests {
|
||||
fn test_build_function_lookup_two_ranges() {
|
||||
let mut input = create_simple_func(11);
|
||||
// append instruction with same srcloc as input.instructions[0]
|
||||
input.instructions.push(InstructionAddressMap {
|
||||
let mut list = Vec::from(mem::take(&mut input.instructions));
|
||||
list.push(InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(11 + 2),
|
||||
code_offset: 23,
|
||||
code_len: 3,
|
||||
});
|
||||
list.push(InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
code_offset: 26,
|
||||
});
|
||||
input.instructions = list.into();
|
||||
let (start, end, lookup) = build_function_lookup(&input, 1);
|
||||
assert_eq!(10, start);
|
||||
assert_eq!(20, end);
|
||||
|
||||
@@ -1145,14 +1145,21 @@ mod tests {
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(code_section_offset + 12),
|
||||
code_offset: 5,
|
||||
code_len: 3,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
code_offset: 8,
|
||||
},
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::new(code_section_offset + 17),
|
||||
code_offset: 15,
|
||||
code_len: 8,
|
||||
},
|
||||
],
|
||||
InstructionAddressMap {
|
||||
srcloc: SourceLoc::default(),
|
||||
code_offset: 23,
|
||||
},
|
||||
]
|
||||
.into(),
|
||||
start_srcloc: SourceLoc::new(code_section_offset + 10),
|
||||
end_srcloc: SourceLoc::new(code_section_offset + 20),
|
||||
body_offset: 0,
|
||||
|
||||
Reference in New Issue
Block a user