@@ -35,7 +35,7 @@ pub struct GlobalStateInner {
3535 /// `AllocExtra` because function pointers also have a base address, and
3636 /// they do not have an `AllocExtra`.
3737 /// This is the inverse of `int_to_ptr_map`.
38- base_addr : FxHashMap < AllocId , u64 > ,
38+ base_addr : FxHashMap < AllocId , ( u64 , bool ) > ,
3939 /// Whether an allocation has been exposed or not. This cannot be put
4040 /// into `AllocExtra` for the same reason as `base_addr`.
4141 exposed : FxHashSet < AllocId > ,
@@ -78,7 +78,7 @@ impl GlobalStateInner {
7878 pub fn remove_unreachable_allocs ( & mut self , allocs : & LiveAllocs < ' _ , ' _ , ' _ > ) {
7979 // `exposed` and `int_to_ptr_map` are cleared immediately when an allocation
8080 // is freed, so `base_addr` is the only one we have to clean up based on the GC.
81- self . base_addr . retain ( |id, _ | allocs. is_live ( * id) ) ;
81+ self . base_addr . retain ( |id, ( _ , is_global ) | allocs. is_live ( * id, is_global ) ) ;
8282 }
8383}
8484
@@ -125,7 +125,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
125125 // We only use this provenance if it has been exposed.
126126 if global_state. exposed . contains ( & alloc_id) {
127127 // This must still be live, since we remove allocations from `int_to_ptr_map` when they get freed.
128- debug_assert ! ( ecx. is_alloc_live( alloc_id) ) ;
128+ debug_assert ! ( !matches! ( ecx. is_alloc_live( alloc_id) , Liveness :: Dead ) ) ;
129129 Some ( alloc_id)
130130 } else {
131131 None
@@ -138,7 +138,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
138138 let global_state = & mut * global_state;
139139
140140 Ok ( match global_state. base_addr . entry ( alloc_id) {
141- Entry :: Occupied ( entry) => * entry. get ( ) ,
141+ Entry :: Occupied ( entry) => entry. get ( ) . 0 ,
142142 Entry :: Vacant ( entry) => {
143143 let ( size, align, kind) = ecx. get_alloc_info ( alloc_id) ;
144144 // This is either called immediately after allocation (and then cached), or when
@@ -161,7 +161,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
161161 . checked_add ( slack)
162162 . ok_or_else ( || err_exhaust ! ( AddressSpaceFull ) ) ?;
163163 let base_addr = align_addr ( base_addr, align. bytes ( ) ) ;
164- entry. insert ( base_addr) ;
164+ entry. insert ( ( base_addr, kind . is_global ( ) ) ) ;
165165 trace ! (
166166 "Assigning base address {:#x} to allocation {:?} (size: {}, align: {}, slack: {})" ,
167167 base_addr,
@@ -204,7 +204,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
204204 }
205205 // Exposing a dead alloc is a no-op, because it's not possible to get a dead allocation
206206 // via int2ptr.
207- if ! ecx. is_alloc_live ( alloc_id) {
207+ if matches ! ( ecx. is_alloc_live( alloc_id) , Liveness :: Dead ) {
208208 return Ok ( ( ) ) ;
209209 }
210210 trace ! ( "Exposing allocation id {alloc_id:?}" ) ;
@@ -312,7 +312,7 @@ impl GlobalStateInner {
312312 // returns a dead allocation.
313313 // To avoid a linear scan we first look up the address in `base_addr`, and then find it in
314314 // `int_to_ptr_map`.
315- let addr = * self . base_addr . get ( & dead_id) . unwrap ( ) ;
315+ let addr = self . base_addr . get ( & dead_id) . unwrap ( ) . 0 ;
316316 let pos = self . int_to_ptr_map . binary_search_by_key ( & addr, |( addr, _) | * addr) . unwrap ( ) ;
317317 let removed = self . int_to_ptr_map . remove ( pos) ;
318318 assert_eq ! ( removed, ( addr, dead_id) ) ; // double-check that we removed the right thing
0 commit comments