@@ -8,7 +8,7 @@ use rustc::hir::{Mutability, MutMutable, MutImmutable};
8
8
use crate :: {
9
9
EvalResult , EvalErrorKind , MiriEvalContext , HelpersEvalContextExt , Evaluator , MutValueVisitor ,
10
10
MemoryKind , MiriMemoryKind , RangeMap , AllocId , Allocation , AllocationExtra ,
11
- Pointer , MemPlace , Scalar , Immediate , ImmTy , PlaceTy , MPlaceTy ,
11
+ Pointer , Immediate , ImmTy , PlaceTy , MPlaceTy ,
12
12
} ;
13
13
14
14
pub type Timestamp = u64 ;
@@ -534,19 +534,21 @@ pub trait EvalContextExt<'tcx> {
534
534
size : Size ,
535
535
fn_barrier : bool ,
536
536
new_bor : Borrow
537
- ) -> EvalResult < ' tcx , Pointer < Borrow > > ;
537
+ ) -> EvalResult < ' tcx > ;
538
538
539
539
/// Retag an indidual pointer, returning the retagged version.
540
540
fn retag_reference (
541
541
& mut self ,
542
542
ptr : ImmTy < ' tcx , Borrow > ,
543
543
mutbl : Mutability ,
544
544
fn_barrier : bool ,
545
+ two_phase : bool ,
545
546
) -> EvalResult < ' tcx , Immediate < Borrow > > ;
546
547
547
548
fn retag (
548
549
& mut self ,
549
550
fn_entry : bool ,
551
+ two_phase : bool ,
550
552
place : PlaceTy < ' tcx , Borrow >
551
553
) -> EvalResult < ' tcx > ;
552
554
@@ -644,9 +646,8 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
644
646
size : Size ,
645
647
fn_barrier : bool ,
646
648
new_bor : Borrow
647
- ) -> EvalResult < ' tcx , Pointer < Borrow > > {
649
+ ) -> EvalResult < ' tcx > {
648
650
let ptr = place. ptr . to_ptr ( ) ?;
649
- let new_ptr = Pointer :: new_with_tag ( ptr. alloc_id , ptr. offset , new_bor) ;
650
651
let barrier = if fn_barrier { Some ( self . frame ( ) . extra ) } else { None } ;
651
652
trace ! ( "reborrow: Creating new reference for {:?} (pointee {}): {:?}" ,
652
653
ptr, place. layout. ty, new_bor) ;
@@ -666,14 +667,15 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
666
667
let kind = if new_bor. is_unique ( ) { RefKind :: Unique } else { RefKind :: Raw } ;
667
668
alloc. extra . reborrow ( ptr, size, barrier, new_bor, kind) ?;
668
669
}
669
- Ok ( new_ptr )
670
+ Ok ( ( ) )
670
671
}
671
672
672
673
fn retag_reference (
673
674
& mut self ,
674
675
val : ImmTy < ' tcx , Borrow > ,
675
676
mutbl : Mutability ,
676
677
fn_barrier : bool ,
678
+ two_phase : bool ,
677
679
) -> EvalResult < ' tcx , Immediate < Borrow > > {
678
680
// We want a place for where the ptr *points to*, so we get one.
679
681
let place = self . ref_to_mplace ( val) ?;
@@ -693,16 +695,24 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
693
695
} ;
694
696
695
697
// Reborrow.
696
- let new_ptr = self . reborrow ( place, size, fn_barrier, new_bor) ?;
698
+ self . reborrow ( place, size, fn_barrier, new_bor) ?;
699
+ let new_place = place. with_tag ( new_bor) ;
700
+ // Handle two-phase borrows.
701
+ if two_phase {
702
+ // We immediately share it, to allow read accesses
703
+ let two_phase_time = self . machine . stacked_borrows . increment_clock ( ) ;
704
+ let two_phase_bor = Borrow :: Shr ( Some ( two_phase_time) ) ;
705
+ self . reborrow ( new_place, size, /*fn_barrier*/ false , two_phase_bor) ?;
706
+ }
697
707
698
- // Return new ptr
699
- let new_place = MemPlace { ptr : Scalar :: Ptr ( new_ptr) , ..* place } ;
708
+ // Return new ptr.
700
709
Ok ( new_place. to_ref ( ) )
701
710
}
702
711
703
712
fn retag (
704
713
& mut self ,
705
714
fn_entry : bool ,
715
+ two_phase : bool ,
706
716
place : PlaceTy < ' tcx , Borrow >
707
717
) -> EvalResult < ' tcx > {
708
718
// Determine mutability and whether to add a barrier.
@@ -725,19 +735,20 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
725
735
if let Some ( ( mutbl, barrier) ) = qualify ( place. layout . ty , fn_entry) {
726
736
// fast path
727
737
let val = self . read_immediate ( self . place_to_op ( place) ?) ?;
728
- let val = self . retag_reference ( val, mutbl, barrier) ?;
738
+ let val = self . retag_reference ( val, mutbl, barrier, two_phase ) ?;
729
739
self . write_immediate ( val, place) ?;
730
740
return Ok ( ( ) ) ;
731
741
}
732
742
let place = self . force_allocation ( place) ?;
733
743
734
- let mut visitor = RetagVisitor { ecx : self , fn_entry } ;
744
+ let mut visitor = RetagVisitor { ecx : self , fn_entry, two_phase } ;
735
745
visitor. visit_value ( place) ?;
736
746
737
747
// The actual visitor
738
748
struct RetagVisitor < ' ecx , ' a , ' mir , ' tcx > {
739
749
ecx : & ' ecx mut MiriEvalContext < ' a , ' mir , ' tcx > ,
740
750
fn_entry : bool ,
751
+ two_phase : bool ,
741
752
}
742
753
impl < ' ecx , ' a , ' mir , ' tcx >
743
754
MutValueVisitor < ' a , ' mir , ' tcx , Evaluator < ' tcx > >
@@ -758,7 +769,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
758
769
// making it useless.
759
770
if let Some ( ( mutbl, barrier) ) = qualify ( place. layout . ty , self . fn_entry ) {
760
771
let val = self . ecx . read_immediate ( place. into ( ) ) ?;
761
- let val = self . ecx . retag_reference ( val, mutbl, barrier) ?;
772
+ let val = self . ecx . retag_reference ( val, mutbl, barrier, self . two_phase ) ?;
762
773
self . ecx . write_immediate ( val, place. into ( ) ) ?;
763
774
}
764
775
Ok ( ( ) )
0 commit comments