Skip to content

Commit 1001139

Browse files
committed
Evict dead entries on PtrRegistry::put
1 parent 5790e3b commit 1001139

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
@@ -1286,7 +1286,7 @@ impl RangeAllocator {
12861286
}
12871287
}
12881288

1289-
fn base_for(&mut self, real_addr: RealAddr, byte_len: ByteLen) -> SyntheticAddr {
1289+
fn get_synthetic_addr(&mut self, real_addr: RealAddr, byte_len: ByteLen) -> SyntheticAddr {
12901290
if let Some(&(base, capacity)) = self.bases.get(&real_addr)
12911291
&& byte_len <= capacity
12921292
{
@@ -1299,10 +1299,50 @@ impl RangeAllocator {
12991299
}
13001300
}
13011301

1302+
struct PtrRegistry {
1303+
ranges: RangeAllocator,
1304+
entries: BTreeMap<SyntheticAddr, (AnyPtr, ByteLen)>,
1305+
swept_len: usize,
1306+
}
1307+
1308+
impl PtrRegistry {
1309+
fn new() -> Self {
1310+
Self {
1311+
ranges: RangeAllocator::new(),
1312+
entries: BTreeMap::new(),
1313+
swept_len: 0,
1314+
}
1315+
}
1316+
1317+
fn put(&mut self, real_addr: RealAddr, byte_len: ByteLen, ptr: AnyPtr) -> SyntheticAddr {
1318+
self.evict_dead();
1319+
let base = self.ranges.get_synthetic_addr(real_addr, byte_len);
1320+
self.entries.insert(base, (ptr, byte_len));
1321+
base
1322+
}
1323+
1324+
fn get(&self, addr: SyntheticAddr) -> Option<(SyntheticAddr, AnyPtr, ByteLen)> {
1325+
self.entries
1326+
.range(..=addr)
1327+
.next_back()
1328+
.map(|(base, (any, len))| (*base, any.clone(), *len))
1329+
}
1330+
1331+
fn evict_dead(&mut self) {
1332+
if self.entries.len() < 16.max(2 * self.swept_len) {
1333+
return;
1334+
}
1335+
self.entries.retain(|_, (any, _)| !any.ptr.is_dangling());
1336+
let entries = &self.entries;
1337+
self.ranges
1338+
.bases
1339+
.retain(|_, &mut (base, _)| entries.contains_key(&base));
1340+
self.swept_len = self.entries.len();
1341+
}
1342+
}
1343+
13021344
thread_local! {
1303-
static PTR_RANGE_ALLOC: RefCell<RangeAllocator> = RefCell::new(RangeAllocator::new());
1304-
static PTR_REGISTRY: RefCell<BTreeMap<SyntheticAddr, (AnyPtr, ByteLen)>> =
1305-
const { RefCell::new(BTreeMap::new()) };
1345+
static PTR_REGISTRY: RefCell<PtrRegistry> = RefCell::new(PtrRegistry::new());
13061346
}
13071347

13081348
impl<T: ByteRepr> ByteRepr for Ptr<T> {
@@ -1322,13 +1362,13 @@ impl<T: ByteRepr> ByteRepr for Ptr<T> {
13221362
self.len() * T::byte_size(),
13231363
),
13241364
};
1325-
let base = PTR_RANGE_ALLOC.with(|a| a.borrow_mut().base_for(self.kind.address(), byte_len));
13261365
let rebased = Ptr {
13271366
offset: 0,
13281367
kind: self.kind.clone(),
13291368
};
1330-
PTR_REGISTRY.with(|r| {
1331-
r.borrow_mut().insert(base, (rebased.to_any(), byte_len));
1369+
let base = PTR_REGISTRY.with(|r| {
1370+
r.borrow_mut()
1371+
.put(self.kind.address(), byte_len, rebased.to_any())
13321372
});
13331373
base.wrapping_add(byte_off).to_bytes(buf);
13341374
}
@@ -1338,12 +1378,7 @@ impl<T: ByteRepr> ByteRepr for Ptr<T> {
13381378
if addr == 0 {
13391379
return Ptr::null();
13401380
}
1341-
let entry = PTR_REGISTRY.with(|r| {
1342-
r.borrow()
1343-
.range(..=addr)
1344-
.next_back()
1345-
.map(|(base, (any, len))| (*base, any.clone(), *len))
1346-
});
1381+
let entry = PTR_REGISTRY.with(|r| r.borrow().get(addr));
13471382
let Some((base, any, byte_len)) = entry else {
13481383
panic!("ub: cast of invalid address 0x{addr:x} to pointer");
13491384
};

0 commit comments

Comments
 (0)