gpui: Dynamic element arena (#32079)

Implements a chunking strategy for the element arena that allows it to
grow dynamically based on allocations, it is initialised with a single
chunk of a total size of 1 mebibyte. On allocation of data with a size
greater than the remaining space of the current chunk a new chunk is
created.

This reduces the memory allocation from the static 32 mebibytes, this
especially helps GPUI applications that don't need such a large element
arena and even Zed in most cases. This also prevents the panic when
allocations ever exceed the element arena.

Release Notes:

- N/A

---------

Co-authored-by: Michael Sloan <michael@zed.dev>
This commit is contained in:
Matin Aniss 2025-06-26 05:29:13 +10:00 committed by GitHub
parent 294147f473
commit e5c812fbcb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 109 additions and 43 deletions

View file

@ -206,8 +206,7 @@ slotmap::new_key_type! {
}
thread_local! {
/// 8MB wasn't quite enough...
pub(crate) static ELEMENT_ARENA: RefCell<Arena> = RefCell::new(Arena::new(32 * 1024 * 1024));
pub(crate) static ELEMENT_ARENA: RefCell<Arena> = RefCell::new(Arena::new(1024 * 1024));
}
/// Returned when the element arena has been used and so must be cleared before the next draw.
@ -218,12 +217,8 @@ impl ArenaClearNeeded {
/// Clear the element arena.
pub fn clear(self) {
ELEMENT_ARENA.with_borrow_mut(|element_arena| {
let percentage = (element_arena.len() as f32 / element_arena.capacity() as f32) * 100.;
if percentage >= 80. {
log::warn!("elevated element arena occupation: {}.", percentage);
}
element_arena.clear();
})
});
}
}