Skip to content

Commit 94dacfd

Browse files
author
Ellen Arteca
committed
moving the intptrcast int_to_ptr_map from a vector to a btreemap
1 parent a87fdb3 commit 94dacfd

File tree

1 file changed

+26
-25
lines changed

1 file changed

+26
-25
lines changed

src/intptrcast.rs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::cell::RefCell;
22
use std::cmp::max;
3-
use std::collections::hash_map::Entry;
3+
use std::collections::{hash_map::Entry, BTreeMap};
44

55
use log::trace;
66
use rand::Rng;
@@ -26,9 +26,9 @@ pub type GlobalState = RefCell<GlobalStateInner>;
2626

2727
#[derive(Clone, Debug)]
2828
pub struct GlobalStateInner {
29-
/// This is used as a map between the address of each allocation and its `AllocId`.
30-
/// It is always sorted
31-
int_to_ptr_map: Vec<(u64, AllocId)>,
29+
/// This is a map between the address of each allocation and its `AllocId`.
30+
/// Since it's a `BTreeMap`, it is always sorted, and provides efficient insertion.
31+
int_to_ptr_map: BTreeMap<u64, AllocId>,
3232
/// The base address for each allocation. We cannot put that into
3333
/// `AllocExtra` because function pointers also have a base address, and
3434
/// they do not have an `AllocExtra`.
@@ -44,7 +44,7 @@ pub struct GlobalStateInner {
4444
impl GlobalStateInner {
4545
pub fn new(config: &MiriConfig) -> Self {
4646
GlobalStateInner {
47-
int_to_ptr_map: Vec::default(),
47+
int_to_ptr_map: BTreeMap::default(),
4848
base_addr: FxHashMap::default(),
4949
exposed: FxHashSet::default(),
5050
provenance_mode: config.provenance_mode,
@@ -59,22 +59,26 @@ impl<'mir, 'tcx> GlobalStateInner {
5959
let global_state = ecx.machine.intptrcast.borrow();
6060
assert!(global_state.provenance_mode != ProvenanceMode::Strict);
6161

62-
let pos = global_state.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr);
63-
6462
// Determine the in-bounds provenance for this pointer.
6563
// (This is only called on an actual access, so in-bounds is the only possible kind of provenance.)
66-
let alloc_id = match pos {
67-
Ok(pos) => Some(global_state.int_to_ptr_map[pos].1),
68-
Err(0) => None,
69-
Err(pos) => {
70-
// This is the largest of the adresses smaller than `int`,
71-
// i.e. the greatest lower bound (glb)
72-
let (glb, alloc_id) = global_state.int_to_ptr_map[pos - 1];
73-
// This never overflows because `addr >= glb`
74-
let offset = addr - glb;
75-
// If the offset exceeds the size of the allocation, don't use this `alloc_id`.
76-
let size = ecx.get_alloc_info(alloc_id).0;
77-
if offset <= size.bytes() { Some(alloc_id) } else { None }
64+
let alloc_id = match global_state.int_to_ptr_map.get(&addr) {
65+
Some(&id) => Some(id),
66+
None => {
67+
// If the address is not in the map, we check the position it should be inserted at.
68+
// This returns the max key in the map less than `addr`.
69+
match global_state.int_to_ptr_map.range(..addr).next_back() {
70+
// Should be inserted at the beginning.
71+
None => None,
72+
// This is the largest of the adresses smaller than `int`,
73+
// i.e. the greatest lower bound (glb).
74+
Some((glb, &alloc_id)) => {
75+
// This never overflows because `addr >= glb`
76+
let offset = addr - glb;
77+
// If the offset exceeds the size of the allocation, don't use this `alloc_id`.
78+
let size = ecx.get_alloc_info(alloc_id).0;
79+
if offset <= size.bytes() { Some(alloc_id) } else { None }
80+
}
81+
}
7882
}
7983
}?;
8084

@@ -183,12 +187,9 @@ impl<'mir, 'tcx> GlobalStateInner {
183187
align.bytes(),
184188
);
185189

186-
// TODO replace int_to_ptr_map's data structure, since even if we binary search for
187-
// the insert location, the insertion is still linear (due to copies)
188-
// I've done it the dumb obviously correct way for now.
189-
global_state.int_to_ptr_map.retain(|&(ref a,_)| a != &base_addr);
190-
global_state.int_to_ptr_map.push((base_addr, alloc_id));
191-
global_state.int_to_ptr_map.sort();
190+
// Map has no duplicates so no need to remove copies.
191+
// Map is always sorted.
192+
global_state.int_to_ptr_map.insert(base_addr, alloc_id);
192193

193194
base_addr
194195
}

0 commit comments

Comments
 (0)