Skip to content

Commit 08a235c

Browse files
committed
Use 1-bit tag for span encoding
1 parent 89a1303 commit 08a235c

File tree

2 files changed

+26
-72
lines changed

2 files changed

+26
-72
lines changed

src/librustc/ty/maps/plumbing.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ macro_rules! define_maps {
221221

222222
profq_msg!(tcx,
223223
ProfileQueriesMsg::QueryBegin(
224-
span.clone(),
224+
span.data(),
225225
QueryMsg::$name(profq_key!(tcx, key))
226226
)
227227
);

src/libsyntax_pos/span_encoding.rs

+25-71
Original file line numberDiff line numberDiff line change
@@ -45,72 +45,40 @@ impl Span {
4545
}
4646

4747
// Tags
48-
const TAG_INLINE0: u32 = 0b00;
49-
const TAG_INLINE1: u32 = 0b01;
50-
const TAG_INLINE2: u32 = 0b10;
51-
const TAG_INTERNED: u32 = 0b11;
52-
const TAG_MASK: u32 = 0b11;
48+
const TAG_INLINE: u32 = 0;
49+
const TAG_INTERNED: u32 = 1;
50+
const TAG_MASK: u32 = 1;
5351

5452
// Fields indexes
5553
const BASE_INDEX: usize = 0;
5654
const LEN_INDEX: usize = 1;
5755
const CTXT_INDEX: usize = 2;
5856

59-
// Tag = 0b00, inline format 0.
57+
// Tag = 0, inline format.
6058
// -----------------------------------
61-
// | base 31:8 | len 7:2 | tag 1:0 |
59+
// | base 31:8 | len 7:1 | tag 0:0 |
6260
// -----------------------------------
63-
const INLINE0_SIZES: [u32; 3] = [24, 6, 0];
64-
const INLINE0_OFFSETS: [u32; 3] = [8, 2, 2];
61+
const INLINE_SIZES: [u32; 3] = [24, 7, 0];
62+
const INLINE_OFFSETS: [u32; 3] = [8, 1, 1];
6563

66-
// Tag = 0b01, inline format 1.
67-
// -----------------------------------
68-
// | base 31:10 | len 9:2 | tag 1:0 |
69-
// -----------------------------------
70-
const INLINE1_SIZES: [u32; 3] = [22, 8, 0];
71-
const INLINE1_OFFSETS: [u32; 3] = [10, 2, 2];
72-
73-
// Tag = 0b10, inline format 2.
74-
// ------------------------------------------------
75-
// | base 31:14 | len 13:13 | ctxt 12:2 | tag 1:0 |
76-
// ------------------------------------------------
77-
const INLINE2_SIZES: [u32; 3] = [18, 1, 11];
78-
const INLINE2_OFFSETS: [u32; 3] = [14, 13, 2];
79-
80-
// Tag = 0b11, interned format.
64+
// Tag = 1, interned format.
8165
// ------------------------
82-
// | index 31:3 | tag 1:0 |
66+
// | index 31:1 | tag 0:0 |
8367
// ------------------------
84-
const INTERNED_INDEX_SIZE: u32 = 30;
85-
const INTERNED_INDEX_OFFSET: u32 = 2;
68+
const INTERNED_INDEX_SIZE: u32 = 31;
69+
const INTERNED_INDEX_OFFSET: u32 = 1;
8670

8771
fn encode(sd: &SpanData) -> Span {
8872
let (base, len, ctxt) = (sd.lo.0, sd.hi.0 - sd.lo.0, sd.ctxt.0);
8973

90-
// Can we fit the span data into this encoding?
91-
let fits = |sizes: [u32; 3]| {
92-
(base >> sizes[BASE_INDEX]) == 0 && (len >> sizes[LEN_INDEX]) == 0 &&
93-
(ctxt >> sizes[CTXT_INDEX]) == 0
94-
};
95-
// Turn fields into a single `u32` value.
96-
let compose = |offsets: [u32; 3], tag| {
97-
(base << offsets[BASE_INDEX]) | (len << offsets[LEN_INDEX]) |
98-
(ctxt << offsets[CTXT_INDEX]) | tag
99-
};
100-
101-
let val = if fits(INLINE0_SIZES) {
102-
compose(INLINE0_OFFSETS, TAG_INLINE0)
103-
} else if fits(INLINE1_SIZES) {
104-
compose(INLINE1_OFFSETS, TAG_INLINE1)
105-
} else if fits(INLINE2_SIZES) {
106-
compose(INLINE2_OFFSETS, TAG_INLINE2)
74+
let val = if (base >> INLINE_SIZES[BASE_INDEX]) == 0 &&
75+
(len >> INLINE_SIZES[LEN_INDEX]) == 0 &&
76+
(ctxt >> INLINE_SIZES[CTXT_INDEX]) == 0 {
77+
(base << INLINE_OFFSETS[BASE_INDEX]) | (len << INLINE_OFFSETS[LEN_INDEX]) |
78+
(ctxt << INLINE_OFFSETS[CTXT_INDEX]) | TAG_INLINE
10779
} else {
10880
let index = with_span_interner(|interner| interner.intern(sd));
109-
if (index >> INTERNED_INDEX_SIZE) == 0 {
110-
(index << INTERNED_INDEX_OFFSET) | TAG_INTERNED
111-
} else {
112-
panic!("too many spans in a crate");
113-
}
81+
(index << INTERNED_INDEX_OFFSET) | TAG_INTERNED
11482
};
11583
Span(val)
11684
}
@@ -119,32 +87,18 @@ fn decode(span: Span) -> SpanData {
11987
let val = span.0;
12088

12189
// Extract a field at position `pos` having size `size`.
122-
let extract = |pos, size| {
90+
let extract = |pos: u32, size: u32| {
12391
let mask = ((!0u32) as u64 >> (32 - size)) as u32; // Can't shift u32 by 32
12492
(val >> pos) & mask
12593
};
12694

127-
let (base, len, ctxt) = match val & TAG_MASK {
128-
TAG_INLINE0 => (
129-
extract(INLINE0_OFFSETS[BASE_INDEX], INLINE0_SIZES[BASE_INDEX]),
130-
extract(INLINE0_OFFSETS[LEN_INDEX], INLINE0_SIZES[LEN_INDEX]),
131-
extract(INLINE0_OFFSETS[CTXT_INDEX], INLINE0_SIZES[CTXT_INDEX]),
132-
),
133-
TAG_INLINE1 => (
134-
extract(INLINE1_OFFSETS[BASE_INDEX], INLINE1_SIZES[BASE_INDEX]),
135-
extract(INLINE1_OFFSETS[LEN_INDEX], INLINE1_SIZES[LEN_INDEX]),
136-
extract(INLINE1_OFFSETS[CTXT_INDEX], INLINE1_SIZES[CTXT_INDEX]),
137-
),
138-
TAG_INLINE2 => (
139-
extract(INLINE2_OFFSETS[BASE_INDEX], INLINE2_SIZES[BASE_INDEX]),
140-
extract(INLINE2_OFFSETS[LEN_INDEX], INLINE2_SIZES[LEN_INDEX]),
141-
extract(INLINE2_OFFSETS[CTXT_INDEX], INLINE2_SIZES[CTXT_INDEX]),
142-
),
143-
TAG_INTERNED => {
144-
let index = extract(INTERNED_INDEX_OFFSET, INTERNED_INDEX_SIZE);
145-
return with_span_interner(|interner| *interner.get(index));
146-
}
147-
_ => unreachable!()
95+
let (base, len, ctxt) = if val & TAG_MASK == TAG_INLINE {(
96+
extract(INLINE_OFFSETS[BASE_INDEX], INLINE_SIZES[BASE_INDEX]),
97+
extract(INLINE_OFFSETS[LEN_INDEX], INLINE_SIZES[LEN_INDEX]),
98+
extract(INLINE_OFFSETS[CTXT_INDEX], INLINE_SIZES[CTXT_INDEX]),
99+
)} else {
100+
let index = extract(INTERNED_INDEX_OFFSET, INTERNED_INDEX_SIZE);
101+
return with_span_interner(|interner| *interner.get(index));
148102
};
149103
SpanData { lo: BytePos(base), hi: BytePos(base + len), ctxt: SyntaxContext(ctxt) }
150104
}

0 commit comments

Comments
 (0)