@@ -14,7 +14,6 @@ use parking_lot::Mutex;
14
14
use std:: cell:: RefCell ;
15
15
16
16
use zerogc_context:: utils:: AtomicCell ;
17
- use zerogc:: format:: { ObjectFormat , OpenAllocObjectFormat } ;
18
17
19
18
/// The minimum size of supported memory (in words)
20
19
///
@@ -30,22 +29,25 @@ pub const ARENA_ELEMENT_ALIGN: usize = ARENA_HEADER_LAYOUT.align();
30
29
/// The size of headers in the arena
31
30
///
32
31
/// 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 > ( ) ;
34
33
35
- use super :: DummyGcHeader ;
36
- use crate :: { RawSimpleCollector , RawObjectFormat } ;
34
+ use crate :: layout:: { GcHeader } ;
37
35
38
36
#[ inline]
39
- pub const fn small_object_size < T > ( ) -> usize {
37
+ pub const fn small_object_size ( layout : Layout ) -> usize {
40
38
let header_layout = ARENA_HEADER_LAYOUT ;
41
39
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
44
47
}
45
48
#[ inline]
46
49
pub 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 > ( ) )
49
51
}
50
52
51
53
pub ( crate ) struct Chunk {
@@ -121,7 +123,7 @@ pub struct FreeSlot {
121
123
#[ repr( C ) ]
122
124
pub ( crate ) union MaybeFreeSlot {
123
125
pub free : FreeSlot ,
124
- pub header : DummyGcHeader ,
126
+ pub header : GcHeader ,
125
127
}
126
128
127
129
impl MaybeFreeSlot {
@@ -199,7 +201,7 @@ impl ArenaState {
199
201
self . current_chunk . store ( ptr) ;
200
202
}
201
203
#[ inline]
202
- fn alloc ( & self , element_size : usize ) -> NonNull < DummyGcHeader > {
204
+ fn alloc ( & self , element_size : usize ) -> NonNull < GcHeader > {
203
205
unsafe {
204
206
let chunk = & * self . current_chunk ( ) . as_ptr ( ) ;
205
207
match chunk. try_alloc ( element_size) {
@@ -211,7 +213,7 @@ impl ArenaState {
211
213
212
214
#[ cold]
213
215
#[ inline( never) ]
214
- fn alloc_fallback ( & self , element_size : usize ) -> NonNull < DummyGcHeader > {
216
+ fn alloc_fallback ( & self , element_size : usize ) -> NonNull < GcHeader > {
215
217
let mut chunks = self . lock_chunks ( ) ;
216
218
// Now that we hold the lock, check the current chunk again
217
219
unsafe {
@@ -227,7 +229,7 @@ impl ArenaState {
227
229
self . force_current_chunk ( NonNull :: from ( & * * chunks. last ( ) . unwrap ( ) ) ) ;
228
230
self . current_chunk ( ) . as_ref ( )
229
231
. try_alloc ( element_size) . unwrap ( )
230
- . cast :: < DummyGcHeader > ( )
232
+ . cast :: < GcHeader > ( )
231
233
}
232
234
}
233
235
}
@@ -249,7 +251,7 @@ impl FreeList {
249
251
self . next . store ( next)
250
252
}
251
253
#[ inline]
252
- fn take_free ( & self ) -> Option < NonNull < DummyGcHeader > > {
254
+ fn take_free ( & self ) -> Option < NonNull < GcHeader > > {
253
255
loop {
254
256
let next_free = match self . next . load ( ) {
255
257
Some ( free) => free,
@@ -271,27 +273,25 @@ impl FreeList {
271
273
}
272
274
}
273
275
274
- pub struct SmallArena < Fmt : RawObjectFormat > {
276
+ pub struct SmallArena {
275
277
pub ( crate ) element_size : usize ,
276
278
state : ArenaState ,
277
- pub ( crate ) free : FreeList ,
278
- format : & ' static Fmt
279
+ pub ( crate ) free : FreeList
279
280
}
280
- impl < Fmt : RawObjectFormat > SmallArena < Fmt > {
281
+ impl SmallArena {
281
282
#[ 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 {
283
284
assert ! ( num_words >= MINIMUM_WORDS ) ;
284
285
let element_size = num_words * mem:: size_of :: < usize > ( ) ;
285
286
assert ! ( INITIAL_SIZE >= element_size * 2 ) ;
286
287
let chunks = vec ! [ Chunk :: alloc( INITIAL_SIZE ) ] ;
287
288
SmallArena {
288
289
state : ArenaState :: new ( chunks) ,
289
290
element_size, free : Default :: default ( ) ,
290
- format
291
291
}
292
292
}
293
293
#[ inline]
294
- pub ( crate ) fn alloc ( & self ) -> NonNull < DummyGcHeader > {
294
+ pub ( crate ) fn alloc ( & self ) -> NonNull < GcHeader > {
295
295
// Check the free list
296
296
if let Some ( free) = self . free . take_free ( ) {
297
297
free
@@ -312,11 +312,11 @@ impl<Fmt: RawObjectFormat> SmallArena<Fmt> {
312
312
}
313
313
}
314
314
macro_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) ,* ) => {
316
316
Some ( match $target {
317
317
$( $size => $arenas[ $idx] . get_or_init( || {
318
318
assert_eq!( SMALL_ARENA_SIZES [ $idx] , $num_words) ;
319
- SmallArena :: with_words( $format , $ num_words)
319
+ SmallArena :: with_words( $num_words)
320
320
} ) , ) *
321
321
_ => {
322
322
assert!( $target > $max) ;
@@ -330,16 +330,16 @@ const SMALL_ARENA_SIZES: [usize; NUM_SMALL_ARENAS] = [
330
330
10 , 12 , 14 , 16 ,
331
331
20 , 24 , 28 , 32
332
332
] ;
333
- pub struct SmallArenaList < Fmt : RawObjectFormat > {
333
+ pub struct SmallArenaList {
334
334
// 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 ] >
336
336
}
337
- impl < Fmt : RawObjectFormat > SmallArenaList < Fmt > {
337
+ impl SmallArenaList {
338
338
pub fn new ( ) -> Self {
339
339
// NOTE: Why does writing arrays have to be so difficult:?
340
340
unsafe {
341
341
let mut arenas: Box < [
342
- MaybeUninit < OnceCell < SmallArena < Fmt > > > ;
342
+ MaybeUninit < OnceCell < SmallArena > > ;
343
343
NUM_SMALL_ARENAS
344
344
] > = Box :: new_uninit ( ) . assume_init ( ) ;
345
345
for i in 0 ..NUM_SMALL_ARENAS {
@@ -348,29 +348,32 @@ impl<Fmt: RawObjectFormat> SmallArenaList<Fmt> {
348
348
SmallArenaList {
349
349
// NOTE: This is done because I want to explicitly specify types
350
350
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 ] >
353
353
> ( arenas)
354
354
}
355
355
}
356
356
}
357
- pub fn iter ( & self ) -> impl Iterator < Item =& SmallArena < Fmt > > + ' _ {
357
+ pub fn iter ( & self ) -> impl Iterator < Item =& SmallArena > + ' _ {
358
358
self . arenas . iter ( ) . filter_map ( OnceCell :: get)
359
359
}
360
360
#[ 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 > {
362
362
if std:: mem:: align_of :: < T > ( ) > ARENA_ELEMENT_ALIGN {
363
363
return None
364
364
}
365
+ if !is_small_object :: < T > ( ) {
366
+ return None
367
+ }
365
368
// Divide round up
366
369
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 ) )
368
371
/ word_size;
369
372
self . find_raw ( num_words)
370
373
}
371
374
#[ 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 ! (
374
377
self . arenas, num_words, max = 32 ;
375
378
0 ..=2 => 2 @ 0 ,
376
379
3 => 3 @ 1 ,
0 commit comments