Never start the Stack::retain loop at offset 0 so that the left element is always inbounds
This commit is contained in:
parent
1c294d1de2
commit
e7faf046c0
@ -43,10 +43,14 @@ impl Stack {
|
||||
pub fn retain(&mut self, tags: &FxHashSet<SbTag>) {
|
||||
let mut first_removed = None;
|
||||
|
||||
// For stacks with a known bottom, we never consider removing the bottom-most tag, because
|
||||
// that is the base tag which exists whether or not there are any pointers to the
|
||||
// allocation.
|
||||
let mut read_idx = if self.unknown_bottom.is_some() { 0 } else { 1 };
|
||||
// We never consider removing the bottom-most tag. For stacks without an unknown
|
||||
// bottom this preserves the base tag.
|
||||
// Note that the algorithm below is based on considering the tag at read_idx - 1,
|
||||
// so precisely considering the tag at index 0 for removal when we have an unknown
|
||||
// bottom would complicate the implementation. The simplification of not considering
|
||||
// it does not have a significant impact on the degree to which the GC mititages
|
||||
// memory growth.
|
||||
let mut read_idx = 1;
|
||||
let mut write_idx = read_idx;
|
||||
while read_idx < self.borrows.len() {
|
||||
let left = self.borrows[read_idx - 1];
|
||||
|
@ -0,0 +1,21 @@
|
||||
//@compile-flags: -Zmiri-permissive-provenance
|
||||
#![feature(strict_provenance)]
|
||||
|
||||
use std::ptr;
|
||||
|
||||
fn main() {
|
||||
let mut v = 1u8;
|
||||
let ptr = &mut v as *mut u8;
|
||||
|
||||
// Expose the allocation and use the exposed pointer, creating an unknown bottom
|
||||
unsafe {
|
||||
let p: *mut u8 = ptr::from_exposed_addr::<u8>(ptr.expose_addr()) as *mut u8;
|
||||
*p = 1;
|
||||
}
|
||||
|
||||
// Pile on a lot of SharedReadOnly at the top of the stack
|
||||
let r = &v;
|
||||
for _ in 0..1024 {
|
||||
let _x = &*r;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user