Skip to content

Commit e685a36

Browse files
implement via flag
1 parent bd28faf commit e685a36

File tree

13 files changed

+43
-101
lines changed

13 files changed

+43
-101
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
420420
Size::from_bytes(size),
421421
align,
422422
interpret::MemoryKind::Machine(MemoryKind::Heap),
423+
false,
423424
)?;
424425
ecx.write_pointer(ptr, dest)?;
425426
}

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
230230
size: Size,
231231
align: Align,
232232
kind: MemoryKind<M::MemoryKind>,
233+
zero_init: bool,
233234
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
234235
let alloc = if M::PANIC_ON_ALLOC_FAIL {
235-
Allocation::uninit(size, align)
236+
Allocation::new(size, align, zero_init)
236237
} else {
237-
Allocation::try_uninit(size, align)?
238+
Allocation::try_new(size, align, zero_init)?
238239
};
239240
self.insert_allocation(alloc, kind)
240241
}
@@ -250,20 +251,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
250251
self.insert_allocation(alloc, kind)
251252
}
252253

253-
pub fn allocate_zeroed_ptr(
254-
&mut self,
255-
size: Size,
256-
align: Align,
257-
kind: MemoryKind<M::MemoryKind>,
258-
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
259-
let alloc = if M::PANIC_ON_ALLOC_FAIL {
260-
Allocation::zeroed(size, align)
261-
} else {
262-
Allocation::try_zeroed(size, align)?
263-
};
264-
self.insert_allocation(alloc, kind)
265-
}
266-
267254
pub fn insert_allocation(
268255
&mut self,
269256
alloc: Allocation<M::Provenance, (), M::Bytes>,
@@ -291,6 +278,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
291278
new_size: Size,
292279
new_align: Align,
293280
kind: MemoryKind<M::MemoryKind>,
281+
zero_init: bool,
294282
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
295283
let (alloc_id, offset, _prov) = self.ptr_get_alloc_id(ptr, 0)?;
296284
if offset.bytes() != 0 {
@@ -303,7 +291,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
303291

304292
// For simplicities' sake, we implement reallocate as "alloc, copy, dealloc".
305293
// This happens so rarely, the perf advantage is outweighed by the maintenance cost.
306-
let new_ptr = self.allocate_ptr(new_size, new_align, kind)?;
294+
let new_ptr = self.allocate_ptr(new_size, new_align, kind, zero_init)?;
307295
let old_size = match old_size_and_align {
308296
Some((size, _align)) => size,
309297
None => self.get_alloc_raw(alloc_id)?.size(),

compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ where
983983
let Some((size, align)) = self.size_and_align_of(&meta, &layout)? else {
984984
span_bug!(self.cur_span(), "cannot allocate space for `extern` type, size is not known")
985985
};
986-
let ptr = self.allocate_ptr(size, align, kind)?;
986+
let ptr = self.allocate_ptr(size, align, kind, false)?;
987987
interp_ok(self.ptr_with_meta_to_mplace(ptr.into(), meta, layout, /*unaligned*/ false))
988988
}
989989

compiler/rustc_const_eval/src/interpret/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub(crate) fn create_static_alloc<'tcx>(
7676
static_def_id: LocalDefId,
7777
layout: TyAndLayout<'tcx>,
7878
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
79-
let alloc = Allocation::try_uninit(layout.size, layout.align.abi)?;
79+
let alloc = Allocation::try_new(layout.size, layout.align.abi, false)?;
8080
let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into());
8181
assert_eq!(ecx.machine.static_root_ids, None);
8282
ecx.machine.static_root_ids = Some((alloc_id, static_def_id));

compiler/rustc_middle/src/mir/interpret/allocation.rs

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,12 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
294294
Allocation::from_bytes(slice, Align::ONE, Mutability::Not)
295295
}
296296

