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:
Alex Crichton
2020-11-02 20:37:18 -06:00
committed by GitHub
parent 372ae2aeb6
commit 10b5cc50c3
5 changed files with 115 additions and 72 deletions

View File

@@ -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);

View File

@@ -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,