Skip to content

Commit b2612cb

Browse files
committed
don't tag new memory inside memory.rs; add machine hook to tag new memory
1 parent ff3b29f commit b2612cb

File tree

7 files changed

+44
-24
lines changed

7 files changed

+44
-24
lines changed

src/librustc_mir/const_eval.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use syntax::ast::Mutability;
3232
use syntax::source_map::{Span, DUMMY_SP};
3333

3434
use interpret::{self,
35-
PlaceTy, MemPlace, OpTy, Operand, Value, Scalar, ConstValue,
35+
PlaceTy, MemPlace, OpTy, Operand, Value, Scalar, ConstValue, Pointer,
3636
EvalResult, EvalError, EvalErrorKind, GlobalId, EvalContext, StackPopCleanup,
3737
Allocation, AllocId, MemoryKind,
3838
snapshot, RefTracking,
@@ -426,7 +426,7 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
426426
}
427427

428428
#[inline(always)]
429-
fn static_with_default_tag(
429+
fn adjust_static_allocation(
430430
alloc: &'_ Allocation
431431
) -> Cow<'_, Allocation<Self::PointerTag>> {
432432
// We do not use a tag so we can just cheaply forward the reference
@@ -465,6 +465,15 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
465465
&ecx.stack[..],
466466
)
467467
}
468+
469+
#[inline(always)]
470+
fn tag_new_allocation(
471+
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
472+
ptr: Pointer,
473+
_kind: MemoryKind<Self::MemoryKinds>,
474+
) -> EvalResult<'tcx, Pointer> {
475+
Ok(ptr)
476+
}
468477
}
469478

470479
/// Project to a field of a (variant of a) const

src/librustc_mir/interpret/cast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
110110
def_id,
111111
substs,
112112
).ok_or_else(|| EvalErrorKind::TooGeneric.into());
113-
let fn_ptr = self.memory.create_fn_alloc(instance?);
113+
let fn_ptr = self.memory.create_fn_alloc(instance?).with_default_tag();
114114
self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?;
115115
}
116116
ref other => bug!("reify fn pointer on {:?}", other),
@@ -143,7 +143,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
143143
substs,
144144
ty::ClosureKind::FnOnce,
145145
);
146-
let fn_ptr = self.memory.create_fn_alloc(instance);
146+
let fn_ptr = self.memory.create_fn_alloc(instance).with_default_tag();
147147
let val = Value::Scalar(Scalar::Ptr(fn_ptr.into()).into());
148148
self.write_value(val, dest)?;
149149
}

src/librustc_mir/interpret/eval_context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
334334
}
335335

336336
pub fn str_to_value(&mut self, s: &str) -> EvalResult<'tcx, Value<M::PointerTag>> {
337-
let ptr = self.memory.allocate_static_bytes(s.as_bytes());
337+
let ptr = self.memory.allocate_static_bytes(s.as_bytes()).with_default_tag();
338338
Ok(Value::new_slice(Scalar::Ptr(ptr), s.len() as u64, self.tcx.tcx))
339339
}
340340

src/librustc_mir/interpret/machine.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
8181

8282
/// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows"
8383
/// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
84+
/// The `default()` is used for pointers to consts, statics, vtables and functions.
8485
type PointerTag: ::std::fmt::Debug + Default + Copy + Eq + Hash + 'static;
8586

8687
/// Extra data stored in every allocation.
@@ -151,13 +152,13 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
151152
) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag, Self::AllocExtra>>>;
152153

153154
/// Called to turn an allocation obtained from the `tcx` into one that has
154-
/// the appropriate tags on each pointer.
155+
/// the right type for this machine.
155156
///
156157
/// This should avoid copying if no work has to be done! If this returns an owned
157-
/// allocation (because a copy had to be done to add the tags), machine memory will
158+
/// allocation (because a copy had to be done to add tags or metadata), machine memory will
158159
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
159160
/// owned allocation to the map even when the map is shared.)
160-
fn static_with_default_tag(
161+
fn adjust_static_allocation(
161162
alloc: &'_ Allocation
162163
) -> Cow<'_, Allocation<Self::PointerTag, Self::AllocExtra>>;
163164

@@ -204,6 +205,13 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
204205
Ok(())
205206
}
206207

208+
/// Add the tag for a newly allocated pointer.
209+
fn tag_new_allocation(
210+
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
211+
ptr: Pointer,
212+
kind: MemoryKind<Self::MemoryKinds>,
213+
) -> EvalResult<'tcx, Pointer<Self::PointerTag>>;
214+
207215
/// Executed when evaluating the `&` operator: Creating a new reference.
208216
/// This has the chance to adjust the tag. It should not change anything else!
209217
/// `mutability` can be `None` in case a raw ptr is being created.

src/librustc_mir/interpret/memory.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
117117
}
118118
}
119119

