mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 05:56:56 +00:00
Auto merge of #119302 - Mark-Simulacrum:relative-spans, r=WaffleLapkin
Support encoding spans with relative offsets The relative offset is often smaller than the absolute offset, and with the LEB128 encoding, this ends up cutting the overall metadata size considerably (~1.5 megabytes on libcore). We can support both relative and absolute encodings essentially for free since we already take a full byte to differentiate between direct and indirect encodings (so an extra variant is quite cheap).
This commit is contained in:
commit
15755f38cd
@ -507,10 +507,18 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
|
||||
|
||||
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
|
||||
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Span {
|
||||
let start = decoder.position();
|
||||
let mode = SpanEncodingMode::decode(decoder);
|
||||
let data = match mode {
|
||||
SpanEncodingMode::Direct => SpanData::decode(decoder),
|
||||
SpanEncodingMode::Shorthand(position) => decoder.with_position(position, |decoder| {
|
||||
SpanEncodingMode::RelativeOffset(offset) => {
|
||||
decoder.with_position(start - offset, |decoder| {
|
||||
let mode = SpanEncodingMode::decode(decoder);
|
||||
debug_assert!(matches!(mode, SpanEncodingMode::Direct));
|
||||
SpanData::decode(decoder)
|
||||
})
|
||||
}
|
||||
SpanEncodingMode::AbsoluteOffset(addr) => decoder.with_position(addr, |decoder| {
|
||||
let mode = SpanEncodingMode::decode(decoder);
|
||||
debug_assert!(matches!(mode, SpanEncodingMode::Direct));
|
||||
SpanData::decode(decoder)
|
||||
|
@ -169,7 +169,19 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
|
||||
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
|
||||
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
|
||||
match s.span_shorthands.entry(*self) {
|
||||
Entry::Occupied(o) => SpanEncodingMode::Shorthand(*o.get()).encode(s),
|
||||
Entry::Occupied(o) => {
|
||||
// If an offset is smaller than the absolute position, we encode with the offset.
|
||||
// This saves space since smaller numbers encode in less bits.
|
||||
let last_location = *o.get();
|
||||
// This cannot underflow. Metadata is written with increasing position(), so any
|
||||
// previously saved offset must be smaller than the current position.
|
||||
let offset = s.opaque.position() - last_location;
|
||||
if offset < last_location {
|
||||
SpanEncodingMode::RelativeOffset(offset).encode(s)
|
||||
} else {
|
||||
SpanEncodingMode::AbsoluteOffset(last_location).encode(s)
|
||||
}
|
||||
}
|
||||
Entry::Vacant(v) => {
|
||||
let position = s.opaque.position();
|
||||
v.insert(position);
|
||||
|
@ -68,7 +68,8 @@ pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_V
|
||||
|
||||
#[derive(Encodable, Decodable)]
|
||||
enum SpanEncodingMode {
|
||||
Shorthand(usize),
|
||||
RelativeOffset(usize),
|
||||
AbsoluteOffset(usize),
|
||||
Direct,
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user