Skip to content

Commit c111151

Browse files
committed
Evict dead entries on PtrRegistry::put
1 parent 41fa40b commit c111151

1 file changed

Lines changed: 48 additions & 13 deletions

File tree

libcc2rs/src/rc.rs

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,7 @@ impl RangeAllocator {
12451245
}
12461246
}
12471247

1248-
fn base_for(&mut self, real_addr: RealAddr, byte_len: ByteLen) -> SyntheticAddr {
1248+
fn get_synthetic_addr(&mut self, real_addr: RealAddr, byte_len: ByteLen) -> SyntheticAddr {
12491249
if let Some(&(base, capacity)) = self.bases.get(&real_addr)
12501250
&& byte_len <= capacity
12511251
{
@@ -1258,10 +1258,50 @@ impl RangeAllocator {
12581258
}
12591259
}
12601260

1261+
struct PtrRegistry {
1262+
ranges: RangeAllocator,
1263+
entries: BTreeMap<SyntheticAddr, (AnyPtr, ByteLen)>,
1264+
swept_len: usize,
1265+
}
1266+
1267+
impl PtrRegistry {
1268+
fn new() -> Self {
1269+
Self {
1270+
ranges: RangeAllocator::new(),
1271+
entries: BTreeMap::new(),
1272+
swept_len: 0,
1273+
}
1274+
}
1275+
1276+
fn put(&mut self, real_addr: RealAddr, byte_len: ByteLen, ptr: AnyPtr) -> SyntheticAddr {
1277+
self.evict_dead();
1278+
let base = self.ranges.get_synthetic_addr(real_addr, byte_len);
1279+
self.entries.insert(base, (ptr, byte_len));
1280+
base
1281+
}
1282+
1283+
fn get(&self, addr: SyntheticAddr) -> Option<(SyntheticAddr, AnyPtr, ByteLen)> {
1284+
self.entries
1285+
.range(..=addr)
1286+
.next_back()
1287+
.map(|(base, (any, len))| (*base, any.clone(), *len))
1288+
}
1289+
1290+
fn evict_dead(&mut self) {
1291+
if self.entries.len() < 16.max(2 * self.swept_len) {
1292+
return;
1293+
}
1294+
self.entries.retain(|_, (any, _)| !any.ptr.is_dangling());
1295+
let entries = &self.entries;
1296+
self.ranges
1297+
.bases
1298+
.retain(|_, &mut (base, _)| entries.contains_key(&base));
1299+
self.swept_len = self.entries.len();
1300+
}
1301+
}
1302+
12611303
thread_local! {
1262-
static PTR_RANGE_ALLOC: RefCell<RangeAllocator> = RefCell::new(RangeAllocator::new());
1263-
static PTR_REGISTRY: RefCell<BTreeMap<SyntheticAddr, (AnyPtr, ByteLen)>> =
1264-
const { RefCell::new(BTreeMap::new()) };
1304+
static PTR_REGISTRY: RefCell<PtrRegistry> = RefCell::new(PtrRegistry::new());
12651305
}
12661306

12671307
impl<T: ByteRepr> ByteRepr for Ptr<T> {
@@ -1281,13 +1321,13 @@ impl<T: ByteRepr> ByteRepr for Ptr<T> {
12811321
self.len() * T::byte_size(),
12821322
),
12831323
};
1284-
let base = PTR_RANGE_ALLOC.with(|a| a.borrow_mut().base_for(self.kind.address(), byte_len));
12851324
let rebased = Ptr {
12861325
offset: 0,
12871326
kind: self.kind.clone(),
12881327
};
1289-
PTR_REGISTRY.with(|r| {
1290-
r.borrow_mut().insert(base, (rebased.to_any(), byte_len));
1328+
let base = PTR_REGISTRY.with(|r| {
1329+
r.borrow_mut()
1330+
.put(self.kind.address(), byte_len, rebased.to_any())
12911331
});
12921332
base.wrapping_add(byte_off).to_bytes(buf);
12931333
}
@@ -1297,12 +1337,7 @@ impl<T: ByteRepr> ByteRepr for Ptr<T> {
12971337
if addr == 0 {
12981338
return Ptr::null();
12991339
}
1300-
let entry = PTR_REGISTRY.with(|r| {
1301-
r.borrow()
1302-
.range(..=addr)
1303-
.next_back()
1304-
.map(|(base, (any, len))| (*base, any.clone(), *len))
1305-
});
1340+
let entry = PTR_REGISTRY.with(|r| r.borrow().get(addr));
13061341
let Some((base, any, byte_len)) = entry else {
13071342
panic!("ub: cast of invalid address 0x{addr:x} to pointer");
13081343
};

0 commit comments

Comments
 (0)