Skip to content

Commit 21934c8

Browse files
committed
add support for storing extra data in an allocation
1 parent 290db47 commit 21934c8

File tree

7 files changed

+37
-38
lines changed

7 files changed

+37
-38
lines changed

src/librustc/mir/interpret/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
524524
}
525525

526526
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
527-
pub struct Allocation<Tag=()> {
527+
pub struct Allocation<Tag=(),Extra=()> {
528528
/// The actual bytes of the allocation.
529529
/// Note that the bytes of a pointer represent the offset of the pointer
530530
pub bytes: Vec<u8>,
@@ -541,9 +541,11 @@ pub struct Allocation<Tag=()> {
541541
/// Also used by codegen to determine if a static should be put into mutable memory,
542542
/// which happens for `static mut` and `static` with interior mutability.
543543
pub mutability: Mutability,
544+
/// Extra state for the machine.
545+
pub extra: Extra,
544546
}
545547

546-
impl<Tag> Allocation<Tag> {
548+
impl<Tag, Extra: Default> Allocation<Tag, Extra> {
547549
/// Creates a read-only allocation initialized by the given bytes
548550
pub fn from_bytes(slice: &[u8], align: Align) -> Self {
549551
let mut undef_mask = UndefMask::new(Size::ZERO);
@@ -554,6 +556,7 @@ impl<Tag> Allocation<Tag> {
554556
undef_mask,
555557
align,
556558
mutability: Mutability::Immutable,
559+
extra: Extra::default(),
557560
}
558561
}
559562

@@ -569,6 +572,7 @@ impl<Tag> Allocation<Tag> {
569572
undef_mask: UndefMask::new(size),
570573
align,
571574
mutability: Mutability::Mutable,
575+
extra: Extra::default(),
572576
}
573577
}
574578
}

src/librustc_mir/const_eval.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
5353
) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'mir, 'tcx>> {
5454
debug!("mk_borrowck_eval_cx: {:?}", instance);
5555
let param_env = tcx.param_env(instance.def_id());
56-
let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), ());
56+
let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new());
5757
// insert a stack frame so any queries have the correct substs
5858
// cannot use `push_stack_frame`; if we do `const_prop` explodes
5959
ecx.stack.push(interpret::Frame {
@@ -76,7 +76,7 @@ pub fn mk_eval_cx<'a, 'tcx>(
7676
) -> EvalResult<'tcx, CompileTimeEvalContext<'a, 'tcx, 'tcx>> {
7777
debug!("mk_eval_cx: {:?}, {:?}", instance, param_env);
7878
let span = tcx.def_span(instance.def_id());
79-
let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), ());
79+
let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new());
8080
let mir = ecx.load_mir(instance.def)?;
8181
// insert a stack frame so any queries have the correct substs
8282
ecx.push_stack_frame(
@@ -155,7 +155,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
155155
// and try improving it down the road when more information is available
156156
let span = tcx.def_span(cid.instance.def_id());
157157
let span = mir.map(|mir| mir.span).unwrap_or(span);
158-
let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), ());
158+
let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeInterpreter::new());
159159
let r = eval_body_using_ecx(&mut ecx, cid, mir, param_env);
160160
(r, ecx)
161161
}
@@ -336,11 +336,11 @@ type CompileTimeEvalContext<'a, 'mir, 'tcx> =
336336
impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
337337
for CompileTimeInterpreter<'a, 'mir, 'tcx>
338338
{
339-
type MemoryData = ();
340339
type MemoryKinds = !;
340+
type AllocExtra = ();
341341
type PointerTag = ();
342342

343-
type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation<()>)>;
343+
type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
344344

345345
const STATIC_KIND: Option<!> = None; // no copying of statics allowed
346346

