Skip to content

Commit 225b3c0

Browse files
committed
Document in the code how this scheme works
1 parent e0103a7 commit 225b3c0

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,10 @@ impl<T> LazyArray<T> {
136136
/// eagerly and in-order.
137137
struct LazyTable<I, T> {
138138
position: NonZeroUsize,
139+
/// The encoded size of the elements of a table is selected at runtime to drop
140+
/// trailing zeroes. This is the number of bytes used for each table element.
139141
width: usize,
142+
/// How many elements are in the table.
140143
len: usize,
141144
_marker: PhantomData<fn(I) -> T>,
142145
}

compiler/rustc_metadata/src/rmeta/table.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,12 @@ impl<T> LazyArray<T> {
346346
let position = (self.position.get() as u64).to_le_bytes();
347347
let len = (self.num_elems as u64).to_le_bytes();
348348

349+
// Element width is selected at runtime on a per-table basis by omitting trailing
350+
// zero bytes in table elements. This works very naturally when table elements are
351+
// simple numbers but `LazyArray` is a pair of integers. If naively encoded, the second
352+
// element would shield the trailing zeroes in the first. Interleaving the bytes
353+
// of the position and length exposes trailing zeroes in both to the optimization.
354+
// We encode length second because we generally expect it to be smaller.
349355
for i in 0..8 {
350356
b[2 * i] = position[i];
351357
b[2 * i + 1] = len[i];
@@ -359,18 +365,26 @@ impl<T> LazyArray<T> {
359365
}
360366
}
361367

368+
// Decoding helper for the encoding scheme used by `LazyArray`.
369+
// Interleaving the bytes of the two integers exposes trailing bytes in the first integer
370+
// to the varint scheme that we use for tables.
371+
#[inline]
372+
fn decode_interleaved(encoded: &[u8; 16]) -> ([u8; 8], [u8; 8]) {
373+
let mut first = [0u8; 8];
374+
let mut second = [0u8; 8];
375+
for i in 0..8 {
376+
first[i] = encoded[2 * i];
377+
second[i] = encoded[2 * i + 1];
378+
}
379+
(first, second)
380+
}
381+
362382
impl<T> FixedSizeEncoding for LazyArray<T> {
363383
type ByteArray = [u8; 16];
364384

365385
#[inline]
366386
fn from_bytes(b: &[u8; 16]) -> Self {
367-
let mut position = [0u8; 8];
368-
let mut meta = [0u8; 8];
369-
370-
for i in 0..8 {
371-
position[i] = b[2 * i];
372-
meta[i] = b[2 * i + 1];
373-
}
387+
let (position, meta) = decode_interleaved(b);
374388

375389
if meta == [0; 8] {
376390
return Default::default();
@@ -390,13 +404,7 @@ impl<T> FixedSizeEncoding for Option<LazyArray<T>> {
390404

391405
#[inline]
392406
fn from_bytes(b: &[u8; 16]) -> Self {
393-
let mut position = [0u8; 8];
394-
let mut meta = [0u8; 8];
395-
396-
for i in 0..8 {
397-
position[i] = b[2 * i];
398-
meta[i] = b[2 * i + 1];
399-
}
407+
let (position, meta) = decode_interleaved(b);
400408

401409
LazyArray::from_bytes_impl(&position, &meta)
402410
}

0 commit comments

Comments
 (0)