1
1
use std:: cell:: RefCell ;
2
+ use std:: collections:: HashSet ;
3
+ use std:: rc:: Rc ;
2
4
3
5
use rustc:: ty:: { self , layout:: Size } ;
4
6
use rustc:: hir:: { Mutability , MutMutable , MutImmutable } ;
@@ -10,6 +12,7 @@ use crate::{
10
12
} ;
11
13
12
14
pub type Timestamp = u64 ;
15
+ pub type CallId = u64 ;
13
16
14
17
/// Information about which kind of borrow was used to create the reference this is tagged
15
18
/// with.
@@ -80,15 +83,6 @@ pub struct Stack {
80
83
frozen_since : Option < Timestamp > , // virtual frozen "item" on top of the stack
81
84
}
82
85
83
- impl Default for Stack {
84
- fn default ( ) -> Self {
85
- Stack {
86
- borrows : vec ! [ BorStackItem :: Shr ] ,
87
- frozen_since : None ,
88
- }
89
- }
90
- }
91
-
92
86
impl Stack {
93
87
#[ inline( always) ]
94
88
pub fn is_frozen ( & self ) -> bool {
@@ -107,17 +101,50 @@ pub enum RefKind {
107
101
Raw ,
108
102
}
109
103
104
+ /// Extra global state in the memory, available to the memory access hooks
105
+ #[ derive( Debug ) ]
106
+ pub struct BarrierTracking {
107
+ next_id : CallId ,
108
+ active_calls : HashSet < CallId > ,
109
+ }
110
+ pub type MemoryState = Rc < RefCell < BarrierTracking > > ;
111
+
112
+ impl Default for BarrierTracking {
113
+ fn default ( ) -> Self {
114
+ BarrierTracking {
115
+ next_id : 0 ,
116
+ active_calls : HashSet :: default ( ) ,
117
+ }
118
+ }
119
+ }
120
+
121
+ impl BarrierTracking {
122
+ pub fn new_call ( & mut self ) -> CallId {
123
+ let id = self . next_id ;
124
+ trace ! ( "new_call: Assigning ID {}" , id) ;
125
+ self . active_calls . insert ( id) ;
126
+ self . next_id += 1 ;
127
+ id
128
+ }
129
+
130
+ pub fn end_call ( & mut self , id : CallId ) {
131
+ assert ! ( self . active_calls. remove( & id) ) ;
132
+ }
133
+ }
134
+
110
135
/// Extra global machine state
111
136
#[ derive( Clone , Debug ) ]
112
137
pub struct State {
113
138
clock : Timestamp
114
139
}
115
140
116
- impl State {
117
- pub fn new ( ) -> State {
141
+ impl Default for State {
142
+ fn default ( ) -> Self {
118
143
State { clock : 0 }
119
144
}
145
+ }
120
146
147
+ impl State {
121
148
fn increment_clock ( & mut self ) -> Timestamp {
122
149
let val = self . clock ;
123
150
self . clock = val + 1 ;
@@ -130,6 +157,7 @@ impl State {
130
157
pub struct Stacks {
131
158
// Even reading memory can have effects on the stack, so we need a `RefCell` here.
132
159
stacks : RefCell < RangeMap < Stack > > ,
160
+ barrier_tracking : MemoryState ,
133
161
}
134
162
135
163
/// Core per-location operations: deref, access, create.
@@ -358,11 +386,16 @@ impl<'tcx> Stacks {
358
386
}
359
387
360
388
/// Hooks and glue
361
- impl AllocationExtra < Borrow , ( ) > for Stacks {
389
+ impl AllocationExtra < Borrow , MemoryState > for Stacks {
362
390
#[ inline( always) ]
363
- fn memory_allocated < ' tcx > ( size : Size , _extra : & ( ) ) -> Self {
391
+ fn memory_allocated < ' tcx > ( size : Size , extra : & MemoryState ) -> Self {
392
+ let stack = Stack {
393
+ borrows : vec ! [ BorStackItem :: Shr ] ,
394
+ frozen_since : None ,
395
+ } ;
364
396
Stacks {
365
- stacks : RefCell :: new ( RangeMap :: new ( size, Stack :: default ( ) ) )
397
+ stacks : RefCell :: new ( RangeMap :: new ( size, stack) ) ,
398
+ barrier_tracking : Rc :: clone ( extra) ,
366
399
}
367
400
}
368
401
0 commit comments