@@ -41,25 +41,31 @@ impl Into<MemoryKind<MiriMemoryKind>> for MiriMemoryKind {
4141/// Extra per-allocation data
4242#[ derive( Debug , Clone ) ]
4343pub struct AllocExtra {
44- pub stacked_borrows : stacked_borrows:: AllocExtra ,
44+ /// Stacked Borrows state is only added if validation is enabled.
45+ pub stacked_borrows : Option < stacked_borrows:: AllocExtra > ,
4546}
4647
4748/// Extra global memory data
4849#[ derive( Default , Clone , Debug ) ]
4950pub struct MemoryExtra {
5051 pub stacked_borrows : stacked_borrows:: MemoryExtra ,
5152 pub intptrcast : intptrcast:: MemoryExtra ,
53+
5254 /// The random number generator to use if Miri is running in non-deterministic mode and to
5355 /// enable intptrcast
54- pub ( crate ) rng : Option < RefCell < StdRng > >
56+ pub ( crate ) rng : Option < RefCell < StdRng > > ,
57+
58+ /// Whether to enforce the validity invariant.
59+ pub ( crate ) validate : bool ,
5560}
5661
5762impl MemoryExtra {
58- pub fn with_rng ( rng : Option < StdRng > ) -> Self {
63+ pub fn new ( rng : Option < StdRng > , validate : bool ) -> Self {
5964 MemoryExtra {
6065 stacked_borrows : Default :: default ( ) ,
6166 intptrcast : Default :: default ( ) ,
6267 rng : rng. map ( RefCell :: new) ,
68+ validate,
6369 }
6470 }
6571}
@@ -82,21 +88,17 @@ pub struct Evaluator<'tcx> {
8288
8389 /// TLS state.
8490 pub ( crate ) tls : TlsData < ' tcx > ,
85-
86- /// Whether to enforce the validity invariant.
87- pub ( crate ) validate : bool ,
8891}
8992
9093impl < ' tcx > Evaluator < ' tcx > {
91- pub ( crate ) fn new ( validate : bool ) -> Self {
94+ pub ( crate ) fn new ( ) -> Self {
9295 Evaluator {
9396 env_vars : HashMap :: default ( ) ,
9497 argc : None ,
9598 argv : None ,
9699 cmd_line : None ,
97100 last_error : 0 ,
98101 tls : TlsData :: default ( ) ,
99- validate,
100102 }
101103 }
102104}
@@ -135,7 +137,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
135137
136138 #[ inline( always) ]
137139 fn enforce_validity ( ecx : & InterpretCx < ' mir , ' tcx , Self > ) -> bool {
138- ecx. machine . validate
140+ ecx. memory ( ) . extra . validate
139141 }
140142
141143 /// Returns `Ok()` when the function was handled; fail otherwise.
@@ -251,12 +253,17 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
251253 ) -> ( Cow < ' b , Allocation < Self :: PointerTag , Self :: AllocExtra > > , Self :: PointerTag ) {
252254 let kind = kind. expect ( "we set our STATIC_KIND so this cannot be None" ) ;
253255 let alloc = alloc. into_owned ( ) ;
254- let ( stacks, base_tag) = Stacks :: new_allocation (
255- id,
256- Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) ,
257- Rc :: clone ( & memory. extra . stacked_borrows ) ,
258- kind,
259- ) ;
256+ let ( stacks, base_tag) = if !memory. extra . validate {
257+ ( None , Tag :: Untagged )
258+ } else {
259+ let ( stacks, base_tag) = Stacks :: new_allocation (
260+ id,
261+ Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) ,
262+ Rc :: clone ( & memory. extra . stacked_borrows ) ,
263+ kind,
264+ ) ;
265+ ( Some ( stacks) , base_tag)
266+ } ;
260267 if kind != MiriMemoryKind :: Static . into ( ) {
261268 assert ! ( alloc. relocations. is_empty( ) , "Only statics can come initialized with inner pointers" ) ;
262269 // Now we can rely on the inner pointers being static, too.
@@ -268,7 +275,14 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
268275 alloc. relocations . iter ( )
269276 // The allocations in the relocations (pointers stored *inside* this allocation)
270277 // all get the base pointer tag.
271- . map ( |& ( offset, ( ( ) , alloc) ) | ( offset, ( memory_extra. static_base_ptr ( alloc) , alloc) ) )
278+ . map ( |& ( offset, ( ( ) , alloc) ) | {
279+ let tag = if !memory. extra . validate {
280+ Tag :: Untagged
281+ } else {
282+ memory_extra. static_base_ptr ( alloc)
283+ } ;
284+ ( offset, ( tag, alloc) )
285+ } )
272286 . collect ( )
273287 ) ,
274288 undef_mask : alloc. undef_mask ,
@@ -286,7 +300,11 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
286300 id : AllocId ,
287301 memory : & Memory < ' mir , ' tcx , Self > ,
288302 ) -> Self :: PointerTag {
289- memory. extra . stacked_borrows . borrow_mut ( ) . static_base_ptr ( id)
303+ if !memory. extra . validate {
304+ Tag :: Untagged
305+ } else {
306+ memory. extra . stacked_borrows . borrow_mut ( ) . static_base_ptr ( id)
307+ }
290308 }
291309
292310 #[ inline( always) ]
@@ -295,12 +313,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
295313 kind : mir:: RetagKind ,
296314 place : PlaceTy < ' tcx , Tag > ,
297315 ) -> InterpResult < ' tcx > {
298- if !ecx. tcx . sess . opts . debugging_opts . mir_emit_retag || !Self :: enforce_validity ( ecx) {
299- // No tracking, or no retagging. The latter is possible because a dependency of ours
300- // might be called with different flags than we are, so there are `Retag`
301- // statements but we do not want to execute them.
302- // Also, honor the whitelist in `enforce_validity` because otherwise we might retag
303- // uninitialized data.
316+ if !Self :: enforce_validity ( ecx) {
317+ // No tracking.
304318 Ok ( ( ) )
305319 } else {
306320 ecx. retag ( kind, place)
@@ -354,7 +368,11 @@ impl AllocationExtra<Tag> for AllocExtra {
354368 ptr : Pointer < Tag > ,
355369 size : Size ,
356370 ) -> InterpResult < ' tcx > {
357- alloc. extra . stacked_borrows . memory_read ( ptr, size)
371+ if let Some ( ref stacked_borrows) = alloc. extra . stacked_borrows {
372+ stacked_borrows. memory_read ( ptr, size)
373+ } else {
374+ Ok ( ( ) )
375+ }
358376 }
359377
360378 #[ inline( always) ]
@@ -363,7 +381,11 @@ impl AllocationExtra<Tag> for AllocExtra {
363381 ptr : Pointer < Tag > ,
364382 size : Size ,
365383 ) -> InterpResult < ' tcx > {
366- alloc. extra . stacked_borrows . memory_written ( ptr, size)
384+ if let Some ( ref mut stacked_borrows) = alloc. extra . stacked_borrows {
385+ stacked_borrows. memory_written ( ptr, size)
386+ } else {
387+ Ok ( ( ) )
388+ }
367389 }
368390
369391 #[ inline( always) ]
@@ -372,7 +394,11 @@ impl AllocationExtra<Tag> for AllocExtra {
372394 ptr : Pointer < Tag > ,
373395 size : Size ,
374396 ) -> InterpResult < ' tcx > {
375- alloc. extra . stacked_borrows . memory_deallocated ( ptr, size)
397+ if let Some ( ref mut stacked_borrows) = alloc. extra . stacked_borrows {
398+ stacked_borrows. memory_deallocated ( ptr, size)
399+ } else {
400+ Ok ( ( ) )
401+ }
376402 }
377403}
378404
0 commit comments