about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCharles Lew <crlf0710@gmail.com>2021-06-20 12:34:26 +0800
committerCharles Lew <crlf0710@gmail.com>2021-06-27 19:34:34 +0800
commit654e3345e535913653a2bad4204c31f9ccedb3c4 (patch)
tree9c6fd74b4ebb57a294f90c202771484be0c5d8a1
parenta5b7511a6ccf241ba2ce6ad0b04e79f1e3d85686 (diff)
downloadrust-654e3345e535913653a2bad4204c31f9ccedb3c4.tar.gz
rust-654e3345e535913653a2bad4204c31f9ccedb3c4.zip
Change miri to use tcx allocated allocations.
-rw-r--r--compiler/rustc_mir/src/interpret/eval_context.rs6
-rw-r--r--compiler/rustc_mir/src/interpret/intern.rs1
-rw-r--r--compiler/rustc_mir/src/interpret/memory.rs4
-rw-r--r--compiler/rustc_mir/src/interpret/terminator.rs4
-rw-r--r--compiler/rustc_mir/src/interpret/traits.rs50
5 files changed, 36 insertions, 29 deletions
diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs
index 6f7519e6156..801e4b1e478 100644
--- a/compiler/rustc_mir/src/interpret/eval_context.rs
+++ b/compiler/rustc_mir/src/interpret/eval_context.rs
@@ -2,7 +2,6 @@ use std::cell::Cell;
 use std::fmt;
 use std::mem;
 
-use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
 use rustc_index::vec::IndexVec;
@@ -40,10 +39,6 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
 
     /// The virtual memory system.
     pub memory: Memory<'mir, 'tcx, M>,
-
-    /// A cache for deduplicating vtables
-    pub(super) vtables:
-        FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Pointer<M::PointerTag>>,
 }
 
 // The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread
@@ -393,7 +388,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             tcx: tcx.at(root_span),
             param_env,
             memory: Memory::new(tcx, memory_extra),
-            vtables: FxHashMap::default(),
         }
     }
 
diff --git a/compiler/rustc_mir/src/interpret/intern.rs b/compiler/rustc_mir/src/interpret/intern.rs
index 23c0fe97c5f..d5fec457fa1 100644
--- a/compiler/rustc_mir/src/interpret/intern.rs
+++ b/compiler/rustc_mir/src/interpret/intern.rs
@@ -107,7 +107,6 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
     match kind {
         MemoryKind::Stack
         | MemoryKind::Machine(const_eval::MemoryKind::Heap)
-        | MemoryKind::Vtable
         | MemoryKind::CallerLocation => {}
     }
     // Set allocation mutability as appropriate. This is used by LLVM to put things into
diff --git a/compiler/rustc_mir/src/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs
index 77de19ac674..94506808a68 100644
--- a/compiler/rustc_mir/src/interpret/memory.rs
+++ b/compiler/rustc_mir/src/interpret/memory.rs
@@ -27,8 +27,6 @@ use crate::util::pretty;
 pub enum MemoryKind<T> {
     /// Stack memory. Error if deallocated except during a stack pop.
     Stack,
-    /// Memory backing vtables. Error if ever deallocated.
-    Vtable,
     /// Memory allocated by `caller_location` intrinsic. Error if ever deallocated.
     CallerLocation,
     /// Additional memory kinds a machine wishes to distinguish from the builtin ones.
@@ -40,7 +38,6 @@ impl<T: MayLeak> MayLeak for MemoryKind<T> {
     fn may_leak(self) -> bool {
         match self {
             MemoryKind::Stack => false,
-            MemoryKind::Vtable => true,
             MemoryKind::CallerLocation => true,
             MemoryKind::Machine(k) => k.may_leak(),
         }
@@ -51,7 +48,6 @@ impl<T: fmt::Display> fmt::Display for MemoryKind<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             MemoryKind::Stack => write!(f, "stack variable"),
-            MemoryKind::Vtable => write!(f, "vtable"),
             MemoryKind::CallerLocation => write!(f, "caller location"),
             MemoryKind::Machine(m) => write!(f, "{}", m),
         }
diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs
index a5bdeb55e78..aea9933b337 100644
--- a/compiler/rustc_mir/src/interpret/terminator.rs
+++ b/compiler/rustc_mir/src/interpret/terminator.rs
@@ -459,7 +459,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 };
                 // Find and consult vtable
                 let vtable = receiver_place.vtable();
-                let drop_fn = self.get_vtable_slot(vtable, u64::try_from(idx).unwrap())?;
+                let fn_val = self.get_vtable_slot(vtable, u64::try_from(idx).unwrap())?;
 
                 // `*mut receiver_place.layout.ty` is almost the layout that we
                 // want for args[0]: We have to project to field 0 because we want
@@ -472,7 +472,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     OpTy::from(ImmTy::from_immediate(receiver_place.ptr.into(), this_receiver_ptr));
                 trace!("Patched self operand to {:#?}", args[0]);
                 // recurse with concrete function
-                self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind)
+                self.eval_fn_call(fn_val, caller_abi, &args, ret, unwind)
             }
         }
     }