src/librustc_mir/interpret/eval_context.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
205205
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
206206
param_env: ty::ParamEnv<'tcx>,
207207
machine: M,
208-
memory_data: M::MemoryData,
209208
) -> Self {
210209
EvalContext {
211210
machine,
212211
tcx,
213212
param_env,
214-
memory: Memory::new(tcx, memory_data),
213+
memory: Memory::new(tcx),
215214
stack: Vec::new(),
216215
vtables: FxHashMap::default(),
217216
}

src/librustc_mir/interpret/machine.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,25 @@ pub trait AllocMap<K: Hash + Eq, V> {
6262
/// Methods of this trait signifies a point where CTFE evaluation would fail
6363
/// and some use case dependent behaviour can instead be applied.
6464
pub trait Machine<'a, 'mir, 'tcx>: Sized {
65-
/// Additional data that can be accessed via the Memory
66-
type MemoryData;
67-
6865
/// Additional memory kinds a machine wishes to distinguish from the builtin ones
69-
type MemoryKinds: ::std::fmt::Debug + Copy + Eq;
66+
type MemoryKinds: ::std::fmt::Debug + Copy + Eq + 'static;
67+
68+
/// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows"
69+
/// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
70+
type PointerTag: ::std::fmt::Debug + Default + Copy + Eq + Hash + 'static;
71+
72+
/// Extra data stored in every allocation.
73+
type AllocExtra: ::std::fmt::Debug + Default + Clone;
7074

7175
/// Memory's allocation map
7276
type MemoryMap:
73-
AllocMap<AllocId, (MemoryKind<Self::MemoryKinds>, Allocation<Self::PointerTag>)> +
77+
AllocMap<
78+
AllocId,
79+
(MemoryKind<Self::MemoryKinds>, Allocation<Self::PointerTag, Self::AllocExtra>)
80+
> +
7481
Default +
7582
Clone;
7683

77-
/// Tag tracked alongside every pointer. This is inert for now, in preparation for
78-
/// a future implementation of "Stacked Borrows"
79-
/// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
80-
type PointerTag: ::std::fmt::Debug + Default + Copy + Eq + Hash + 'static;
81-
8284
/// The memory kind to use for copied statics -- or None if those are not supported.
8385
/// Statics are copied under two circumstances: When they are mutated, and when
8486
/// `static_with_default_tag` or `find_foreign_static` (see below) returns an owned allocation
@@ -127,7 +129,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
127129
fn find_foreign_static(
128130
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
129131
def_id: DefId,
130-
) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag>>>;
132+
) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag, Self::AllocExtra>>>;
131133

132134
/// Called to turn an allocation obtained from the `tcx` into one that has
133135
/// the appropriate tags on each pointer.
@@ -138,7 +140,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
138140
/// owned allocation to the map even when the map is shared.)
139141
fn static_with_default_tag(
140142
alloc: &'_ Allocation
141-
) -> Cow<'_, Allocation<Self::PointerTag>>;
143+
) -> Cow<'_, Allocation<Self::PointerTag, Self::AllocExtra>>;
142144

143145
/// Called for all binary operations on integer(-like) types when one operand is a pointer
144146
/// value, and for the `Offset` operation that is inherently about pointers.

