Skip to content

Commit b3f7d2f

Browse files
committed
get_global_alloc_bytes refactor
1 parent 116dba4 commit b3f7d2f

File tree

3 files changed

+25
-27
lines changed

3 files changed

+25
-27
lines changed

src/tools/miri/src/alloc_addresses/mod.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -356,16 +356,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
356356

357357
// This returns some prepared `MiriAllocBytes`, either because `addr_from_alloc_id` reserved
358358
// memory space in the past, or by doing the pre-allocation right upon being called.
359-
fn take_prepared_alloc_bytes(&self, id: AllocId, kind: MemoryKind) -> InterpResult<'tcx, MiriAllocBytes> {
359+
fn get_global_alloc_bytes(&self, id: AllocId, kind: MemoryKind, bytes: &[u8], align: Align) -> InterpResult<'tcx, MiriAllocBytes> {
360360
let ecx = self.eval_context_ref();
361-
// This additional call ensures that some `MiriAllocBytes` are prepared.
362-
ecx.addr_from_alloc_id(id, kind)?;
363-
let mut global_state = ecx.machine.alloc_addresses.borrow_mut();
364-
let prepared_alloc_bytes = global_state
365-
.prepared_alloc_bytes
366-
.remove(&id)
367-
.unwrap_or_else(|| panic!("alloc bytes for {id:?} has not been prepared"));
368-
Ok(prepared_alloc_bytes)
361+
Ok(if ecx.machine.native_lib.is_some() {
362+
// This additional call ensures that some `MiriAllocBytes` are always prepared.
363+
ecx.addr_from_alloc_id(id, kind)?;
364+
let mut global_state = ecx.machine.alloc_addresses.borrow_mut();
365+
// The memory we need here will have already been allocated during an earlier call to
366+
// `global_root_pointer` for this allocation. So don't create a new `MiriAllocBytes` here, instead
367+
// fetch the previously prepared bytes from `prepared_alloc_bytes`.
368+
let mut prepared_alloc_bytes = global_state
369+
.prepared_alloc_bytes
370+
.remove(&id)
371+
.unwrap_or_else(|| panic!("alloc bytes for {id:?} have not been prepared"));
372+
assert!(prepared_alloc_bytes.as_ptr().is_aligned_to(align.bytes_usize()));
373+
assert_eq!(prepared_alloc_bytes.len(), bytes.len());
374+
// SAFETY: `alloc_bytes` and `bytes` span the same number of bytes.
375+
unsafe { prepared_alloc_bytes.as_mut_ptr().copy_from(bytes.as_ptr(), bytes.len()) };
376+
prepared_alloc_bytes
377+
} else {
378+
MiriAllocBytes::from_bytes(std::borrow::Cow::Borrowed(&*bytes), align)
379+
})
369380
}
370381

371382
/// When a pointer is used for a memory access, this computes where in which allocation the

src/tools/miri/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#![feature(strict_overflow_ops)]
1515
#![feature(strict_provenance)]
1616
#![feature(exposed_provenance)]
17+
#![feature(pointer_is_aligned_to)]
1718
// Configure clippy and other lints
1819
#![allow(
1920
clippy::collapsible_else_if,

src/tools/miri/src/machine.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,27 +1242,13 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
12421242
{
12431243
// The default implementation does a copy; CTFE machines have a more efficient implementation
12441244
// based on their particular choice for `Provenance`, `AllocExtra`, and `Bytes`.
1245-
let kind = Self::GLOBAL_KIND
1246-
.expect("if GLOBAL_KIND is None, adjust_global_allocation must be overwritten");
1247-
// This closure is special in that it relies on `take_prepared_alloc_bytes` to give it some
1248-
// reserved memory space in case Miri needs to handle addresses especially for native calls.
1249-
let alloc = alloc.adjust_from_tcx(&ecx.tcx, |bytes, align| {
1250-
Ok(if ecx.machine.native_lib.is_some() {
1251-
assert_eq!(alloc.align, align);
1252-
let kind = Self::GLOBAL_KIND.unwrap().into();
1253-
let mut alloc_bytes = ecx.take_prepared_alloc_bytes(id, kind)?;
1254-
assert_eq!(alloc_bytes.len(), bytes.len());
1255-
// SAFETY: `alloc_bytes` and `bytes` span the same number of bytes.
1256-
unsafe { alloc_bytes.as_mut_ptr().copy_from(bytes.as_ptr(), bytes.len()) };
1257-
alloc_bytes
1258-
} else {
1259-
MiriAllocBytes::from_bytes(Cow::Borrowed(&*bytes), align)
1260-
})
1261-
},
1245+
let kind = Self::GLOBAL_KIND.unwrap().into();
1246+
let alloc = alloc.adjust_from_tcx(&ecx.tcx,
1247+
|bytes, align| ecx.get_global_alloc_bytes(id, kind, bytes, align),
12621248
|ptr| ecx.global_root_pointer(ptr),
12631249
)?;
12641250
let extra =
1265-
Self::init_alloc_extra(ecx, id, MemoryKind::Machine(kind), alloc.size(), alloc.align)?;
1251+
Self::init_alloc_extra(ecx, id, kind, alloc.size(), alloc.align)?;
12661252
Ok(Cow::Owned(alloc.with_extra(extra)))
12671253
}
12681254

0 commit comments

Comments
 (0)