@@ -14,7 +14,6 @@ use parking_lot::Mutex;
1414use std:: cell:: RefCell ;
1515
1616use zerogc_context:: utils:: AtomicCell ;
17- use zerogc:: format:: { ObjectFormat , OpenAllocObjectFormat } ;
1817
1918/// The minimum size of supported memory (in words)
2019///
@@ -30,22 +29,25 @@ pub const ARENA_ELEMENT_ALIGN: usize = ARENA_HEADER_LAYOUT.align();
3029/// The size of headers in the arena
3130///
3231/// This is the same regardless of the underlying object format
33- const ARENA_HEADER_LAYOUT : Layout = Layout :: new :: < DummyGcHeader > ( ) ;
32+ const ARENA_HEADER_LAYOUT : Layout = Layout :: new :: < GcHeader > ( ) ;
3433
35- use super :: DummyGcHeader ;
36- use crate :: { RawSimpleCollector , RawObjectFormat } ;
34+ use crate :: layout:: { GcHeader } ;
3735
3836#[ inline]
39- pub const fn small_object_size < T > ( ) -> usize {
37+ pub const fn small_object_size ( layout : Layout ) -> usize {
4038 let header_layout = ARENA_HEADER_LAYOUT ;
4139 header_layout. size ( ) + header_layout
42- . padding_needed_for ( std:: mem:: align_of :: < T > ( ) )
43- + mem:: size_of :: < T > ( )
40+ . padding_needed_for ( layout. align ( ) )
41+ + layout. size ( )
42+ }
43+ #[ inline]
44+ pub const fn fits_small_object ( layout : Layout ) -> bool {
45+ small_object_size ( layout) <= MAXIMUM_SMALL_WORDS * std:: mem:: size_of :: < usize > ( )
46+ && layout. align ( ) <= ARENA_ELEMENT_ALIGN
4447}
4548#[ inline]
4649pub const fn is_small_object < T > ( ) -> bool {
47- small_object_size :: < T > ( ) <= MAXIMUM_SMALL_WORDS * 8
48- && mem:: align_of :: < T > ( ) <= ARENA_ELEMENT_ALIGN
50+ fits_small_object ( Layout :: new :: < T > ( ) )
4951}
5052
5153pub ( crate ) struct Chunk {
@@ -121,7 +123,7 @@ pub struct FreeSlot {
121123#[ repr( C ) ]
122124pub ( crate ) union MaybeFreeSlot {
123125 pub free : FreeSlot ,
124- pub header : DummyGcHeader ,
126+ pub header : GcHeader ,
125127}
126128
127129impl MaybeFreeSlot {
@@ -199,7 +201,7 @@ impl ArenaState {
199201 self . current_chunk . store ( ptr) ;
200202 }
201203 #[ inline]
202- fn alloc ( & self , element_size : usize ) -> NonNull < DummyGcHeader > {
204+ fn alloc ( & self , element_size : usize ) -> NonNull < GcHeader > {
203205 unsafe {
204206 let chunk = & * self . current_chunk ( ) . as_ptr ( ) ;
205207 match chunk. try_alloc ( element_size) {
@@ -211,7 +213,7 @@ impl ArenaState {
211213
212214 #[ cold]
213215 #[ inline( never) ]
214- fn alloc_fallback ( & self , element_size : usize ) -> NonNull < DummyGcHeader > {
216+ fn alloc_fallback ( & self , element_size : usize ) -> NonNull < GcHeader > {
215217 let mut chunks = self . lock_chunks ( ) ;
216218 // Now that we hold the lock, check the current chunk again
217219 unsafe {
@@ -227,7 +229,7 @@ impl ArenaState {
227229 self . force_current_chunk ( NonNull :: from ( & * * chunks. last ( ) . unwrap ( ) ) ) ;
228230 self . current_chunk ( ) . as_ref ( )
229231 . try_alloc ( element_size) . unwrap ( )
230- . cast :: < DummyGcHeader > ( )
232+ . cast :: < GcHeader > ( )
231233 }
232234 }
233235}
@@ -249,7 +251,7 @@ impl FreeList {
249251 self . next . store ( next)
250252 }
251253 #[ inline]
252- fn take_free ( & self ) -> Option < NonNull < DummyGcHeader > > {
254+ fn take_free ( & self ) -> Option < NonNull < GcHeader > > {
253255 loop {
254256 let next_free = match self . next . load ( ) {
255257 Some ( free) => free,
@@ -271,27 +273,25 @@ impl FreeList {
271273 }
272274}
273275
274- pub struct SmallArena < Fmt : RawObjectFormat > {
276+ pub struct SmallArena {
275277 pub ( crate ) element_size : usize ,
276278 state : ArenaState ,
277- pub ( crate ) free : FreeList ,
278- format : & ' static Fmt
279+ pub ( crate ) free : FreeList
279280}
280- impl < Fmt : RawObjectFormat > SmallArena < Fmt > {
281+ impl SmallArena {
281282 #[ cold] // Initialization is the slow path
282- fn with_words ( format : & ' static Fmt , num_words : usize ) -> SmallArena < Fmt > {
283+ fn with_words ( num_words : usize ) -> SmallArena {
283284 assert ! ( num_words >= MINIMUM_WORDS ) ;
284285 let element_size = num_words * mem:: size_of :: < usize > ( ) ;
285286 assert ! ( INITIAL_SIZE >= element_size * 2 ) ;
286287 let chunks = vec ! [ Chunk :: alloc( INITIAL_SIZE ) ] ;
287288 SmallArena {
288289 state : ArenaState :: new ( chunks) ,
289290 element_size, free : Default :: default ( ) ,
290- format
291291 }
292292 }
293293 #[ inline]
294- pub ( crate ) fn alloc ( & self ) -> NonNull < DummyGcHeader > {
294+ pub ( crate ) fn alloc ( & self ) -> NonNull < GcHeader > {
295295 // Check the free list
296296 if let Some ( free) = self . free . take_free ( ) {
297297 free
@@ -312,11 +312,11 @@ impl<Fmt: RawObjectFormat> SmallArena<Fmt> {
312312 }
313313}
314314macro_rules! arena_match {
315- ( $format : expr , $ arenas: expr, $target: ident, max = $max: expr; $( $size: pat => $num_words: literal @ $idx: expr) ,* ) => {
315+ ( $arenas: expr, $target: ident, max = $max: expr; $( $size: pat => $num_words: literal @ $idx: expr) ,* ) => {
316316 Some ( match $target {
317317 $( $size => $arenas[ $idx] . get_or_init( || {
318318 assert_eq!( SMALL_ARENA_SIZES [ $idx] , $num_words) ;
319- SmallArena :: with_words( $format , $ num_words)
319+ SmallArena :: with_words( $num_words)
320320 } ) , ) *
321321 _ => {
322322 assert!( $target > $max) ;
@@ -330,16 +330,16 @@ const SMALL_ARENA_SIZES: [usize; NUM_SMALL_ARENAS] = [
330330 10 , 12 , 14 , 16 ,
331331 20 , 24 , 28 , 32
332332] ;
333- pub struct SmallArenaList < Fmt : RawObjectFormat > {
333+ pub struct SmallArenaList {
334334 // NOTE: Internally boxed to avoid bloating main struct
335- arenas : Box < [ OnceCell < SmallArena < Fmt > > ; NUM_SMALL_ARENAS ] >
335+ arenas : Box < [ OnceCell < SmallArena > ; NUM_SMALL_ARENAS ] >
336336}
337- impl < Fmt : RawObjectFormat > SmallArenaList < Fmt > {
337+ impl SmallArenaList {
338338 pub fn new ( ) -> Self {
339339 // NOTE: Why does writing arrays have to be so difficult:?
340340 unsafe {
341341 let mut arenas: Box < [
342- MaybeUninit < OnceCell < SmallArena < Fmt > > > ;
342+ MaybeUninit < OnceCell < SmallArena > > ;
343343 NUM_SMALL_ARENAS
344344 ] > = Box :: new_uninit ( ) . assume_init ( ) ;
345345 for i in 0 ..NUM_SMALL_ARENAS {
@@ -348,29 +348,32 @@ impl<Fmt: RawObjectFormat> SmallArenaList<Fmt> {
348348 SmallArenaList {
349349 // NOTE: This is done because I want to explicitly specify types
350350 arenas : mem:: transmute :: <
351- Box < [ MaybeUninit < OnceCell < SmallArena < Fmt > > > ; NUM_SMALL_ARENAS ] > ,
352- Box < [ OnceCell < SmallArena < Fmt > > ; NUM_SMALL_ARENAS ] >
351+ Box < [ MaybeUninit < OnceCell < SmallArena > > ; NUM_SMALL_ARENAS ] > ,
352+ Box < [ OnceCell < SmallArena > ; NUM_SMALL_ARENAS ] >
353353 > ( arenas)
354354 }
355355 }
356356 }
357- pub fn iter ( & self ) -> impl Iterator < Item =& SmallArena < Fmt > > + ' _ {
357+ pub fn iter ( & self ) -> impl Iterator < Item =& SmallArena > + ' _ {
358358 self . arenas . iter ( ) . filter_map ( OnceCell :: get)
359359 }
360360 #[ inline] // This should be constant folded away (size/align is const)
361- pub fn find < T > ( & self ) -> Option < & SmallArena < Fmt > > {
361+ pub fn find < T > ( & self ) -> Option < & SmallArena > {
362362 if std:: mem:: align_of :: < T > ( ) > ARENA_ELEMENT_ALIGN {
363363 return None
364364 }
365+ if !is_small_object :: < T > ( ) {
366+ return None
367+ }
365368 // Divide round up
366369 let word_size = mem:: size_of :: < usize > ( ) ;
367- let num_words = ( small_object_size :: < T > ( ) + ( word_size - 1 ) )
370+ let num_words = ( small_object_size ( Layout :: new :: < T > ( ) ) + ( word_size - 1 ) )
368371 / word_size;
369372 self . find_raw ( num_words)
370373 }
371374 #[ inline] // We want this constant-folded away......
372- fn find_raw ( & self , num_words : usize ) -> Option < & SmallArena < Fmt > > {
373- arena_match ! ( self . format ,
375+ fn find_raw ( & self , num_words : usize ) -> Option < & SmallArena > {
376+ arena_match ! (
374377 self . arenas, num_words, max = 32 ;
375378 0 ..=2 => 2 @ 0 ,
376379 3 => 3 @ 1 ,
0 commit comments