src/librustc_mir/interpret/memory.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,6 @@ pub enum MemoryKind<T> {
4747
// `Memory` has to depend on the `Machine` because some of its operations
4848
// (e.g. `get`) call a `Machine` hook.
4949
pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
50-
/// Additional data required by the Machine
51-
pub data: M::MemoryData,
52-
5350
/// Allocations local to this instance of the miri engine. The kind
5451
/// helps ensure that the same mechanism is used for allocation and
5552
/// deallocation. When an allocation is not found here, it is a
@@ -91,11 +88,9 @@ impl<'a, 'b, 'c, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> HasDataLayout
9188
// carefully copy only the reachable parts.
9289
impl<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>>
9390
Clone for Memory<'a, 'mir, 'tcx, M>
94-
where M::MemoryData: Clone
9591
{
9692
fn clone(&self) -> Self {
9793
Memory {
98-
data: self.data.clone(),
9994
alloc_map: self.alloc_map.clone(),
10095
dead_alloc_map: self.dead_alloc_map.clone(),
10196
tcx: self.tcx,
@@ -104,9 +99,8 @@ impl<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>>
10499
}
105100

106101
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
107-
pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self {
102+
pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>) -> Self {
108103
Memory {
109-
data,
110104
alloc_map: Default::default(),
111105
dead_alloc_map: FxHashMap::default(),
112106
tcx,
@@ -123,7 +117,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
123117

124118
pub fn allocate_with(
125119
&mut self,
126-
alloc: Allocation<M::PointerTag>,
120+
alloc: Allocation<M::PointerTag, M::AllocExtra>,
127121
kind: MemoryKind<M::MemoryKinds>,
128122
) -> EvalResult<'tcx, AllocId> {
129123
let id = self.tcx.alloc_map.lock().reserve();
@@ -334,7 +328,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
334328
fn get_static_alloc(
335329
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
336330
id: AllocId,
337-
) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag>>> {
331+
) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> {
338332
let alloc = tcx.alloc_map.lock().get(id);
339333
let def_id = match alloc {
340334
Some(AllocType::Memory(mem)) => {
@@ -376,7 +370,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
376370
})
377371
}
378372

379-
pub fn get(&self, id: AllocId) -> EvalResult<'tcx, &Allocation<M::PointerTag>> {
373+
pub fn get(&self, id: AllocId) -> EvalResult<'tcx, &Allocation<M::PointerTag, M::AllocExtra>> {
380374
// The error type of the inner closure here is somewhat funny. We have two
381375
// ways of "erroring": An actual error, or because we got a reference from
382376
// `get_static_alloc` that we can actually use directly without inserting anything anywhere.
@@ -409,7 +403,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
409403
pub fn get_mut(
410404
&mut self,
411405
id: AllocId,
412-
) -> EvalResult<'tcx, &mut Allocation<M::PointerTag>> {
406+
) -> EvalResult<'tcx, &mut Allocation<M::PointerTag, M::AllocExtra>> {
413407
let tcx = self.tcx;
414408
let a = self.alloc_map.get_mut_or(id, || {
415409
// Need to make a copy, even if `get_static_alloc` is able
@@ -482,12 +476,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
482476
self.dump_allocs(vec![id]);
483477
}
484478

485-
fn dump_alloc_helper<Tag>(
479+
fn dump_alloc_helper<Tag, Extra>(
486480
&self,
487481
allocs_seen: &mut FxHashSet<AllocId>,
488482
allocs_to_print: &mut VecDeque<AllocId>,
489483
mut msg: String,
490-
alloc: &Allocation<Tag>,
484+
alloc: &Allocation<Tag, Extra>,
491485
extra: String,
492486
) {
493487
use std::fmt::Write;
@@ -687,8 +681,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
687681
/// Interning (for CTFE)
688682
impl<'a, 'mir, 'tcx, M> Memory<'a, 'mir, 'tcx, M>
689683
where
690-
M: Machine<'a, 'mir, 'tcx, PointerTag=()>,
691-
M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation<()>)>,
684+
M: Machine<'a, 'mir, 'tcx, PointerTag=(), AllocExtra=()>,
685+
M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation)>,
692686
{
693687
/// mark an allocation as static and initialized, either mutable or not
694688
pub fn intern_static(

src/librustc_mir/interpret/place.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ impl<'a, 'mir, 'tcx, Tag, M> EvalContext<'a, 'mir, 'tcx, M>
267267
where
268268
Tag: ::std::fmt::Debug+Default+Copy+Eq+Hash+'static,
269269
M: Machine<'a, 'mir, 'tcx, PointerTag=Tag>,
270-
M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation<Tag>)>,
270+
M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation<Tag, M::AllocExtra>)>,
271271
{
272272
/// Take a value, which represents a (thin or fat) reference, and make it a place.
273273
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref`.

src/librustc_mir/interpret/snapshot.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
305305
type Item = AllocationSnapshot<'a>;
306306

307307
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
308-
let Allocation { bytes, relocations, undef_mask, align, mutability } = self;
308+
let Allocation { bytes, relocations, undef_mask, align, mutability, extra: () } = self;
309309

310310
AllocationSnapshot {
311311
bytes,

0 commit comments

Comments
 (0)