297-
fn uninit_inner<R>(size: Size, align: Align, fail: impl FnOnce() -> R) -> Result<Self, R> {
297+
fn new_inner<R>(
298+
size: Size,
299+
align: Align,
300+
zero_init: bool,
301+
fail: impl FnOnce() -> R,
302+
) -> Result<Self, R> {
298303
// We raise an error if we cannot create the allocation on the host.
299304
// This results in an error that can happen non-deterministically, since the memory
300305
// available to the compiler can change between runs. Normally queries are always
@@ -306,7 +311,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
306311
Ok(Allocation {
307312
bytes,
308313
provenance: ProvenanceMap::new(),
309-
init_mask: InitMask::new(size, false),
314+
init_mask: InitMask::new(size, zero_init),
310315
align,
311316
mutability: Mutability::Mut,
312317
extra: (),
@@ -315,8 +320,8 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
315320

316321
/// Try to create an Allocation of `size` bytes, failing if there is not enough memory
317322
/// available to the compiler to do so.
318-
pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> {
319-
Self::uninit_inner(size, align, || {
323+
pub fn try_new<'tcx>(size: Size, align: Align, zero_init: bool) -> InterpResult<'tcx, Self> {
324+
Self::new_inner(size, align, zero_init, || {
320325
ty::tls::with(|tcx| tcx.dcx().delayed_bug("exhausted memory during interpretation"));
321326
InterpErrorKind::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
322327
})
@@ -328,51 +333,8 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
328333
///
329334
/// Example use case: To obtain an Allocation filled with specific data,
330335
/// first call this function and then call write_scalar to fill in the right data.
331-
pub fn uninit(size: Size, align: Align) -> Self {
332-
match Self::uninit_inner(size, align, || {
333-
panic!(
334-
"interpreter ran out of memory: cannot create allocation of {} bytes",
335-
size.bytes()
336-
);
337-
}) {
338-
Ok(x) => x,
339-
Err(x) => x,
340-
}
341-
}
342-
343-
fn zeroed_inner<R>(size: Size, align: Align, fail: impl FnOnce() -> R) -> Result<Self, R> {
344-
// We raise an error if we cannot create the allocation on the host.
345-
// This results in an error that can happen non-deterministically, since the memory
346-
// available to the compiler can change between runs. Normally queries are always
347-
// deterministic. However, we can be non-deterministic here because all uses of const
348-
// evaluation (including ConstProp!) will make compilation fail (via hard error
349-
// or ICE) upon encountering a `MemoryExhausted` error.
350-
let bytes = Bytes::zeroed(size, align).ok_or_else(fail)?;
351-
352-
Ok(Allocation {
353-
bytes,
354-
provenance: ProvenanceMap::new(),
355-
init_mask: InitMask::new(size, true),
356-
align,
357-
mutability: Mutability::Mut,
358-
extra: (),
359-
})
360-
}
361-
362-
/// Try to create an Allocation of `size` zero-initialized bytes, failing if there is not enough memory
363-
/// available to the compiler to do so.
364-
pub fn try_zeroed<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> {
365-
Self::zeroed_inner(size, align, || {
366-
ty::tls::with(|tcx| tcx.dcx().delayed_bug("exhausted memory during interpretation"));
367-
InterpErrorKind::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
368-
})
369-
.into()
370-
}
371-
372-
/// Try to create an Allocation of `size` zero-initialized bytes, panics if there is not enough memory
373-
/// available to the compiler to do so.
374-
pub fn zeroed(size: Size, align: Align) -> Self {
375-
match Self::zeroed_inner(size, align, || {
336+
pub fn new(size: Size, align: Align, zero_init: bool) -> Self {
337+
match Self::new_inner(size, align, zero_init, || {
376338
panic!(
377339
"interpreter ran out of memory: cannot create allocation of {} bytes",
378340
size.bytes()

compiler/rustc_middle/src/ty/vtable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
108108
let ptr_align = tcx.data_layout.pointer_align.abi;
109109

110110
let vtable_size = ptr_size * u64::try_from(vtable_entries.len()).unwrap();
111-
let mut vtable = Allocation::uninit(vtable_size, ptr_align);
111+
let mut vtable = Allocation::new(vtable_size, ptr_align, false);
112112

113113
// No need to do any alignment checks on the memory accesses below, because we know the
114114
// allocation is correctly aligned as we created it above. Also we're only offsetting by

compiler/rustc_smir/src/rustc_smir/alloc.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ pub(crate) fn try_new_allocation<'tcx>(
4444
.layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty))
4545
.map_err(|e| e.stable(tables))?
4646
.align;
47-
let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi);
47+
let mut allocation =
48+
rustc_middle::mir::interpret::Allocation::new(size, align.abi, false);
4849
allocation
4950
.write_scalar(&tables.tcx, alloc_range(Size::ZERO, size), scalar)
5051
.map_err(|e| e.stable(tables))?;
@@ -69,7 +70,7 @@ pub(crate) fn try_new_allocation<'tcx>(
6970
.layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty))
7071
.map_err(|e| e.stable(tables))?;
7172
let mut allocation =
72-
rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
73+
rustc_middle::mir::interpret::Allocation::new(layout.size, layout.align.abi, false);
7374
allocation
7475
.write_scalar(
7576
&tables.tcx,

src/tools/miri/src/shims/alloc.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
8181
fn malloc(&mut self, size: u64, zero_init: bool) -> InterpResult<'tcx, Pointer> {
8282
let this = self.eval_context_mut();
8383
let align = this.malloc_align(size);
84-
let ptr = if zero_init {
85-
this.allocate_zeroed_ptr(Size::from_bytes(size), align, MiriMemoryKind::C.into())?
86-
} else {
87-
this.allocate_ptr(Size::from_bytes(size), align, MiriMemoryKind::C.into())?
88-
};
84+
let ptr = this.allocate_ptr(Size::from_bytes(size), align, MiriMemoryKind::C.into(), zero_init)?;
8985
interp_ok(ptr.into())
9086
}
9187

@@ -109,6 +105,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
109105
Size::from_bytes(size),
110106
Align::from_bytes(align).unwrap(),
111107
MiriMemoryKind::C.into(),
108+
false
112109
)?;
113110
this.write_pointer(ptr, &memptr)?;
114111
interp_ok(Scalar::from_i32(0))
@@ -141,6 +138,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
141138
Size::from_bytes(new_size),
142139
new_align,
143140
MiriMemoryKind::C.into(),
141+
false
144142
)?;
145143
interp_ok(new_ptr.into())
146144
}
@@ -181,6 +179,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
181179
Size::from_bytes(size),
182180
Align::from_bytes(align).unwrap(),
183181
MiriMemoryKind::C.into(),
182+
false
184183
)?;
185184
interp_ok(ptr.into())
186185
}

src/tools/miri/src/shims/foreign_items.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
508508
Size::from_bytes(size),
509509
Align::from_bytes(align).unwrap(),
510510
memory_kind.into(),
511+
false
511512
)?;
512513

513514
ecx.write_pointer(ptr, dest)
@@ -532,10 +533,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
532533

533534
this.check_rustc_alloc_request(size, align)?;
534535

535-
let ptr = this.allocate_zeroed_ptr(
536+
let ptr = this.allocate_ptr(
536537
Size::from_bytes(size),
537538
Align::from_bytes(align).unwrap(),
538539
MiriMemoryKind::Rust.into(),
540+
true
539541
)?;
540542
this.write_pointer(ptr, dest)
541543
});
@@ -596,6 +598,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
596598
Size::from_bytes(new_size),
597599
align,
598600
MiriMemoryKind::Rust.into(),
601+
false
599602
)?;
600603
this.write_pointer(new_ptr, dest)
601604
});

