diff options
| -rw-r--r-- | src/librustc_mir/interpret/machine.rs | 13 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 14 |
2 files changed, 23 insertions, 4 deletions
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index e68d92555db..8ac15bed689 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -243,8 +243,11 @@ pub trait Machine<'mir, 'tcx>: Sized { /// locals in Miri is that in the internals of the compiler they look as /// normal statics, except that they have the `thread_local` attribute. /// However, in Miri we want to have a property that each allocation has - /// a unique id and, therefore, for these thread locals we generate a - /// fresh allocation id for each thread. + /// a unique id. Therefore, for these thread locals in + /// `canonical_alloc_id` we reserve fresh allocation ids for each + /// thread. Please note that `canonical_alloc_id` only reserves the + /// allocation ids, the actual allocation for the thread local statics + /// is done in the same way as for regular statics. /// /// This function must be idempotent. #[inline] @@ -255,8 +258,10 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Called to obtain the `GlobalAlloc` associated with the allocation id. /// /// Miri uses this callback to resolve the information about the original - /// thread local static for which `canonical_alloc_id` generated a fresh - /// allocation id. + /// thread local static for which `canonical_alloc_id` reserved a fresh + /// allocation id. Since `canonical_alloc_id` does not create the actual + /// allocation and the reserved allocation id has no reference to its + /// parent, we need to ask Miri to retrieve information for us. #[inline(always)] fn resolve_maybe_global_alloc( tcx: TyCtxtAt<'tcx>, diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 817d69d2878..69ab96132b9 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -429,6 +429,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { id: AllocId, is_write: bool, ) -> InterpResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> { + // The call to `resolve_maybe_global_alloc` is needed to enable Miri to + // support thread local statics. In `M::canonical_alloc_id`, for a + // thread local static, Miri reserves a fresh allocation id, but the + // actual allocation is left to the code that handles statics which + // calls this function (`get_global_alloc`). Since the allocation id is + // fresh, it has no information about the original static. The call to + // `resolve_maybe_global_alloc` allows Miri to retrieve this information + // for us. let (alloc, def_id) = match M::resolve_maybe_global_alloc(tcx, memory_extra, id) { Some(GlobalAlloc::Memory(mem)) => { // Memory of a constant or promoted or anonymous memory referenced by a static. @@ -589,6 +597,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } // # Statics + // The call to `resolve_maybe_global_alloc` is needed here because Miri + // via the call to `canonical_alloc_id` above reserves fresh allocation + // ids for thread local statics. However, the actual allocation is done + // not in `canonical_alloc_id`, but in `get_raw` and `get_raw_mut`. + // Since this function may get called before `get_raw`, we need to allow + // Miri to retrieve the information about the static for us. match M::resolve_maybe_global_alloc(self.tcx, &self.extra, id) { Some(GlobalAlloc::Static(did)) => { // Use size and align of the type. |
