cache tag for vtable; fn_alloc's don't have a stack nor tag

This commit is contained in:
Ralf Jung 2019-05-25 13:48:56 +02:00
parent 538e17a3fd
commit 2726a91cca
4 changed files with 14 additions and 10 deletions

View file

@ -86,7 +86,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
def_id, def_id,
substs, substs,
).ok_or_else(|| InterpError::TooGeneric.into()); ).ok_or_else(|| InterpError::TooGeneric.into());
let fn_ptr = self.memory.create_fn_alloc(instance?).with_default_tag(); let fn_ptr = self.memory.create_fn_alloc(instance?);
self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?;
} }
_ => bug!("reify fn pointer on {:?}", src.layout.ty), _ => bug!("reify fn pointer on {:?}", src.layout.ty),
@ -115,7 +115,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
substs, substs,
ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce,
); );
let fn_ptr = self.memory.create_fn_alloc(instance).with_default_tag(); let fn_ptr = self.memory.create_fn_alloc(instance);
let val = Immediate::Scalar(Scalar::Ptr(fn_ptr.into()).into()); let val = Immediate::Scalar(Scalar::Ptr(fn_ptr.into()).into());
self.write_immediate(val, dest)?; self.write_immediate(val, dest)?;
} }

View file

@ -15,7 +15,7 @@ use rustc::ty::query::TyCtxtAt;
use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::indexed_vec::IndexVec;
use rustc::mir::interpret::{ use rustc::mir::interpret::{
ErrorHandled, ErrorHandled,
GlobalId, Scalar, FrameInfo, AllocId, GlobalId, Scalar, Pointer, FrameInfo, AllocId,
EvalResult, InterpError, EvalResult, InterpError,
truncate, sign_extend, truncate, sign_extend,
}; };
@ -43,7 +43,10 @@ pub struct InterpretCx<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
pub(crate) stack: Vec<Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>>, pub(crate) stack: Vec<Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>>,
/// A cache for deduplicating vtables /// A cache for deduplicating vtables
pub(super) vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), AllocId>, pub(super) vtables: FxHashMap<
(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>),
Pointer<M::PointerTag>
>,
} }
/// A stack frame. /// A stack frame.

View file

@ -108,8 +108,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
} }
} }
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> Pointer { pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> Pointer<M::PointerTag> {
Pointer::from(self.tcx.alloc_map.lock().create_fn_alloc(instance)) // Default tag is okay because anyway you cannot access memory with this.
Pointer::from(self.tcx.alloc_map.lock().create_fn_alloc(instance)).with_default_tag()
} }
pub fn allocate_static_bytes(&mut self, bytes: &[u8]) -> Pointer { pub fn allocate_static_bytes(&mut self, bytes: &[u8]) -> Pointer {

View file

@ -25,7 +25,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
// always use the same vtable for the same (Type, Trait) combination. // always use the same vtable for the same (Type, Trait) combination.
// That's not what happens in rustc, but emulating per-crate deduplication // That's not what happens in rustc, but emulating per-crate deduplication
// does not sound like it actually makes anything any better. // does not sound like it actually makes anything any better.
return Ok(Pointer::from(vtable).with_default_tag()); return Ok(vtable);
} }
let methods = if let Some(poly_trait_ref) = poly_trait_ref { let methods = if let Some(poly_trait_ref) = poly_trait_ref {
@ -56,7 +56,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
let tcx = &*self.tcx; let tcx = &*self.tcx;
let drop = crate::monomorphize::resolve_drop_in_place(*tcx, ty); let drop = crate::monomorphize::resolve_drop_in_place(*tcx, ty);
let drop = self.memory.create_fn_alloc(drop).with_default_tag(); let drop = self.memory.create_fn_alloc(drop);
// no need to do any alignment checks on the memory accesses below, because we know the // 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 // allocation is correctly aligned as we created it above. Also we're only offsetting by
// multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`. // multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`.
@ -83,7 +83,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
def_id, def_id,
substs, substs,
).ok_or_else(|| InterpError::TooGeneric)?; ).ok_or_else(|| InterpError::TooGeneric)?;
let fn_ptr = self.memory.create_fn_alloc(instance).with_default_tag(); let fn_ptr = self.memory.create_fn_alloc(instance);
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?; let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?;
self.memory self.memory
.get_mut(method_ptr.alloc_id)? .get_mut(method_ptr.alloc_id)?
@ -92,7 +92,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
} }
self.memory.mark_immutable(vtable.alloc_id)?; self.memory.mark_immutable(vtable.alloc_id)?;
assert!(self.vtables.insert((ty, poly_trait_ref), vtable.alloc_id).is_none()); assert!(self.vtables.insert((ty, poly_trait_ref), vtable).is_none());
Ok(vtable) Ok(vtable)
} }