src/tools/miri/src/shims/unix/fs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11091109
Size::from_bytes(size),
11101110
dirent_layout.align.abi,
11111111
MiriMemoryKind::Runtime.into(),
1112+
false
11121113
)?;
11131114
let entry: Pointer = entry.into();
11141115

src/tools/miri/src/shims/unix/linux/mem.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
4949
Size::from_bytes(new_size),
5050
align,
5151
MiriMemoryKind::Mmap.into(),
52+
true
5253
)?;
53-
if let Some(increase) = new_size.checked_sub(old_size) {
54-
// We just allocated this, the access is definitely in-bounds and fits into our address space.
55-
// mmap guarantees new mappings are zero-init.
56-
this.write_bytes_ptr(
57-
ptr.wrapping_offset(Size::from_bytes(old_size), this).into(),
58-
std::iter::repeat(0u8).take(usize::try_from(increase).unwrap()),
59-
)
60-
.unwrap();
61-
}
6254

6355
interp_ok(Scalar::from_pointer(ptr, this))
6456
}

src/tools/miri/src/shims/unix/mem.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
111111
return interp_ok(this.eval_libc("MAP_FAILED"));
112112
}
113113

114-
// mmap guarantees new mappings are zero-init.
115-
let ptr = this.allocate_zeroed_ptr(
114+
let ptr = this.allocate_ptr(
116115
Size::from_bytes(map_length),
117116
align,
118117
MiriMemoryKind::Mmap.into(),
118+
// mmap guarantees new mappings are zero-init.
119+
true
119120
)?;
120121

121122
interp_ok(Scalar::from_pointer(ptr, this))

src/tools/miri/src/shims/windows/foreign_items.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -258,19 +258,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
258258
// Alignment is twice the pointer size.
259259
// Source: <https://learn.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapalloc>
260260
let align = this.tcx.pointer_size().bytes().strict_mul(2);
261-
let ptr = if zero_init {
262-
this.allocate_zeroed_ptr(
263-
Size::from_bytes(size),
264-
Align::from_bytes(align).unwrap(),
265-
MiriMemoryKind::WinHeap.into(),
266-
)?
267-
} else {
268-
this.allocate_ptr(
269-
Size::from_bytes(size),
270-
Align::from_bytes(align).unwrap(),
271-
MiriMemoryKind::WinHeap.into(),
272-
)?
273-
};
261+
let ptr = this.allocate_ptr(
262+
Size::from_bytes(size),
263+
Align::from_bytes(align).unwrap(),
264+
MiriMemoryKind::WinHeap.into(),
265+
zero_init
266+
)?;
274267
this.write_pointer(ptr, dest)?;
275268
}
276269
"HeapFree" => {
@@ -302,6 +295,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
302295
Size::from_bytes(size),
303296
Align::from_bytes(align).unwrap(),
304297
MiriMemoryKind::WinHeap.into(),
298+
false
305299
)?;
306300
this.write_pointer(new_ptr, dest)?;
307301
}

0 commit comments

Comments
 (0)