Deduplicate vtables within a single evaluation
This commit is contained in:
parent
4f9b581f71
commit
80feed380d
2 changed files with 9 additions and 1 deletions
|
|
@ -27,6 +27,7 @@ use rustc::mir::interpret::{
|
|||
EvalResult, EvalErrorKind,
|
||||
truncate, sign_extend,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use syntax::source_map::{self, Span};
|
||||
|
||||
|
|
@ -50,6 +51,9 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
|
|||
|
||||
/// The virtual call stack.
|
||||
pub(crate) stack: Vec<Frame<'mir, 'tcx, M::PointerTag>>,
|
||||
|
||||
/// A cache for deduplicating vtables
|
||||
pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), AllocId>,
|
||||
}
|
||||
|
||||
/// A stack frame.
|
||||
|
|
@ -209,6 +213,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||
param_env,
|
||||
memory: Memory::new(tcx, memory_data),
|
||||
stack: Vec::new(),
|
||||
vtables: FxHashMap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||
) -> EvalResult<'tcx, Pointer<M::PointerTag>> {
|
||||
debug!("get_vtable(trait_ref={:?})", trait_ref);
|
||||
|
||||
// FIXME: Cache this!
|
||||
if let Some(&vtable) = self.vtables.get(&(ty, trait_ref)) {
|
||||
return Ok(Pointer::from(vtable).with_default_tag());
|
||||
}
|
||||
|
||||
let layout = self.layout_of(trait_ref.self_ty())?;
|
||||
assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
|
||||
|
|
@ -64,6 +66,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||
}
|
||||
|
||||
self.memory.mark_immutable(vtable.alloc_id)?;
|
||||
assert!(self.vtables.insert((ty, trait_ref), vtable.alloc_id).is_none());
|
||||
|
||||
Ok(vtable)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue