@@ -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
5553const BASE_INDEX : usize = 0 ;
5654const LEN_INDEX : usize = 1 ;
5755const 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
8771fn 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