@@ -207,7 +207,17 @@ impl Table {
207
207
/// If `page` is out of bounds or the type `T` is incorrect.
208
208
#[ inline]
209
209
pub ( crate ) fn page < T : Slot > ( & self , page : PageIndex ) -> PageView < ' _ , T > {
210
- self . pages [ page. 0 ] . assert_type :: < T > ( )
210
+ #[ cold]
211
+ #[ inline( never) ]
212
+ fn assert_failed ( index : usize ) -> ! {
213
+ panic ! ( "index {index} is uninitialized" ) ;
214
+ }
215
+
216
+ if let Some ( page) = self . pages . get ( page. 0 ) {
217
+ return page. assert_type ( ) ;
218
+ }
219
+
220
+ assert_failed ( page. 0 )
211
221
}
212
222
213
223
/// Allocate a new page for the given ingredient and with slots of type `T`
@@ -286,6 +296,8 @@ impl Table {
286
296
. flat_map ( |view| view. data ( ) )
287
297
}
288
298
299
+ #[ cold]
300
+ #[ inline( never) ]
289
301
pub ( crate ) fn fetch_or_push_page < T : Slot > (
290
302
& self ,
291
303
ingredient : IngredientIndex ,
@@ -299,6 +311,7 @@ impl Table {
299
311
{
300
312
return page;
301
313
}
314
+
302
315
self . push_page :: < T > ( ingredient, memo_types ( ) )
303
316
}
304
317
@@ -311,22 +324,23 @@ impl Table {
311
324
}
312
325
}
313
326
314
- impl < ' p , T : Slot > PageView < ' p , T > {
327
+ impl < ' db , T : Slot > PageView < ' db , T > {
315
328
#[ inline]
316
- fn page_data ( & self ) -> & ' p [ PageDataEntry < T > ] {
329
+ fn page_data ( & self ) -> & ' db [ PageDataEntry < T > ] {
317
330
let len = self . 0 . allocated . load ( Ordering :: Acquire ) ;
318
331
// SAFETY: `len` is the initialized length of the page
319
332
unsafe { slice:: from_raw_parts ( self . 0 . data . cast :: < PageDataEntry < T > > ( ) . as_ptr ( ) , len) }
320
333
}
321
334
322
335
#[ inline]
323
- fn data ( & self ) -> & ' p [ T ] {
336
+ fn data ( & self ) -> & ' db [ T ] {
324
337
let len = self . 0 . allocated . load ( Ordering :: Acquire ) ;
325
338
// SAFETY: `len` is the initialized length of the page
326
339
unsafe { slice:: from_raw_parts ( self . 0 . data . cast :: < T > ( ) . as_ptr ( ) , len) }
327
340
}
328
341
329
- pub ( crate ) fn allocate < V > ( & self , page : PageIndex , value : V ) -> Result < Id , V >
342
+ #[ inline]
343
+ pub ( crate ) fn allocate < V > ( & self , page : PageIndex , value : V ) -> Result < ( Id , & ' db T ) , V >
330
344
where
331
345
V : FnOnce ( Id ) -> T ,
332
346
{
@@ -347,11 +361,14 @@ impl<'p, T: Slot> PageView<'p, T> {
347
361
// interior
348
362
unsafe { ( * entry. get ( ) ) . write ( value ( id) ) } ;
349
363
364
+ // SAFETY: We just initialized the value above.
365
+ let value = unsafe { ( * entry. get ( ) ) . assume_init_ref ( ) } ;
366
+
350
367
// Update the length (this must be done after initialization as otherwise an uninitialized
351
368
// read could occur!)
352
369
self . 0 . allocated . store ( index + 1 , Ordering :: Release ) ;
353
370
354
- Ok ( id )
371
+ Ok ( ( id , value ) )
355
372
}
356
373
}
357
374
0 commit comments