Skip to content

Commit a88fc0e

Browse files
committed
Auto merge of #141860 - RalfJung:miri-sync, r=RalfJung
Miri subtree update r? `@ghost` Includes rust-lang/miri#4370 to unbreak PR CI. (So we're committing to having bda28aa38 in the Miri history by landing this, whether or not that Miri PR lands.) Cc `@Noratrieb` `@tiif`
2 parents 9b0268a + 0884c68 commit a88fc0e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1300
-246
lines changed

src/tools/miri/cargo-miri/src/phases.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
9090
"`cargo miri` supports the following subcommands: `run`, `test`, `nextest`, `clean`, and `setup`."
9191
),
9292
};
93-
let verbose = num_arg_flag("-v");
93+
let verbose = num_arg_flag("-v") + num_arg_flag("--verbose");
9494
let quiet = has_arg_flag("-q") || has_arg_flag("--quiet");
9595

9696
// Determine the involved architectures.

src/tools/miri/ci/ci.sh

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,12 @@ case $HOST_TARGET in
142142
# Host
143143
GC_STRESS=1 MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests
144144
# Extra tier 1
145-
# With reduced many-seed count to avoid spending too much time on that.
146-
# (All OSes and ABIs are run with 64 seeds at least once though via the macOS runner.)
147-
MANY_SEEDS=16 TEST_TARGET=i686-unknown-linux-gnu run_tests
148-
MANY_SEEDS=16 TEST_TARGET=aarch64-unknown-linux-gnu run_tests
149-
MANY_SEEDS=16 TEST_TARGET=x86_64-apple-darwin run_tests
150-
MANY_SEEDS=16 TEST_TARGET=x86_64-pc-windows-gnu run_tests
145+
MANY_SEEDS=64 TEST_TARGET=i686-unknown-linux-gnu run_tests
146+
MANY_SEEDS=64 TEST_TARGET=aarch64-unknown-linux-gnu run_tests
147+
MANY_SEEDS=64 TEST_TARGET=x86_64-apple-darwin run_tests
148+
MANY_SEEDS=64 TEST_TARGET=x86_64-pc-windows-gnu run_tests
149+
# Extra tier 1 candidate
150+
MANY_SEEDS=64 TEST_TARGET=aarch64-pc-windows-msvc run_tests
151151
;;
152152
aarch64-apple-darwin)
153153
# Host
@@ -156,7 +156,8 @@ case $HOST_TARGET in
156156
MANY_SEEDS=64 TEST_TARGET=i686-pc-windows-gnu run_tests
157157
MANY_SEEDS=64 TEST_TARGET=x86_64-pc-windows-msvc CARGO_MIRI_ENV=1 run_tests
158158
# Extra tier 2
159-
MANY_SEEDS=16 TEST_TARGET=arm-unknown-linux-gnueabi run_tests
159+
MANY_SEEDS=16 TEST_TARGET=arm-unknown-linux-gnueabi run_tests # 32bit ARM
160+
MANY_SEEDS=16 TEST_TARGET=aarch64-pc-windows-gnullvm run_tests # gnullvm ABI
160161
MANY_SEEDS=16 TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
161162
# Not officially supported tier 2
162163
MANY_SEEDS=16 TEST_TARGET=mips-unknown-linux-gnu run_tests # a 32bit big-endian target, and also a target without 64bit atomics
@@ -178,7 +179,7 @@ case $HOST_TARGET in
178179
# Host
179180
# Without GC_STRESS and with reduced many-seeds count as this is the slowest runner.
180181
# (The macOS runner checks windows-msvc with full many-seeds count.)
181-
MIR_OPT=1 MANY_SEEDS=16 TEST_BENCH=1 run_tests
182+
MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 run_tests
182183
# Extra tier 1
183184
# We really want to ensure a Linux target works on a Windows host,
184185
# and a 64bit target works on a 32bit host.

