Skip to content

Commit

Permalink
Rollup merge of rust-lang#129785 - RalfJung:miri-sync, r=RalfJung
Browse files Browse the repository at this point in the history
Miri subtree update

r? `@ghost`
  • Loading branch information
workingjubilee authored Aug 31, 2024
2 parents a8616b9 + f03c7b2 commit 296e85f
Show file tree
Hide file tree
Showing 68 changed files with 1,197 additions and 441 deletions.
7 changes: 7 additions & 0 deletions src/tools/miri/bench-cargo-miri/slice-chunked/Cargo.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "slice-chunked"
version = "0.1.0"
8 changes: 8 additions & 0 deletions src/tools/miri/bench-cargo-miri/slice-chunked/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "slice-chunked"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
26 changes: 26 additions & 0 deletions src/tools/miri/bench-cargo-miri/slice-chunked/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! This is a small example using slice::chunks, which creates a very large Tree Borrows tree.
//! Thanks to ##3837, the GC now compacts the tree, so this test can be run in a reasonable time again.
//! The actual code is adapted from tiny_skia, see https://github.com/RazrFalcon/tiny-skia/blob/master/src/pixmap.rs#L121
//! To make this benchmark demonstrate the effectiveness, run with MIRIFLAGS="-Zmiri-tree-borrows -Zmiri-provenance-gc=100"
const N: usize = 1000;

fn input_vec() -> Vec<u8> {
vec![0; N]
}

fn main() {
let data_len = 2 * N;
let mut rgba_data = Vec::with_capacity(data_len);
let img_data = input_vec();
for slice in img_data.chunks(2) {
let gray = slice[0];
let alpha = slice[1];
rgba_data.push(gray);
rgba_data.push(gray);
rgba_data.push(gray);
rgba_data.push(alpha);
}

assert_eq!(rgba_data.len(), data_len);
}
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fdf61d499c8a8421ecf98e7924bb87caf43a9938
0d634185dfddefe09047881175f35c65d68dcff1
6 changes: 6 additions & 0 deletions src/tools/miri/src/borrow_tracker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ pub struct FrameState {

impl VisitProvenance for FrameState {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
// Visit all protected tags. At least in Tree Borrows,
// protected tags can not be GC'd because they still have
// an access coming when the protector ends. Additionally,
// the tree compacting mechanism of TB's GC relies on the fact
// that all protected tags are marked as live for correctness,
// so we _have_ to visit them here.
for (id, tag) in &self.protected_tags {
visit(Some(*id), Some(*tag));
}
Expand Down
40 changes: 39 additions & 1 deletion src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ mod transition {
Active =>
if protected {
// We wrote, someone else reads -- that's bad.
// (If this is initialized, this move-to-protected will mean insta-UB.)
// (Since Active is always initialized, this move-to-protected will mean insta-UB.)
Disabled
} else {
// We don't want to disable here to allow read-read reordering: it is crucial
Expand Down Expand Up @@ -267,6 +267,44 @@ impl Permission {
transition::perform_access(kind, rel_pos, old_state, protected)
.map(|new_state| PermTransition { from: old_state, to: new_state })
}

/// During a provenance GC, we want to compact the tree.
/// For this, we want to merge nodes upwards if they have a singleton parent.
/// But we need to be careful: If the parent is Frozen, and the child is Reserved,
/// we can not do such a merge. In general, such a merge is possible if the parent
/// allows similar accesses, and in particular if the parent never causes UB on its
/// own. This is enforced by a test, namely `tree_compacting_is_sound`. See that
/// test for more information.
/// This method is only sound if the parent is not protected. We never attempt to
/// remove protected parents.
pub fn can_be_replaced_by_child(self, child: Self) -> bool {
match (self.inner, child.inner) {
// ReservedIM can be replaced by anything, as it allows all
// transitions.
(ReservedIM, _) => true,
// Reserved (as parent, where conflictedness does not matter)
// can be replaced by all but ReservedIM,
// since ReservedIM alone would survive foreign writes
(ReservedFrz { .. }, ReservedIM) => false,
(ReservedFrz { .. }, _) => true,
// Active can not be replaced by something surviving
// foreign reads and then remaining writable.
(Active, ReservedIM) => false,
(Active, ReservedFrz { .. }) => false,
// Replacing a state by itself is always okay, even if the child state is protected.
(Active, Active) => true,
// Active can be replaced by Frozen, since it is not protected.
(Active, Frozen) => true,
(Active, Disabled) => true,
// Frozen can only be replaced by Disabled (and itself).
(Frozen, Frozen) => true,
(Frozen, Disabled) => true,
(Frozen, _) => false,
// Disabled can not be replaced by anything else.
(Disabled, Disabled) => true,
(Disabled, _) => false,
}
}
}

impl PermTransition {
Expand Down
Loading

0 comments on commit 296e85f

Please sign in to comment.