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,
substs,
).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)?;
}
_ => 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,
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());
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::mir::interpret::{
ErrorHandled,
GlobalId, Scalar, FrameInfo, AllocId,
GlobalId, Scalar, Pointer, FrameInfo, AllocId,
EvalResult, InterpError,
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>>,
/// 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.

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 {
Pointer::from(self.tcx.alloc_map.lock().create_fn_alloc(instance))
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> Pointer<M::PointerTag> {
// 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 {

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.
// That's not what happens in rustc, but emulating per-crate deduplication
// 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 {
@ -56,7 +56,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
let tcx = &*self.tcx;
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
// 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`.
@ -83,7 +83,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
def_id,
substs,
).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)?;
self.memory
.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)?;
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)
}