cache tag for vtable; fn_alloc's don't have a stack nor tag
This commit is contained in:
parent
538e17a3fd
commit
2726a91cca
4 changed files with 14 additions and 10 deletions
|
@ -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)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue