Skip to content

Commit c018150

Browse files
committed
pack Mappings of StringTableSlice better
StringTableSlice has an alignment of 2, given its u16 members. The byte_len field can always fit into a u8. To give it an alignment of 1 so that it can pack well into a Mapping, we need to store the byte_start member as separate u8 fields, and change Mapping's discriminant to a u8. This change makes Range take up 12 bytes on a 64-bit system instead of 16, for a significant space savings. LLVM ought to be able to optimize the load/load/shift/or recomposition of byte_start into a single u16 load on unaligned architectures like x86. Current Rust does not do that, but an extra instruction or two is worth a 25% space optimization.
1 parent a44257d commit c018150

File tree

3 files changed

+5742
-5731
lines changed

3 files changed

+5742
-5731
lines changed

idna/src/make_uts46_mapping_table.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ def strtab_slice(s):
5151
return c
5252

5353
def rust_slice(s):
54-
return "(StringTableSlice { byte_start: %d, byte_len: %d })" % s
54+
start = s[0]
55+
length = s[1]
56+
start_lo = start & 0xff
57+
start_hi = start >> 8
58+
assert length <= 255
59+
assert start_hi <= 255
60+
return "(StringTableSlice { byte_start_lo: %d, byte_start_hi: %d, byte_len: %d })" % (start_lo, start_hi, length)
5561

5662
ranges = []
5763

idna/src/uts46.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,22 @@ include!("uts46_mapping_table.rs");
2121

2222
#[derive(Debug)]
2323
struct StringTableSlice {
24-
byte_start: u16,
25-
byte_len: u16,
24+
// Store these as separate fields so the structure will have an
25+
// alignment of 1 and thus pack better into the Mapping enum, below.
26+
byte_start_lo: u8,
27+
byte_start_hi: u8,
28+
byte_len: u8,
2629
}
2730

2831
fn decode_slice(slice: &StringTableSlice) -> &'static str {
29-
let start = slice.byte_start as usize;
32+
let lo = slice.byte_start_lo as usize;
33+
let hi = slice.byte_start_hi as usize;
34+
let start = (hi << 8) | lo;
3035
let len = slice.byte_len as usize;
3136
&STRING_TABLE[start..(start + len)]
3237
}
3338

34-
#[repr(u16)]
39+
#[repr(u8)]
3540
#[derive(Debug)]
3641
enum Mapping {
3742
Valid,

0 commit comments

Comments
 (0)