@@ -45,72 +45,40 @@ impl Span {
45
45
}
46
46
47
47
// 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 ;
53
51
54
52
// Fields indexes
55
53
const BASE_INDEX : usize = 0 ;
56
54
const LEN_INDEX : usize = 1 ;
57
55
const CTXT_INDEX : usize = 2 ;
58
56
59
- // Tag = 0b00 , inline format 0 .
57
+ // Tag = 0 , inline format.
60
58
// -----------------------------------
61
- // | base 31:8 | len 7:2 | tag 1 :0 |
59
+ // | base 31:8 | len 7:1 | tag 0 :0 |
62
60
// -----------------------------------
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 ] ;
65
63
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.
81
65
// ------------------------
82
- // | index 31:3 | tag 1 :0 |
66
+ // | index 31:1 | tag 0 :0 |
83
67
// ------------------------
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 ;
86
70
87
71
fn encode ( sd : & SpanData ) -> Span {
88
72
let ( base, len, ctxt) = ( sd. lo . 0 , sd. hi . 0 - sd. lo . 0 , sd. ctxt . 0 ) ;
89
73
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
107
79
} else {
108
80
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
114
82
} ;
115
83
Span ( val)
116
84
}
@@ -119,32 +87,18 @@ fn decode(span: Span) -> SpanData {
119
87
let val = span. 0 ;
120
88
121
89
// Extract a field at position `pos` having size `size`.
122
- let extract = |pos, size| {
90
+ let extract = |pos : u32 , size : u32 | {
123
91
let mask = ( ( !0u32 ) as u64 >> ( 32 - size) ) as u32 ; // Can't shift u32 by 32
124
92
( val >> pos) & mask
125
93
} ;
126
94
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) ) ;
148
102
} ;
149
103
SpanData { lo : BytePos ( base) , hi : BytePos ( base + len) , ctxt : SyntaxContext ( ctxt) }
150
104
}
0 commit comments