mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Mint arena handles only over bytes the bump reserved
This commit is contained in:
@@ -344,9 +344,13 @@ impl Arena {
|
||||
/// The generation-checked handle for a region this arena holds, `None` for
|
||||
/// a pointer from anywhere else. The handle keeps the region's provenance,
|
||||
/// so a cache stores one where it would otherwise launder an address.
|
||||
///
|
||||
/// The offset must sit below the bump watermark, not merely inside the
|
||||
/// backbone: [`ArenaWeak::upgrade`] hands out a `&T` at it, so only bytes a
|
||||
/// reservation already handed out may be minted into a handle.
|
||||
pub fn handle_at(&self, ptr: *const u8) -> Option<ArenaWeak<u8>> {
|
||||
let offset = (ptr as usize).checked_sub(self.base() as usize)?;
|
||||
(offset < self.buf.len()).then_some(())?;
|
||||
(offset < self.offset.load(Ordering::Acquire)).then_some(())?;
|
||||
ArenaWeak::new(self.generation(), offset)
|
||||
}
|
||||
|
||||
@@ -550,6 +554,19 @@ mod tests {
|
||||
assert!(cell.load(&arena).is_none(), "a half-dropped generation must resolve no handle");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handles_mint_only_over_reserved_bytes() {
|
||||
let _guard = COUNTER_GUARD.lock().unwrap_or_else(PoisonError::into_inner);
|
||||
let arena = Arena::new(1024).unwrap();
|
||||
let (value, _) = arena.alloc(41u32).unwrap();
|
||||
let ptr = std::ptr::from_ref(value).cast::<u8>();
|
||||
assert!(arena.handle_at(ptr).is_some(), "a byte the bump handed out mints a handle");
|
||||
|
||||
let unreserved = ptr.wrapping_add(64);
|
||||
assert!(arena.contains(unreserved), "the fixture stays inside the backbone");
|
||||
assert!(arena.handle_at(unreserved).is_none(), "a byte past the watermark mints nothing");
|
||||
}
|
||||
|
||||
/// Held by every test that perturbs [`NEXT_GENERATION`], so a swapped-out counter
|
||||
/// is never observed by a concurrently constructing test.
|
||||
static COUNTER_GUARD: Mutex<()> = Mutex::new(());
|
||||
|
||||
Reference in New Issue
Block a user