@@ -17,35 +17,16 @@ const CACHE_LEN: usize = 32;
17
17
struct PackedItem ( u64 ) ;
18
18
19
19
impl PackedItem {
20
- const TAG_MASK : u64 = u64:: MAX << 2 ;
21
- const PERM_MASK : u64 = !Self :: TAG_MASK ;
22
-
23
- fn new ( tag : SbTag , perm : Permission ) -> Self {
24
- let packed_perm = match perm {
25
- Permission :: Unique => 0 ,
26
- Permission :: SharedReadWrite => 1 ,
27
- Permission :: SharedReadOnly => 2 ,
28
- Permission :: Disabled => 3 ,
29
- } ;
30
- debug_assert ! ( packed_perm & Self :: TAG_MASK == 0 ) ;
31
-
32
- let packed_tag = tag. 0 . get ( ) << 2 ;
33
- debug_assert ! ( packed_tag & Self :: PERM_MASK == 0 ) ;
34
-
35
- let new = Self ( packed_tag + packed_perm) ;
36
-
37
- debug_assert ! ( new. tag( ) == tag) ;
38
- debug_assert ! ( new. perm( ) == perm) ;
39
-
40
- new
41
- }
20
+ const TAG_MASK : u64 = u64:: MAX >> 3 ;
21
+ const PERM_MASK : u64 = 0x3 << 61 ;
22
+ const PROTECTED_MASK : u64 = 0x1 << 63 ;
42
23
43
24
fn tag ( self ) -> SbTag {
44
- unsafe { SbTag ( std:: num:: NonZeroU64 :: new_unchecked ( ( self . 0 & Self :: TAG_MASK ) >> 2 ) ) }
25
+ unsafe { SbTag ( std:: num:: NonZeroU64 :: new_unchecked ( self . 0 & Self :: TAG_MASK ) ) }
45
26
}
46
27
47
28
fn perm ( self ) -> Permission {
48
- match self . 0 & Self :: PERM_MASK {
29
+ match ( self . 0 & Self :: PERM_MASK ) >> 61 {
49
30
0 => Permission :: Unique ,
50
31
1 => Permission :: SharedReadWrite ,
51
32
2 => Permission :: SharedReadOnly ,
@@ -54,20 +35,40 @@ impl PackedItem {
54
35
}
55
36
}
56
37
38
+ fn protected ( self ) -> bool {
39
+ self . 0 & Self :: PROTECTED_MASK > 0
40
+ }
41
+
57
42
fn set_disabled ( & mut self ) {
58
- self . 0 |= 0x3 ;
43
+ self . 0 |= Self :: PERM_MASK ;
59
44
}
60
45
}
61
46
62
47
impl From < Item > for PackedItem {
63
48
fn from ( item : Item ) -> Self {
64
- Self :: new ( item. tag , item. perm )
49
+ assert ! ( item. tag. 0 . get( ) <= Self :: TAG_MASK ) ;
50
+ let perm = match item. perm {
51
+ Permission :: Unique => 0 ,
52
+ Permission :: SharedReadWrite => 1 ,
53
+ Permission :: SharedReadOnly => 2 ,
54
+ Permission :: Disabled => 3 ,
55
+ } << 61 ;
56
+ let tag = item. tag . 0 . get ( ) ;
57
+ let protected = ( item. protected as u64 ) << 63 ;
58
+
59
+ let new = Self ( tag + perm + protected) ;
60
+
61
+ debug_assert ! ( new. tag( ) == item. tag) ;
62
+ debug_assert ! ( new. perm( ) == item. perm) ;
63
+ debug_assert ! ( new. protected( ) == item. protected) ;
64
+
65
+ new
65
66
}
66
67
}
67
68
68
69
impl From < PackedItem > for Item {
69
70
fn from ( item : PackedItem ) -> Item {
70
- let new = Item { tag : item. tag ( ) , perm : item. perm ( ) } ;
71
+ let new = Item { tag : item. tag ( ) , perm : item. perm ( ) , protected : item . protected ( ) } ;
71
72
72
73
debug_assert ! ( new. tag == item. tag( ) ) ;
73
74
debug_assert ! ( new. perm == item. perm( ) ) ;
@@ -310,7 +311,7 @@ impl<'tcx> Stack {
310
311
}
311
312
312
313
// This primes the cache for the next access, which is almost always the just-added tag.
313
- self . cache . add ( new_idx, PackedItem :: new ( new. tag , new . perm ) ) ;
314
+ self . cache . add ( new_idx, PackedItem :: from ( new) ) ;
314
315
315
316
#[ cfg( feature = "expensive-debug-assertions" ) ]
316
317
self . verify_cache_consistency ( ) ;
@@ -322,10 +323,7 @@ impl<'tcx> Stack {
322
323
borrows : vec ! [ item. into( ) ] ,
323
324
unknown_bottom : None ,
324
325
#[ cfg( feature = "stack-cache" ) ]
325
- cache : StackCache {
326
- idx : [ 0 ; CACHE_LEN ] ,
327
- tags : [ PackedItem :: new ( item. tag , item. perm ) ; CACHE_LEN ] ,
328
- } ,
326
+ cache : StackCache { idx : [ 0 ; CACHE_LEN ] , tags : [ PackedItem :: from ( item) ; CACHE_LEN ] } ,
329
327
#[ cfg( feature = "stack-cache" ) ]
330
328
unique_range : if item. perm == Permission :: Unique { 0 ..1 } else { 0 ..0 } ,
331
329
}
0 commit comments