@@ -25,7 +25,8 @@ use diagnostics::{AllocHistory, TagHistory};
25
25
26
26
pub type PtrId = NonZeroU64 ;
27
27
pub type CallId = NonZeroU64 ;
28
- pub type AllocExtra = Stacks ;
28
+ // Even reading memory can have effects on the stack, so we need a `RefCell` here.
29
+ pub type AllocExtra = RefCell < Stacks > ;
29
30
30
31
/// Tracking pointer provenance
31
32
#[ derive( Copy , Clone , Hash , Eq ) ]
@@ -131,7 +132,7 @@ pub struct Stack {
131
132
/// * Above a `SharedReadOnly` there can only be more `SharedReadOnly`.
132
133
/// * Except for `Untagged`, no tag occurs in the stack more than once.
133
134
borrows : Vec < Item > ,
134
- /// If this is `Some(id)`, then the actual current stack is unknown. THis can happen when
135
+ /// If this is `Some(id)`, then the actual current stack is unknown. This can happen when
135
136
/// wildcard pointers are used to access this location. What we do know is that `borrows` are at
136
137
/// the top of the stack, and below it are arbitrarily many items whose `tag` is either
137
138
/// `Untagged` or strictly less than `id`.
@@ -144,11 +145,11 @@ pub struct Stack {
144
145
#[ derive( Clone , Debug ) ]
145
146
pub struct Stacks {
146
147
// Even reading memory can have effects on the stack, so we need a `RefCell` here.
147
- stacks : RefCell < RangeMap < Stack > > ,
148
+ stacks : RangeMap < Stack > ,
148
149
/// Stores past operations on this allocation
149
- history : RefCell < AllocHistory > ,
150
+ history : AllocHistory ,
150
151
/// The set of tags that have been exposed inside this allocation.
151
- exposed_tags : RefCell < FxHashSet < SbTag > > ,
152
+ exposed_tags : FxHashSet < SbTag > ,
152
153
}
153
154
154
155
/// Extra global state, available to the memory access hooks.
@@ -689,34 +690,14 @@ impl<'tcx> Stacks {
689
690
let stack = Stack { borrows : vec ! [ item] , unknown_bottom : None } ;
690
691
691
692
Stacks {
692
- stacks : RefCell :: new ( RangeMap :: new ( size, stack) ) ,
693
- history : RefCell :: new ( AllocHistory :: new ( ) ) ,
694
- exposed_tags : RefCell :: new ( FxHashSet :: default ( ) ) ,
693
+ stacks : RangeMap :: new ( size, stack) ,
694
+ history : AllocHistory :: new ( ) ,
695
+ exposed_tags : FxHashSet :: default ( ) ,
695
696
}
696
697
}
697
698
698
699
/// Call `f` on every stack in the range.
699
700
fn for_each (
700
- & self ,
701
- range : AllocRange ,
702
- mut f : impl FnMut (
703
- Size ,
704
- & mut Stack ,
705
- & mut AllocHistory ,
706
- & mut FxHashSet < SbTag > ,
707
- ) -> InterpResult < ' tcx > ,
708
- ) -> InterpResult < ' tcx > {
709
- let mut stacks = self . stacks . borrow_mut ( ) ;
710
- let history = & mut * self . history . borrow_mut ( ) ;
711
- let exposed_tags = & mut * self . exposed_tags . borrow_mut ( ) ;
712
- for ( offset, stack) in stacks. iter_mut ( range. start , range. size ) {
713
- f ( offset, stack, history, exposed_tags) ?;
714
- }
715
- Ok ( ( ) )
716
- }
717
-
718
- /// Call `f` on every stack in the range.
719
- fn for_each_mut (
720
701
& mut self ,
721
702
range : AllocRange ,
722
703
mut f : impl FnMut (
@@ -726,11 +707,8 @@ impl<'tcx> Stacks {
726
707
& mut FxHashSet < SbTag > ,
727
708
) -> InterpResult < ' tcx > ,
728
709
) -> InterpResult < ' tcx > {
729
- let stacks = self . stacks . get_mut ( ) ;
730
- let history = & mut * self . history . get_mut ( ) ;
731
- let exposed_tags = self . exposed_tags . get_mut ( ) ;
732
- for ( offset, stack) in stacks. iter_mut ( range. start , range. size ) {
733
- f ( offset, stack, history, exposed_tags) ?;
710
+ for ( offset, stack) in self . stacks . iter_mut ( range. start , range. size ) {
711
+ f ( offset, stack, & mut self . history , & mut self . exposed_tags ) ?;
734
712
}
735
713
Ok ( ( ) )
736
714
}
@@ -777,8 +755,8 @@ impl Stacks {
777
755
( tag, Permission :: SharedReadWrite )
778
756
}
779
757
} ;
780
- let stacks = Stacks :: new ( size, perm, base_tag) ;
781
- stacks. history . borrow_mut ( ) . log_creation (
758
+ let mut stacks = Stacks :: new ( size, perm, base_tag) ;
759
+ stacks. history . log_creation (
782
760
None ,
783
761
base_tag,
784
762
alloc_range ( Size :: ZERO , size) ,
@@ -789,7 +767,7 @@ impl Stacks {
789
767
790
768
#[ inline( always) ]
791
769
pub fn memory_read < ' tcx > (
792
- & self ,
770
+ & mut self ,
793
771
alloc_id : AllocId ,
794
772
tag : SbTagExtra ,
795
773
range : AllocRange ,
@@ -832,7 +810,7 @@ impl Stacks {
832
810
range. size. bytes( )
833
811
) ;
834
812
let mut state = state. borrow_mut ( ) ;
835
- self . for_each_mut ( range, |offset, stack, history, exposed_tags| {
813
+ self . for_each ( range, |offset, stack, history, exposed_tags| {
836
814
stack. access (
837
815
AccessKind :: Write ,
838
816
tag,
@@ -855,7 +833,7 @@ impl Stacks {
855
833
) -> InterpResult < ' tcx > {
856
834
trace ! ( "deallocation with tag {:?}: {:?}, size {}" , tag, alloc_id, range. size. bytes( ) ) ;
857
835
let state = state. borrow ( ) ;
858
- self . for_each_mut ( range, |offset, stack, history, exposed_tags| {
836
+ self . for_each ( range, |offset, stack, history, exposed_tags| {
859
837
stack. dealloc ( tag, ( alloc_id, range, offset) , & state, history, exposed_tags)
860
838
} ) ?;
861
839
Ok ( ( ) )
@@ -890,17 +868,19 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
890
868
return Ok ( ( ) )
891
869
} ;
892
870
let extra = this. get_alloc_extra ( alloc_id) ?;
893
- let stacked_borrows =
894
- extra. stacked_borrows . as_ref ( ) . expect ( "we should have Stacked Borrows data" ) ;
895
- let mut alloc_history = stacked_borrows. history . borrow_mut ( ) ;
896
- alloc_history. log_creation (
871
+ let mut stacked_borrows = extra
872
+ . stacked_borrows
873
+ . as_ref ( )
874
+ . expect ( "we should have Stacked Borrows data" )
875
+ . borrow_mut ( ) ;
876
+ stacked_borrows. history . log_creation (
897
877
Some ( orig_tag) ,
898
878
new_tag,
899
879
alloc_range ( base_offset, size) ,
900
880
current_span,
901
881
) ;
902
882
if protect {
903
- alloc_history . log_protector ( orig_tag, new_tag, current_span) ;
883
+ stacked_borrows . history . log_protector ( orig_tag, new_tag, current_span) ;
904
884
}
905
885
Ok ( ( ) )
906
886
} ;
@@ -976,8 +956,11 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
976
956
// We have to use shared references to alloc/memory_extra here since
977
957
// `visit_freeze_sensitive` needs to access the global state.
978
958
let extra = this. get_alloc_extra ( alloc_id) ?;
979
- let stacked_borrows =
980
- extra. stacked_borrows . as_ref ( ) . expect ( "we should have Stacked Borrows data" ) ;
959
+ let mut stacked_borrows = extra
960
+ . stacked_borrows
961
+ . as_ref ( )
962
+ . expect ( "we should have Stacked Borrows data" )
963
+ . borrow_mut ( ) ;
981
964
this. visit_freeze_sensitive ( place, size, |mut range, frozen| {
982
965
// Adjust range.
983
966
range. start += base_offset;
@@ -1015,13 +998,16 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1015
998
// Note that this asserts that the allocation is mutable -- but since we are creating a
1016
999
// mutable pointer, that seems reasonable.
1017
1000
let ( alloc_extra, machine) = this. get_alloc_extra_mut ( alloc_id) ?;
1018
- let stacked_borrows =
1019
- alloc_extra. stacked_borrows . as_mut ( ) . expect ( "we should have Stacked Borrows data" ) ;
1001
+ let mut stacked_borrows = alloc_extra
1002
+ . stacked_borrows
1003
+ . as_mut ( )
1004
+ . expect ( "we should have Stacked Borrows data" )
1005
+ . borrow_mut ( ) ;
1020
1006
let item = Item { perm, tag : new_tag, protector } ;
1021
1007
let range = alloc_range ( base_offset, size) ;
1022
1008
let mut global = machine. stacked_borrows . as_ref ( ) . unwrap ( ) . borrow_mut ( ) ;
1023
1009
let current_span = & mut machine. current_span ( ) ; // `get_alloc_extra_mut` invalidated our old `current_span`
1024
- stacked_borrows. for_each_mut ( range, |offset, stack, history, exposed_tags| {
1010
+ stacked_borrows. for_each ( range, |offset, stack, history, exposed_tags| {
1025
1011
stack. grant (
1026
1012
orig_tag,
1027
1013
item,
@@ -1177,7 +1163,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1177
1163
match this. get_alloc_extra ( alloc_id) {
1178
1164
Ok ( alloc_extra) => {
1179
1165
trace ! ( "Stacked Borrows tag {tag:?} exposed in {alloc_id}" ) ;
1180
- alloc_extra. stacked_borrows . as_ref ( ) . unwrap ( ) . exposed_tags . borrow_mut ( ) . insert ( tag) ;
1166
+ alloc_extra. stacked_borrows . as_ref ( ) . unwrap ( ) . borrow_mut ( ) . exposed_tags . insert ( tag) ;
1181
1167
}
1182
1168
Err ( err) => {
1183
1169
trace ! (
0 commit comments