diff --git a/compiler/rustc_mir/src/interpret/traits.rs b/compiler/rustc_mir/src/interpret/traits.rs
index 072c252be2f..539d767d62a 100644
--- a/compiler/rustc_mir/src/interpret/traits.rs
+++ b/compiler/rustc_mir/src/interpret/traits.rs
@@ -1,14 +1,29 @@
 use std::convert::TryFrom;
 
-use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic, Scalar};
+use rustc_middle::mir::interpret::{
+    AllocError, InterpError, InterpResult, Pointer, PointerArithmetic, Scalar,
+    UndefinedBehaviorInfo, UnsupportedOpInfo,
+};
 use rustc_middle::ty::{
     self, Instance, Ty, VtblEntry, COMMON_VTABLE_ENTRIES, COMMON_VTABLE_ENTRIES_ALIGN,
     COMMON_VTABLE_ENTRIES_DROPINPLACE, COMMON_VTABLE_ENTRIES_SIZE,
 };
 use rustc_target::abi::{Align, LayoutOf, Size};
 
+use super::alloc_range;
 use super::util::ensure_monomorphic_enough;
-use super::{FnVal, InterpCx, Machine, MemoryKind};
+use super::{Allocation, FnVal, InterpCx, Machine};
+
+fn vtable_alloc_error_to_interp_error<'tcx>(error: AllocError) -> InterpError<'tcx> {
+    match error {
+        AllocError::ReadPointerAsBytes => {
+            InterpError::Unsupported(UnsupportedOpInfo::ReadPointerAsBytes)
+        }
+        AllocError::InvalidUninitBytes(_info) => {
+            InterpError::UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(None))
+        }
+    }
+}
 
 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Creates a dynamic vtable for the given type and vtable origin. This is used only for
@@ -60,10 +75,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // `get_vtable` in `rust_codegen_llvm/meth.rs`.
         // /////////////////////////////////////////////////////////////////////////////////////////
         let vtable_size = ptr_size * u64::try_from(vtable_entries.len()).unwrap();
-        let vtable = self.memory.allocate(vtable_size, ptr_align, MemoryKind::Vtable);
-
-        let drop = Instance::resolve_drop_in_place(tcx, ty);
-        let drop = self.memory.create_fn_alloc(FnVal::Instance(drop));
+        let mut vtable = Allocation::uninit(vtable_size, ptr_align);
 
         // No need to do any alignment checks on the memory accesses below, because we know the
         // allocation is correctly aligned as we created it above. Also we're only offsetting by
@@ -72,36 +84,42 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             .iter()
             .map(|entry| -> InterpResult<'tcx, _> {
                 match entry {
-                    VtblEntry::MetadataDropInPlace => Ok(Some(drop.into())),
+                    VtblEntry::MetadataDropInPlace => {
+                        let instance = Instance::resolve_drop_in_place(tcx, ty);
+                        let fn_alloc_id = tcx.create_fn_alloc(instance);
+                        let fn_ptr = Pointer::from(fn_alloc_id);
+                        Ok(Some(fn_ptr.into()))
+                    }
                     VtblEntry::MetadataSize => Ok(Some(Scalar::from_uint(size, ptr_size).into())),
                     VtblEntry::MetadataAlign => Ok(Some(Scalar::from_uint(align, ptr_size).into())),
                     VtblEntry::Vacant => Ok(None),
                     VtblEntry::Method(def_id, substs) => {
                         // Prepare the fn ptr we write into the vtable.
                         let instance =
-                            ty::Instance::resolve_for_vtable(tcx, self.param_env, *def_id, substs)
+                            Instance::resolve_for_vtable(tcx, self.param_env, *def_id, substs)
                                 .ok_or_else(|| err_inval!(TooGeneric))?;
-                        let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance));
+                        let fn_alloc_id = tcx.create_fn_alloc(instance);
+                        let fn_ptr = Pointer::from(fn_alloc_id);
                         Ok(Some(fn_ptr.into()))
                     }
                 }
             })
             .collect::<Result<Vec<_>, _>>()?;
-        let mut vtable_alloc =
-            self.memory.get_mut(vtable.into(), vtable_size, ptr_align)?.expect("not a ZST");
         for (idx, scalar) in scalars.into_iter().enumerate() {
             if let Some(scalar) = scalar {
                 let idx: u64 = u64::try_from(idx).unwrap();
-                vtable_alloc.write_ptr_sized(ptr_size * idx, scalar)?;
+                vtable
+                    .write_scalar(self, alloc_range(ptr_size * idx, ptr_size), scalar)
+                    .map_err(vtable_alloc_error_to_interp_error)?;
             }
         }
 
-        M::after_static_mem_initialized(self, vtable, vtable_size)?;
+        let vtable_id = tcx.create_memory_alloc(tcx.intern_const_alloc(vtable));
+        let vtable_ptr = self.memory.global_base_pointer(Pointer::from(vtable_id))?;
 
-        self.memory.mark_immutable(vtable.alloc_id)?;
-        assert!(self.vtables.insert((ty, poly_trait_ref), vtable).is_none());
+        assert!(self.vtables.insert((ty, poly_trait_ref), vtable_ptr).is_none());
 
-        Ok(vtable)
+        Ok(vtable_ptr)
     }
 
     /// Resolves the function at the specified slot in the provided