From 12d74f702baf58bbb7d80cffb268d2c02e7f8999 Mon Sep 17 00:00:00 2001 From: Adrian Wielgosik Date: Tue, 9 Mar 2021 23:43:38 +0100 Subject: [PATCH 1/2] Mark cheap functions as inline. --- src/gc-arena/src/context.rs | 1 + src/gc-arena/src/types.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/gc-arena/src/context.rs b/src/gc-arena/src/context.rs index 3a3d9505..f55380a6 100644 --- a/src/gc-arena/src/context.rs +++ b/src/gc-arena/src/context.rs @@ -317,6 +317,7 @@ enum Phase { Sleep, } +#[inline] unsafe fn static_gc_box<'gc>( ptr: NonNull>, ) -> NonNull> { diff --git a/src/gc-arena/src/types.rs b/src/gc-arena/src/types.rs index 1ccf2906..c8157ff1 100644 --- a/src/gc-arena/src/types.rs +++ b/src/gc-arena/src/types.rs @@ -20,10 +20,12 @@ pub(crate) struct GcBox { pub(crate) struct GcFlags(Cell); impl GcFlags { + #[inline] pub(crate) fn new() -> GcFlags { GcFlags(Cell::new(0)) } + #[inline] pub(crate) fn color(&self) -> GcColor { match self.0.get() & 0x3 { 0x0 => GcColor::White, @@ -33,6 +35,7 @@ impl GcFlags { } } + #[inline] pub(crate) fn set_color(&self, color: GcColor) { self.0.set( (self.0.get() & !0x3) @@ -44,10 +47,12 @@ impl GcFlags { ) } + #[inline] pub(crate) fn needs_trace(&self) -> bool { self.0.get() & 0x4 != 0x0 } + #[inline] pub(crate) fn set_needs_trace(&self, needs_trace: bool) { self.0 .set((self.0.get() & !0x4) | if needs_trace { 0x4 } else { 0x0 }); From e2f9bb086ba8531ead64f0b77bdd0abcb2cd91bc Mon Sep 17 00:00:00 2001 From: Adrian Wielgosik Date: Tue, 9 Mar 2021 23:50:58 +0100 Subject: [PATCH 2/2] Manually initialize GcBox contents post-allocation --- src/gc-arena/src/context.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/gc-arena/src/context.rs b/src/gc-arena/src/context.rs index f55380a6..8c8e5af7 100644 --- a/src/gc-arena/src/context.rs +++ b/src/gc-arena/src/context.rs @@ -264,13 +264,17 @@ impl Context { ); } - let gc_box = GcBox { - flags: GcFlags::new(), - next: Cell::new(self.all.get()), - value: UnsafeCell::new(t), - }; - gc_box.flags.set_needs_trace(T::needs_trace()); - let ptr = NonNull::new_unchecked(Box::into_raw(Box::new(gc_box))); + let flags = GcFlags::new(); + flags.set_needs_trace(T::needs_trace()); + + let mut uninitialized = Box::new(mem::MaybeUninit::>::uninit()); + + std::ptr::write(&mut (*uninitialized.as_mut_ptr()).flags, flags); + std::ptr::write(&mut (*uninitialized.as_mut_ptr()).next, Cell::new(self.all.get())); + std::ptr::write(&mut (*uninitialized.as_mut_ptr()).value, UnsafeCell::new(t)); + + let ptr = NonNull::new_unchecked(Box::into_raw(uninitialized) as *mut GcBox); + self.all.set(Some(static_gc_box(ptr))); if self.phase.get() == Phase::Sweep && self.sweep_prev.get().is_none() { self.sweep_prev.set(self.all.get());