]> git.lizzy.rs Git - rust.git/blobdiff - src/thread.rs
get_or_create_thread_local_alloc_id: share code with Memory::get_global_alloc
[rust.git] / src / thread.rs
index aee7d395ddfcfb8a151ae7dcbaa0dca272bbfc19..8d493ac8f3bde83faae4dfd389517b7a31870f0f 100644 (file)
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
 use rustc_index::vec::{Idx, IndexVec};
-use rustc_middle::{
-    middle::codegen_fn_attrs::CodegenFnAttrFlags,
-    mir,
-    ty::{self, Instance},
-};
 
 use crate::sync::SynchronizationState;
 use crate::*;
@@ -373,7 +368,7 @@ fn unblock_thread(&mut self, thread: ThreadId) {
 
     /// Change the active thread to some enabled thread.
     fn yield_active_thread(&mut self) {
-        // We do not immediately, as swapping out the current stack while execution a MIR statement
+        // We do not yield immediately, as swapping out the current stack while executing a MIR statement
         // could lead to all sorts of confusion.
         // We should only switch stacks between steps.
         self.yield_active_thread = true;
@@ -499,46 +494,8 @@ fn schedule(&mut self) -> InterpResult<'tcx, SchedulingAction> {
 // Public interface to thread management.
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
-    /// A workaround for thread-local statics until
-    /// https://github.com/rust-lang/rust/issues/70685 is fixed: change the
-    /// thread-local allocation id with a freshly generated allocation id for
-    /// the currently active thread.
-    fn remap_thread_local_alloc_ids(
-        &self,
-        val: &mut mir::interpret::ConstValue<'tcx>,
-    ) -> InterpResult<'tcx> {
-        let this = self.eval_context_ref();
-        match *val {
-            mir::interpret::ConstValue::Scalar(Scalar::Ptr(ref mut ptr)) => {
-                let alloc_id = ptr.alloc_id;
-                let alloc = this.tcx.get_global_alloc(alloc_id);
-                let tcx = this.tcx;
-                let is_thread_local = |def_id| {
-                    tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
-                };
-                match alloc {
-                    Some(GlobalAlloc::Static(def_id)) if is_thread_local(def_id) => {
-                        ptr.alloc_id = this.get_or_create_thread_local_alloc_id(def_id)?;
-                    }
-                    _ => {}
-                }
-            }
-            _ => {
-                // FIXME: Handling only `Scalar` seems to work for now, but at
-                // least in principle thread-locals could be in any constant, so
-                // we should also consider other cases. However, once
-                // https://github.com/rust-lang/rust/issues/70685 gets fixed,
-                // this code will have to be rewritten anyway.
-            }
-        }
-        Ok(())
-    }
-
     /// Get a thread-specific allocation id for the given thread-local static.
     /// If needed, allocate a new one.
-    ///
-    /// FIXME: This method should be replaced as soon as
-    /// https://github.com/rust-lang/rust/issues/70685 gets fixed.
     fn get_or_create_thread_local_alloc_id(&self, def_id: DefId) -> InterpResult<'tcx, AllocId> {
         let this = self.eval_context_ref();
         let tcx = this.tcx;
@@ -550,29 +507,15 @@ fn get_or_create_thread_local_alloc_id(&self, def_id: DefId) -> InterpResult<'tc
             // We need to allocate a thread-specific allocation id for this
             // thread-local static.
             //
-            // At first, we invoke the `const_eval_raw` query and extract the
-            // allocation from it. Unfortunately, we have to duplicate the code
-            // from `Memory::get_global_alloc` that does this.
-            //
+            // At first, we compute the initial value for this static.
             // Then we store the retrieved allocation back into the `alloc_map`
             // to get a fresh allocation id, which we can use as a
             // thread-specific allocation id for the thread-local static.
+            // On first access to that allocation, it will be copied over to the machine memory.
             if tcx.is_foreign_item(def_id) {
                 throw_unsup_format!("foreign thread-local statics are not supported");
             }
-            // Invoke the `const_eval_raw` query.
-            let instance = Instance::mono(tcx.tcx, def_id);
-            let gid = GlobalId { instance, promoted: None };
-            let raw_const =
-                tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid)).map_err(|err| {
-                    // no need to report anything, the const_eval call takes care of that
-                    // for statics
-                    assert!(tcx.is_static(def_id));
-                    err
-                })?;
-            let id = raw_const.alloc_id;
-            // Extract the allocation from the query result.
-            let allocation = tcx.global_alloc(id).unwrap_memory();
+            let allocation = interpret::get_static(*tcx, def_id)?;
             // Create a new allocation id for the same allocation in this hacky
             // way. Internally, `alloc_map` deduplicates allocations, but this
             // is fine because Miri will make a copy before a first mutable