@@ -138,54 +138,82 @@ impl<T: layout::HasDataLayout> PointerArithmetic for T {}
138138/// each context.
139139///
140140/// Defaults to the index based and loosely coupled AllocId.
141+ ///
142+ /// Pointer is also generic over the `Tag` associated with each pointer,
143+ /// which is used to do provenance tracking during execution.
141144#[ derive( Copy , Clone , Debug , Eq , PartialEq , Ord , PartialOrd , RustcEncodable , RustcDecodable , Hash ) ]
142- pub struct Pointer < Id =AllocId > {
145+ pub struct Pointer < Tag = ( ) , Id =AllocId > {
143146 pub alloc_id : Id ,
144147 pub offset : Size ,
148+ pub tag : Tag ,
145149}
146150
147151/// Produces a `Pointer` which points to the beginning of the Allocation
148152impl From < AllocId > for Pointer {
153+ #[ inline( always) ]
149154 fn from ( alloc_id : AllocId ) -> Self {
150155 Pointer :: new ( alloc_id, Size :: ZERO )
151156 }
152157}
153158
154- impl < ' tcx > Pointer {
159+ impl < ' tcx > Pointer < ( ) > {
160+ #[ inline( always) ]
155161 pub fn new ( alloc_id : AllocId , offset : Size ) -> Self {
156- Pointer { alloc_id, offset }
162+ Pointer { alloc_id, offset, tag : ( ) }
163+ }
164+
165+ #[ inline( always) ]
166+ pub fn with_default_tag < Tag > ( self ) -> Pointer < Tag >
167+ where Tag : Default
168+ {
169+ Pointer :: new_with_tag ( self . alloc_id , self . offset , Default :: default ( ) )
170+ }
171+ }
172+
173+ impl < ' tcx , Tag > Pointer < Tag > {
174+ #[ inline( always) ]
175+ pub fn new_with_tag ( alloc_id : AllocId , offset : Size , tag : Tag ) -> Self {
176+ Pointer { alloc_id, offset, tag }
157177 }
158178
159179 pub fn wrapping_signed_offset < C : HasDataLayout > ( self , i : i64 , cx : C ) -> Self {
160- Pointer :: new (
180+ Pointer :: new_with_tag (
161181 self . alloc_id ,
162182 Size :: from_bytes ( cx. data_layout ( ) . wrapping_signed_offset ( self . offset . bytes ( ) , i) ) ,
183+ self . tag ,
163184 )
164185 }
165186
166187 pub fn overflowing_signed_offset < C : HasDataLayout > ( self , i : i128 , cx : C ) -> ( Self , bool ) {
167188 let ( res, over) = cx. data_layout ( ) . overflowing_signed_offset ( self . offset . bytes ( ) , i) ;
168- ( Pointer :: new ( self . alloc_id , Size :: from_bytes ( res) ) , over)
189+ ( Pointer :: new_with_tag ( self . alloc_id , Size :: from_bytes ( res) , self . tag ) , over)
169190 }
170191
171192 pub fn signed_offset < C : HasDataLayout > ( self , i : i64 , cx : C ) -> EvalResult < ' tcx , Self > {
172- Ok ( Pointer :: new (
193+ Ok ( Pointer :: new_with_tag (
173194 self . alloc_id ,
174195 Size :: from_bytes ( cx. data_layout ( ) . signed_offset ( self . offset . bytes ( ) , i) ?) ,
196+ self . tag ,
175197 ) )
176198 }
177199
178200 pub fn overflowing_offset < C : HasDataLayout > ( self , i : Size , cx : C ) -> ( Self , bool ) {
179201 let ( res, over) = cx. data_layout ( ) . overflowing_offset ( self . offset . bytes ( ) , i. bytes ( ) ) ;
180- ( Pointer :: new ( self . alloc_id , Size :: from_bytes ( res) ) , over)
202+ ( Pointer :: new_with_tag ( self . alloc_id , Size :: from_bytes ( res) , self . tag ) , over)
181203 }
182204
183205 pub fn offset < C : HasDataLayout > ( self , i : Size , cx : C ) -> EvalResult < ' tcx , Self > {
184- Ok ( Pointer :: new (
206+ Ok ( Pointer :: new_with_tag (
185207 self . alloc_id ,
186208 Size :: from_bytes ( cx. data_layout ( ) . offset ( self . offset . bytes ( ) , i. bytes ( ) ) ?) ,
209+ self . tag
187210 ) )
188211 }
212+
213+ #[ inline]
214+ pub fn erase_tag ( self ) -> Pointer {
215+ Pointer { alloc_id : self . alloc_id , offset : self . offset , tag : ( ) }
216+ }
189217}
190218
191219
@@ -496,15 +524,15 @@ impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
496524}
497525
498526#[ derive( Clone , Debug , Eq , PartialEq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
499- pub struct Allocation {
527+ pub struct Allocation < Tag = ( ) > {
500528 /// The actual bytes of the allocation.
501529 /// Note that the bytes of a pointer represent the offset of the pointer
502530 pub bytes : Vec < u8 > ,
503- /// Maps from byte addresses to allocations .
531+ /// Maps from byte addresses to extra data for each pointer .
504532 /// Only the first byte of a pointer is inserted into the map; i.e.,
505533 /// every entry in this map applies to `pointer_size` consecutive bytes starting
506534 /// at the given offset.
507- pub relocations : Relocations ,
535+ pub relocations : Relocations < Tag > ,
508536 /// Denotes undefined memory. Reading from undefined memory is forbidden in miri
509537 pub undef_mask : UndefMask ,
510538 /// The alignment of the allocation to detect unaligned reads.
@@ -515,7 +543,7 @@ pub struct Allocation {
515543 pub mutability : Mutability ,
516544}
517545
518- impl Allocation {
546+ impl < Tag > Allocation < Tag > {
519547 /// Creates a read-only allocation initialized by the given bytes
520548 pub fn from_bytes ( slice : & [ u8 ] , align : Align ) -> Self {
521549 let mut undef_mask = UndefMask :: new ( Size :: ZERO ) ;
@@ -548,29 +576,29 @@ impl Allocation {
548576impl < ' tcx > :: serialize:: UseSpecializedDecodable for & ' tcx Allocation { }
549577
550578#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug , RustcEncodable , RustcDecodable ) ]
551- pub struct Relocations < Id =AllocId > ( SortedMap < Size , Id > ) ;
579+ pub struct Relocations < Tag = ( ) , Id =AllocId > ( SortedMap < Size , ( Tag , Id ) > ) ;
552580
553- impl < Id > Relocations < Id > {
581+ impl < Tag , Id > Relocations < Tag , Id > {
554582 pub fn new ( ) -> Self {
555583 Relocations ( SortedMap :: new ( ) )
556584 }
557585
558586 // The caller must guarantee that the given relocations are already sorted
559587 // by address and contain no duplicates.
560- pub fn from_presorted ( r : Vec < ( Size , Id ) > ) -> Self {
588+ pub fn from_presorted ( r : Vec < ( Size , ( Tag , Id ) ) > ) -> Self {
561589 Relocations ( SortedMap :: from_presorted_elements ( r) )
562590 }
563591}
564592
565- impl Deref for Relocations {
566- type Target = SortedMap < Size , AllocId > ;
593+ impl < Tag > Deref for Relocations < Tag > {
594+ type Target = SortedMap < Size , ( Tag , AllocId ) > ;
567595
568596 fn deref ( & self ) -> & Self :: Target {
569597 & self . 0
570598 }
571599}
572600
573- impl DerefMut for Relocations {
601+ impl < Tag > DerefMut for Relocations < Tag > {
574602 fn deref_mut ( & mut self ) -> & mut Self :: Target {
575603 & mut self . 0
576604 }
0 commit comments