120-
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> Pointer<M::PointerTag> {
121-
Pointer::from(self.tcx.alloc_map.lock().create_fn_alloc(instance)).with_default_tag()
120+
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> Pointer {
121+
Pointer::from(self.tcx.alloc_map.lock().create_fn_alloc(instance))
122122
}
123123

124-
pub fn allocate_static_bytes(&mut self, bytes: &[u8]) -> Pointer<M::PointerTag> {
125-
Pointer::from(self.tcx.allocate_bytes(bytes)).with_default_tag()
124+
pub fn allocate_static_bytes(&mut self, bytes: &[u8]) -> Pointer {
125+
Pointer::from(self.tcx.allocate_bytes(bytes))
126126
}
127127

128128
pub fn allocate_with(
@@ -140,9 +140,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
140140
size: Size,
141141
align: Align,
142142
kind: MemoryKind<M::MemoryKinds>,
143-
) -> EvalResult<'tcx, Pointer<M::PointerTag>> {
144-
let ptr = Pointer::from(self.allocate_with(Allocation::undef(size, align), kind)?);
145-
Ok(ptr.with_default_tag())
143+
) -> EvalResult<'tcx, Pointer> {
144+
Ok(Pointer::from(self.allocate_with(Allocation::undef(size, align), kind)?))
146145
}
147146

148147
pub fn reallocate(
@@ -153,17 +152,18 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
153152
new_size: Size,
154153
new_align: Align,
155154
kind: MemoryKind<M::MemoryKinds>,
156-
) -> EvalResult<'tcx, Pointer<M::PointerTag>> {
155+
) -> EvalResult<'tcx, Pointer> {
157156
if ptr.offset.bytes() != 0 {
158157
return err!(ReallocateNonBasePtr);
159158
}
160159

161-
// For simplicities' sake, we implement reallocate as "alloc, copy, dealloc"
160+
// For simplicities' sake, we implement reallocate as "alloc, copy, dealloc".
161+
// FIXME: Do something more efficient.
162162
let new_ptr = self.allocate(new_size, new_align, kind)?;
163163
self.copy(
164164
ptr.into(),
165165
old_align,
166-
new_ptr.into(),
166+
new_ptr.with_default_tag().into(),
167167
new_align,
168168
old_size.min(new_size),
169169
/*nonoverlapping*/ true,
@@ -347,7 +347,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
347347
Some(AllocType::Memory(mem)) => {
348348
// We got tcx memory. Let the machine figure out whether and how to
349349
// turn that into memory with the right pointer tag.
350-
return Ok(M::static_with_default_tag(mem))
350+
return Ok(M::adjust_static_allocation(mem))
351351
}
352352
Some(AllocType::Function(..)) => {
353353
return err!(DerefFunctionPointer)
@@ -381,7 +381,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
381381
if let ConstValue::ByRef(_, allocation, _) = const_val.val {
382382
// We got tcx memory. Let the machine figure out whether and how to
383383
// turn that into memory with the right pointer tag.
384-
M::static_with_default_tag(allocation)
384+
M::adjust_static_allocation(allocation)
385385
} else {
386386
bug!("Matching on non-ByRef static")
387387
}

src/librustc_mir/interpret/place.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,8 @@ where
856856
}
857857

858858
/// Make sure that a place is in memory, and return where it is.
859+
/// If the place currently refers to a local that doesn't yet have a matching allocation,
860+
/// create such an allocation.
859861
/// This is essentially `force_to_memplace`.
860862
pub fn force_allocation(
861863
&mut self,
@@ -899,10 +901,11 @@ where
899901
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
900902
if layout.is_unsized() {
901903
assert!(self.tcx.features().unsized_locals, "cannot alloc memory for unsized type");
902-
// FIXME: What should we do here?
904+
// FIXME: What should we do here? We should definitely also tag!
903905
Ok(MPlaceTy::dangling(layout, &self))
904906
} else {
905907
let ptr = self.memory.allocate(layout.size, layout.align, kind)?;
908+
let ptr = M::tag_new_allocation(self, ptr, kind)?;
906909
Ok(MPlaceTy::from_aligned_ptr(ptr, layout))
907910
}
908911
}

src/librustc_mir/interpret/traits.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
5454
ptr_size * (3 + methods.len() as u64),
5555
ptr_align,
5656
MemoryKind::Vtable,
57-
)?;
57+
)?.with_default_tag();
5858

5959
let drop = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
60-
let drop = self.memory.create_fn_alloc(drop);
60+
let drop = self.memory.create_fn_alloc(drop).with_default_tag();
6161
self.memory.write_ptr_sized(vtable, ptr_align, Scalar::Ptr(drop).into())?;
6262

6363
let size_ptr = vtable.offset(ptr_size, &self)?;
@@ -69,7 +69,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
6969
for (i, method) in methods.iter().enumerate() {
7070
if let Some((def_id, substs)) = *method {
7171
let instance = self.resolve(def_id, substs)?;
72-
let fn_ptr = self.memory.create_fn_alloc(instance);
72+
let fn_ptr = self.memory.create_fn_alloc(instance).with_default_tag();
7373
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
7474
self.memory.write_ptr_sized(method_ptr, ptr_align, Scalar::Ptr(fn_ptr).into())?;
7575
}

0 commit comments

Comments
 (0)