Skip to content

Commit 74092c5

Browse files
committed
Auto merge of #3134 - RalfJung:log-not-lin, r=saethlin
avoid a linear scan over the entire int_to_ptr_map on each deallocation
2 parents f35c36a + 48445b9 commit 74092c5

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

src/tools/miri/src/intptrcast.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ pub type GlobalState = RefCell<GlobalStateInner>;
2727
#[derive(Clone, Debug)]
2828
pub struct GlobalStateInner {
2929
/// This is used as a map between the address of each allocation and its `AllocId`. It is always
30-
/// sorted. We cannot use a `HashMap` since we can be given an address that is offset from the
31-
/// base address, and we need to find the `AllocId` it belongs to.
32-
/// This is not the *full* inverse of `base_addr`; dead allocations have been removed.
30+
/// sorted by address. We cannot use a `HashMap` since we can be given an address that is offset
31+
/// from the base address, and we need to find the `AllocId` it belongs to. This is not the
32+
/// *full* inverse of `base_addr`; dead allocations have been removed.
3333
int_to_ptr_map: Vec<(u64, AllocId)>,
3434
/// The base address for each allocation. We cannot put that into
3535
/// `AllocExtra` because function pointers also have a base address, and
@@ -285,7 +285,12 @@ impl GlobalStateInner {
285285
// However, we *can* remove it from `int_to_ptr_map`, since any wildcard pointers that exist
286286
// can no longer actually be accessing that address. This ensures `alloc_id_from_addr` never
287287
// returns a dead allocation.
288-
self.int_to_ptr_map.retain(|&(_, id)| id != dead_id);
288+
// To avoid a linear scan we first look up the address in `base_addr`, and then find it in
289+
// `int_to_ptr_map`.
290+
let addr = *self.base_addr.get(&dead_id).unwrap();
291+
let pos = self.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr).unwrap();
292+
let removed = self.int_to_ptr_map.remove(pos);
293+
assert_eq!(removed, (addr, dead_id)); // double-check that we removed the right thing
289294
// We can also remove it from `exposed`, since this allocation can anyway not be returned by
290295
// `alloc_id_from_addr` any more.
291296
self.exposed.remove(&dead_id);

0 commit comments

Comments
 (0)