From cef9aa359079f74dd8ae44accf3e6a162a76b162 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 18 Dec 2023 18:58:40 +0100 Subject: [PATCH 1/3] Use a different frame arena for each window Co-Authored-By: Max Brunsfeld Co-Authored-By: Nathan Sobo --- crates/gpui2/src/window.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 337f61272f12e3..e00c707de34f5a 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -99,12 +99,12 @@ struct FocusEvent { slotmap::new_key_type! { pub struct FocusId; } thread_local! { - pub static FRAME_ARENA: RefCell = RefCell::new(Arena::new(16 * 1024 * 1024)); + pub static FRAME_ARENA: RefCell> = RefCell::new(None); } #[inline(always)] pub(crate) fn frame_alloc(f: impl FnOnce() -> T) -> ArenaRef { - FRAME_ARENA.with_borrow_mut(|arena| arena.alloc(f)) + FRAME_ARENA.with_borrow_mut(|arena| arena.as_mut().unwrap().alloc(f)) } impl FocusId { @@ -254,6 +254,7 @@ pub struct Window { pub(crate) element_id_stack: GlobalElementId, pub(crate) rendered_frame: Frame, pub(crate) next_frame: Frame, + frame_arena: Option, pub(crate) focus_handles: Arc>>, focus_listeners: SubscriberSet<(), AnyWindowFocusListener>, blur_listeners: SubscriberSet<(), AnyObserver>, @@ -397,6 +398,7 @@ impl Window { element_id_stack: GlobalElementId::default(), rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), + frame_arena: Some(Arena::new(16 * 1024 * 1024)), focus_handles: Arc::new(RwLock::new(SlotMap::with_key())), focus_listeners: SubscriberSet::new(), blur_listeners: SubscriberSet::new(), @@ -1278,7 +1280,9 @@ impl<'a> WindowContext<'a> { self.window.platform_window.clear_input_handler(); self.window.layout_engine.as_mut().unwrap().clear(); self.window.next_frame.clear(); - FRAME_ARENA.with_borrow_mut(|arena| arena.clear()); + let mut frame_arena = self.window.frame_arena.take().unwrap(); + frame_arena.clear(); + FRAME_ARENA.replace(Some(frame_arena)); let root_view = self.window.root_view.take().unwrap(); self.with_z_index(0, |cx| { @@ -1364,6 +1368,7 @@ impl<'a> WindowContext<'a> { } self.window.drawing = false; + self.window.frame_arena = Some(FRAME_ARENA.take().unwrap()); scene } From 37efe82c5e5f98978b386df85b3be61ccc83b078 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 18 Dec 2023 19:35:17 +0100 Subject: [PATCH 2/3] Use a different frame arena for all elements Co-Authored-By: Nathan Sobo Co-Authored-By: Max Brunsfeld --- crates/gpui2/src/arena.rs | 4 +++ crates/gpui2/src/element.rs | 7 ++-- crates/gpui2/src/window.rs | 70 ++++++++++++++++++++----------------- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index c99f09d29f46e3..24434153fb344b 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -78,6 +78,10 @@ impl Arena { } } } + + pub fn size(&self) -> usize { + self.offset + } } impl Drop for Arena { diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 6f739d8e33ac93..d0ed50a3d54780 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -1,6 +1,6 @@ use crate::{ - frame_alloc, ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, - Point, Size, ViewContext, WindowContext, + ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, Size, + ViewContext, WindowContext, ELEMENT_ARENA, }; use derive_more::{Deref, DerefMut}; pub(crate) use smallvec::SmallVec; @@ -413,7 +413,8 @@ impl AnyElement { E: 'static + Element, E::State: Any, { - let element = frame_alloc(|| Some(DrawableElement::new(element))) + let element = ELEMENT_ARENA + .with_borrow_mut(|arena| arena.alloc(|| Some(DrawableElement::new(element)))) .map(|element| element as &mut dyn ElementObject); AnyElement(element) } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index e00c707de34f5a..0cef1644605a97 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -99,12 +99,7 @@ struct FocusEvent { slotmap::new_key_type! { pub struct FocusId; } thread_local! { - pub static FRAME_ARENA: RefCell> = RefCell::new(None); -} - -#[inline(always)] -pub(crate) fn frame_alloc(f: impl FnOnce() -> T) -> ArenaRef { - FRAME_ARENA.with_borrow_mut(|arena| arena.as_mut().unwrap().alloc(f)) + pub(crate) static ELEMENT_ARENA: RefCell = RefCell::new(Arena::new(4 * 1024 * 1024)); } impl FocusId { @@ -254,7 +249,7 @@ pub struct Window { pub(crate) element_id_stack: GlobalElementId, pub(crate) rendered_frame: Frame, pub(crate) next_frame: Frame, - frame_arena: Option, + frame_arena: Arena, pub(crate) focus_handles: Arc>>, focus_listeners: SubscriberSet<(), AnyWindowFocusListener>, blur_listeners: SubscriberSet<(), AnyObserver>, @@ -398,7 +393,7 @@ impl Window { element_id_stack: GlobalElementId::default(), rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), - frame_arena: Some(Arena::new(16 * 1024 * 1024)), + frame_arena: Arena::new(1 * 1024 * 1024), focus_handles: Arc::new(RwLock::new(SlotMap::with_key())), focus_listeners: SubscriberSet::new(), blur_listeners: SubscriberSet::new(), @@ -836,12 +831,15 @@ impl<'a> WindowContext<'a> { mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { let order = self.window.next_frame.z_index_stack.clone(); - let handler = frame_alloc(|| { - move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { - handler(event.downcast_ref().unwrap(), phase, cx) - } - }) - .map(|handler| handler as _); + let handler = self + .window + .frame_arena + .alloc(|| { + move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { + handler(event.downcast_ref().unwrap(), phase, cx) + } + }) + .map(|handler| handler as _); self.window .next_frame .mouse_listeners @@ -860,14 +858,17 @@ impl<'a> WindowContext<'a> { &mut self, listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = frame_alloc(|| { - move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { - if let Some(event) = event.downcast_ref::() { - listener(event, phase, cx) + let listener = self + .window + .frame_arena + .alloc(|| { + move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { + if let Some(event) = event.downcast_ref::() { + listener(event, phase, cx) + } } - } - }) - .map(|handler| handler as _); + }) + .map(|handler| handler as _); self.window.next_frame.dispatch_tree.on_key_event(listener); } @@ -882,7 +883,11 @@ impl<'a> WindowContext<'a> { action_type: TypeId, listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = frame_alloc(|| listener).map(|handler| handler as _); + let listener = self + .window + .frame_arena + .alloc(|| listener) + .map(|handler| handler as _); self.window .next_frame .dispatch_tree @@ -1280,21 +1285,22 @@ impl<'a> WindowContext<'a> { self.window.platform_window.clear_input_handler(); self.window.layout_engine.as_mut().unwrap().clear(); self.window.next_frame.clear(); - let mut frame_arena = self.window.frame_arena.take().unwrap(); - frame_arena.clear(); - FRAME_ARENA.replace(Some(frame_arena)); + self.window.frame_arena.clear(); let root_view = self.window.root_view.take().unwrap(); self.with_z_index(0, |cx| { cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| { for (action_type, action_listeners) in &cx.app.global_action_listeners { for action_listener in action_listeners.iter().cloned() { - let listener = frame_alloc(|| { - move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { - action_listener(action, phase, cx) - } - }) - .map(|listener| listener as _); + let listener = cx + .window + .frame_arena + .alloc(|| { + move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { + action_listener(action, phase, cx) + } + }) + .map(|listener| listener as _); cx.window .next_frame .dispatch_tree @@ -1368,7 +1374,7 @@ impl<'a> WindowContext<'a> { } self.window.drawing = false; - self.window.frame_arena = Some(FRAME_ARENA.take().unwrap()); + ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear()); scene } From 0000e6831094c38bf3455acc0617922ced877516 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 18 Dec 2023 10:41:02 -0800 Subject: [PATCH 3/3] Remove unused Arena::sized method --- crates/gpui2/src/arena.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index 24434153fb344b..c99f09d29f46e3 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -78,10 +78,6 @@ impl Arena { } } } - - pub fn size(&self) -> usize { - self.offset - } } impl Drop for Arena {