src/tools/miri/miri-script/src/commands.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use std::collections::BTreeMap;
22
use std::ffi::{OsStr, OsString};
33
use std::fmt::Write as _;
44
use std::fs::{self, File};
@@ -404,7 +404,28 @@ impl Command {
404404
// We want to forward the host stdin so apparently we cannot use `cmd!`.
405405
let mut cmd = process::Command::new("git");
406406
cmd.arg("rebase").arg(&base).arg("--interactive");
407-
cmd.env("GIT_SEQUENCE_EDITOR", env::current_exe()?);
407+
let current_exe = {
408+
if cfg!(windows) {
409+
// Apparently git-for-Windows gets confused by backslashes if we just use
410+
// `current_exe()` here. So replace them by forward slashes if this is not a "magic"
411+
// path starting with "\\". This is clearly a git bug but we work around it here.
412+
// Also see <https://github.com/rust-lang/miri/issues/4340>.
413+
let bin = env::current_exe()?;
414+
match bin.into_os_string().into_string() {
415+
Err(not_utf8) => not_utf8.into(), // :shrug:
416+
Ok(str) => {
417+
if str.starts_with(r"\\") {
418+
str.into() // don't touch these magic paths, they must use backslashes
419+
} else {
420+
str.replace('\\', "/").into()
421+
}
422+
}
423+
}
424+
} else {
425+
env::current_exe()?
426+
}
427+
};
428+
cmd.env("GIT_SEQUENCE_EDITOR", current_exe);
408429
cmd.env("MIRI_SCRIPT_IS_GIT_SEQUENCE_EDITOR", "1");
409430
cmd.current_dir(sh.current_dir());
410431
let result = cmd.status()?;
@@ -489,7 +510,9 @@ impl Command {
489510
sh.read_dir(benches_dir)?
490511
.into_iter()
491512
.filter(|path| path.is_dir())
492-
.map(|path| path.into_os_string().into_string().unwrap())
513+
// Only keep the basename: that matches the usage with a manual bench list,
514+
// and it ensure the path concatenations below work as intended.
515+
.map(|path| path.file_name().unwrap().to_owned().into_string().unwrap())
493516
.collect()
494517
} else {
495518
benches.into_iter().collect()
@@ -530,14 +553,16 @@ impl Command {
530553
stddev: f64,
531554
}
532555

533-
let gather_results = || -> Result<HashMap<&str, BenchResult>> {
556+
let gather_results = || -> Result<BTreeMap<&str, BenchResult>> {
534557
let baseline_temp_dir = results_json_dir.unwrap();
535-
let mut results = HashMap::new();
558+
let mut results = BTreeMap::new();
536559
for bench in &benches {
537-
let result = File::open(path!(baseline_temp_dir / format!("{bench}.bench.json")))?;
538-
let mut result: serde_json::Value =
539-
serde_json::from_reader(BufReader::new(result))?;
540-
let result: BenchResult = serde_json::from_value(result["results"][0].take())?;
560+
let result = File::open(path!(baseline_temp_dir / format!("{bench}.bench.json")))
561+
.context("failed to read hyperfine JSON")?;
562+
let mut result: serde_json::Value = serde_json::from_reader(BufReader::new(result))
563+
.context("failed to parse hyperfine JSON")?;
564+
let result: BenchResult = serde_json::from_value(result["results"][0].take())
565+
.context("failed to interpret hyperfine JSON")?;
541566
results.insert(bench as &str, result);
542567
}
543568
Ok(results)
@@ -549,15 +574,15 @@ impl Command {
549574
serde_json::to_writer_pretty(BufWriter::new(baseline), &results)?;
550575
} else if let Some(baseline_file) = load_baseline {
551576
let new_results = gather_results()?;
552-
let baseline_results: HashMap<String, BenchResult> = {
577+
let baseline_results: BTreeMap<String, BenchResult> = {
553578
let f = File::open(baseline_file)?;
554579
serde_json::from_reader(BufReader::new(f))?
555580
};
556581
println!(
557582
"Comparison with baseline (relative speed, lower is better for the new results):"
558583
);
559-
for (bench, new_result) in new_results.iter() {
560-
let Some(baseline_result) = baseline_results.get(*bench) else { continue };
584+
for (bench, new_result) in new_results {
585+
let Some(baseline_result) = baseline_results.get(bench) else { continue };
561586

562587
// Compare results (inspired by hyperfine)
563588
let ratio = new_result.mean / baseline_result.mean;

src/tools/miri/rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2b96ddca1272960623e41829439df8dae82d20af
1+
337c11e5932275e7d450c1f2e26f289f0ddfa717

src/tools/miri/src/alloc_bytes.rs renamed to src/tools/miri/src/alloc/alloc_bytes.rs

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
use std::alloc::Layout;
22
use std::borrow::Cow;
33
use std::{alloc, slice};
4+
#[cfg(target_os = "linux")]
5+
use std::{cell::RefCell, rc::Rc};
46

57
use rustc_abi::{Align, Size};
68
use rustc_middle::mir::interpret::AllocBytes;
79

10+
#[cfg(target_os = "linux")]
11+
use crate::alloc::isolated_alloc::IsolatedAlloc;
812
use crate::helpers::ToU64 as _;
913

14+
#[derive(Clone, Debug)]
15+
pub enum MiriAllocParams {
16+
Global,
17+
#[cfg(target_os = "linux")]
18+
Isolated(Rc<RefCell<IsolatedAlloc>>),
19+
}
20+
1021
/// Allocation bytes that explicitly handle the layout of the data they're storing.
1122
/// This is necessary to interface with native code that accesses the program store in Miri.
1223
#[derive(Debug)]
@@ -18,13 +29,16 @@ pub struct MiriAllocBytes {
1829
/// * If `self.layout.size() == 0`, then `self.ptr` was allocated with the equivalent layout with size 1.
1930
/// * Otherwise, `self.ptr` points to memory allocated with `self.layout`.
2031
ptr: *mut u8,
32+
/// Whether this instance of `MiriAllocBytes` had its allocation created by calling `alloc::alloc()`
33+
/// (`Global`) or the discrete allocator (`Isolated`)
34+
params: MiriAllocParams,
2135
}
2236

2337
impl Clone for MiriAllocBytes {
2438
fn clone(&self) -> Self {
2539
let bytes: Cow<'_, [u8]> = Cow::Borrowed(self);
2640
let align = Align::from_bytes(self.layout.align().to_u64()).unwrap();
27-
MiriAllocBytes::from_bytes(bytes, align, ())
41+
MiriAllocBytes::from_bytes(bytes, align, self.params.clone())
2842
}
2943
}
3044

@@ -37,8 +51,16 @@ impl Drop for MiriAllocBytes {
3751
} else {
3852
self.layout
3953
};
54+
4055
// SAFETY: Invariant, `self.ptr` points to memory allocated with `self.layout`.
41-
unsafe { alloc::dealloc(self.ptr, alloc_layout) }
56+
unsafe {
57+
match self.params.clone() {
58+
MiriAllocParams::Global => alloc::dealloc(self.ptr, alloc_layout),
59+
#[cfg(target_os = "linux")]
60+
MiriAllocParams::Isolated(alloc) =>
61+
alloc.borrow_mut().dealloc(self.ptr, alloc_layout),
62+
}
63+
}
4264
}
4365
}
4466

@@ -67,35 +89,45 @@ impl MiriAllocBytes {
6789
fn alloc_with(
6890
size: u64,
6991
align: u64,
70-
alloc_fn: impl FnOnce(Layout) -> *mut u8,
92+
params: MiriAllocParams,
93+
alloc_fn: impl FnOnce(Layout, &MiriAllocParams) -> *mut u8,
7194
) -> Result<MiriAllocBytes, ()> {
7295
let size = usize::try_from(size).map_err(|_| ())?;
7396
let align = usize::try_from(align).map_err(|_| ())?;
7497
let layout = Layout::from_size_align(size, align).map_err(|_| ())?;
7598
// When size is 0 we allocate 1 byte anyway, to ensure each allocation has a unique address.
7699
let alloc_layout =
77100
if size == 0 { Layout::from_size_align(1, align).unwrap() } else { layout };
78-
let ptr = alloc_fn(alloc_layout);
101+
let ptr = alloc_fn(alloc_layout, &params);
79102
if ptr.is_null() {
80103
Err(())
81104
} else {
82105
// SAFETY: All `MiriAllocBytes` invariants are fulfilled.
83-
Ok(Self { ptr, layout })
106+
Ok(Self { ptr, layout, params })
84107
}
85108
}
86109
}
87110

88111
impl AllocBytes for MiriAllocBytes {
89-
/// Placeholder!
90-
type AllocParams = ();
112+
type AllocParams = MiriAllocParams;
91113

92-
fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, align: Align, _params: ()) -> Self {
114+
fn from_bytes<'a>(
115+
slice: impl Into<Cow<'a, [u8]>>,
116+
align: Align,
117+
params: MiriAllocParams,
118+
) -> Self {
93119
let slice = slice.into();
94120
let size = slice.len();
95121
let align = align.bytes();
96122
// SAFETY: `alloc_fn` will only be used with `size != 0`.
97-
let alloc_fn = |layout| unsafe { alloc::alloc(layout) };
98-
let alloc_bytes = MiriAllocBytes::alloc_with(size.to_u64(), align, alloc_fn)
123+
let alloc_fn = |layout, params: &MiriAllocParams| unsafe {
124+
match params {
125+
MiriAllocParams::Global => alloc::alloc(layout),
126+
#[cfg(target_os = "linux")]
127+
MiriAllocParams::Isolated(alloc) => alloc.borrow_mut().alloc(layout),
128+
}
129+
};
130+
let alloc_bytes = MiriAllocBytes::alloc_with(size.to_u64(), align, params, alloc_fn)
99131
.unwrap_or_else(|()| {
100132
panic!("Miri ran out of memory: cannot create allocation of {size} bytes")
101133
});
@@ -105,12 +137,18 @@ impl AllocBytes for MiriAllocBytes {
105137
alloc_bytes
106138
}
107139

108-
fn zeroed(size: Size, align: Align, _params: ()) -> Option<Self> {
140+
fn zeroed(size: Size, align: Align, params: MiriAllocParams) -> Option<Self> {
109141
let size = size.bytes();
110142
let align = align.bytes();
111143
// SAFETY: `alloc_fn` will only be used with `size != 0`.
112-
let alloc_fn = |layout| unsafe { alloc::alloc_zeroed(layout) };
113-
MiriAllocBytes::alloc_with(size, align, alloc_fn).ok()
144+
let alloc_fn = |layout, params: &MiriAllocParams| unsafe {
145+
match params {
146+
MiriAllocParams::Global => alloc::alloc_zeroed(layout),
147+
#[cfg(target_os = "linux")]
148+
MiriAllocParams::Isolated(alloc) => alloc.borrow_mut().alloc_zeroed(layout),
149+
}
150+
};
151+
MiriAllocBytes::alloc_with(size, align, params, alloc_fn).ok()
114152
}
115153

116154
fn as_mut_ptr(&mut self) -> *mut u8 {

0 commit comments

Comments
 (0)