@@ -457,14 +457,29 @@ impl<'tcx> Stacks {
457
457
& self ,
458
458
ptr : Pointer < Tag > ,
459
459
size : Size ,
460
- global : & GlobalState ,
461
- f : impl Fn ( Pointer < Tag > , & mut Stack , & GlobalState ) -> InterpResult < ' tcx > ,
460
+ f : impl Fn ( Pointer < Tag > , & mut Stack ) -> InterpResult < ' tcx > ,
462
461
) -> InterpResult < ' tcx > {
463
462
let mut stacks = self . stacks . borrow_mut ( ) ;
464
463
for ( offset, stack) in stacks. iter_mut ( ptr. offset , size) {
465
464
let mut cur_ptr = ptr;
466
465
cur_ptr. offset = offset;
467
- f ( cur_ptr, stack, & * global) ?;
466
+ f ( cur_ptr, stack) ?;
467
+ }
468
+ Ok ( ( ) )
469
+ }
470
+
471
+ /// Call `f` on every stack in the range.
472
+ fn for_each_mut (
473
+ & mut self ,
474
+ ptr : Pointer < Tag > ,
475
+ size : Size ,
476
+ f : impl Fn ( Pointer < Tag > , & mut Stack ) -> InterpResult < ' tcx > ,
477
+ ) -> InterpResult < ' tcx > {
478
+ let stacks = self . stacks . get_mut ( ) ;
479
+ for ( offset, stack) in stacks. iter_mut ( ptr. offset , size) {
480
+ let mut cur_ptr = ptr;
481
+ cur_ptr. offset = offset;
482
+ f ( cur_ptr, stack) ?;
468
483
}
469
484
Ok ( ( ) )
470
485
}
@@ -516,9 +531,8 @@ impl Stacks {
516
531
extra : & MemoryExtra ,
517
532
) -> InterpResult < ' tcx > {
518
533
trace ! ( "read access with tag {:?}: {:?}, size {}" , ptr. tag, ptr. erase_tag( ) , size. bytes( ) ) ;
519
- self . for_each ( ptr, size, & * extra. borrow ( ) , |ptr, stack, global| {
520
- stack. access ( AccessKind :: Read , ptr, global)
521
- } )
534
+ let global = & * extra. borrow ( ) ;
535
+ self . for_each ( ptr, size, move |ptr, stack| stack. access ( AccessKind :: Read , ptr, global) )
522
536
}
523
537
524
538
#[ inline( always) ]
@@ -529,9 +543,8 @@ impl Stacks {
529
543
extra : & mut MemoryExtra ,
530
544
) -> InterpResult < ' tcx > {
531
545
trace ! ( "write access with tag {:?}: {:?}, size {}" , ptr. tag, ptr. erase_tag( ) , size. bytes( ) ) ;
532
- self . for_each ( ptr, size, extra. get_mut ( ) , |ptr, stack, global| {
533
- stack. access ( AccessKind :: Write , ptr, global)
534
- } )
546
+ let global = extra. get_mut ( ) ;
547
+ self . for_each_mut ( ptr, size, move |ptr, stack| stack. access ( AccessKind :: Write , ptr, global) )
535
548
}
536
549
537
550
#[ inline( always) ]
@@ -542,7 +555,8 @@ impl Stacks {
542
555
extra : & mut MemoryExtra ,
543
556
) -> InterpResult < ' tcx > {
544
557
trace ! ( "deallocation with tag {:?}: {:?}, size {}" , ptr. tag, ptr. erase_tag( ) , size. bytes( ) ) ;
545
- self . for_each ( ptr, size, extra. get_mut ( ) , |ptr, stack, global| stack. dealloc ( ptr, global) )
558
+ let global = extra. get_mut ( ) ;
559
+ self . for_each_mut ( ptr, size, move |ptr, stack| stack. dealloc ( ptr, global) )
546
560
}
547
561
}
548
562
@@ -571,12 +585,6 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
571
585
size. bytes( )
572
586
) ;
573
587
574
- // Get the allocation. We need both the allocation and the MemoryExtra, so we cannot use `&mut`.
575
- // FIXME: make `get_alloc_extra_mut` also return `&mut MemoryExtra`.
576
- let extra = this. memory . get_alloc_extra ( ptr. alloc_id ) ?;
577
- let stacked_borrows =
578
- extra. stacked_borrows . as_ref ( ) . expect ( "we should have Stacked Borrows data" ) ;
579
- let global = this. memory . extra . stacked_borrows . as_ref ( ) . unwrap ( ) . borrow ( ) ;
580
588
// Update the stacks.
581
589
// Make sure that raw pointers and mutable shared references are reborrowed "weak":
582
590
// There could be existing unique pointers reborrowed from them that should remain valid!
@@ -588,6 +596,12 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
588
596
// Shared references and *const are a whole different kind of game, the
589
597
// permission is not uniform across the entire range!
590
598
// We need a frozen-sensitive reborrow.
599
+ // We have to use shared references to alloc/memory_extra here since
600
+ // `visit_freeze_sensitive` needs to access the global state.
601
+ let extra = this. memory . get_alloc_extra ( ptr. alloc_id ) ?;
602
+ let stacked_borrows =
603
+ extra. stacked_borrows . as_ref ( ) . expect ( "we should have Stacked Borrows data" ) ;
604
+ let global = this. memory . extra . stacked_borrows . as_ref ( ) . unwrap ( ) . borrow ( ) ;
591
605
return this. visit_freeze_sensitive ( place, size, |cur_ptr, size, frozen| {
592
606
// We are only ever `SharedReadOnly` inside the frozen bits.
593
607
let perm = if frozen {
@@ -596,15 +610,19 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
596
610
Permission :: SharedReadWrite
597
611
} ;
598
612
let item = Item { perm, tag : new_tag, protector } ;
599
- stacked_borrows. for_each ( cur_ptr, size, & * global , |cur_ptr, stack, global | {
600
- stack. grant ( cur_ptr, item, global)
613
+ stacked_borrows. for_each ( cur_ptr, size, |cur_ptr, stack| {
614
+ stack. grant ( cur_ptr, item, & * global)
601
615
} )
602
616
} ) ;
603
617
}
604
618
} ;
619
+ // Here we can avoid `borrow()` calls because we have mutable references.
620
+ let ( alloc_extra, memory_extra) = this. memory . get_alloc_extra_mut ( ptr. alloc_id ) ?;
621
+ let stacked_borrows =
622
+ alloc_extra. stacked_borrows . as_mut ( ) . expect ( "we should have Stacked Borrows data" ) ;
623
+ let global = memory_extra. stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) ;
605
624
let item = Item { perm, tag : new_tag, protector } ;
606
- stacked_borrows
607
- . for_each ( ptr, size, & * global, |ptr, stack, global| stack. grant ( ptr, item, global) )
625
+ stacked_borrows. for_each_mut ( ptr, size, |ptr, stack| stack. grant ( ptr, item, global) )
608
626
}
609
627
610
628
/// Retags an indidual pointer, returning the retagged version.
@@ -640,7 +658,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
640
658
641
659
// Compute new borrow.
642
660
let new_tag = {
643
- let mut mem_extra = this. memory . extra . stacked_borrows . as_ref ( ) . unwrap ( ) . borrow_mut ( ) ;
661
+ let mem_extra = this. memory . extra . stacked_borrows . as_mut ( ) . unwrap ( ) . get_mut ( ) ;
644
662
match kind {
645
663
// Give up tracking for raw pointers.
646
664
RefKind :: Raw { .. } if !mem_extra. track_raw => Tag :: Untagged ,
0 commit comments