1
1
#![ unstable( feature = "raw_vec_internals" , reason = "implementation detail" , issue = "none" ) ]
2
2
#![ doc( hidden) ]
3
3
4
- use core:: alloc:: { LayoutErr , MemoryBlock } ;
4
+ use core:: alloc:: MemoryBlock ;
5
5
use core:: cmp;
6
6
use core:: mem:: { self , ManuallyDrop , MaybeUninit } ;
7
7
use core:: ops:: Drop ;
@@ -172,7 +172,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
172
172
} else {
173
173
// We avoid `unwrap_or_else` here because it bloats the amount of
174
174
// LLVM IR generated.
175
- let layout = match Layout :: array :: < T > ( capacity) {
175
+ let layout = match array_layout ( Layout :: new :: < T > ( ) , capacity) {
176
176
Ok ( layout) => layout,
177
177
Err ( _) => capacity_overflow ( ) ,
178
178
} ;
@@ -423,10 +423,10 @@ impl<T, A: AllocRef> RawVec<T, A> {
423
423
} ;
424
424
let cap = cmp:: max ( min_non_zero_cap, cap) ;
425
425
426
- let new_layout = Layout :: array :: < T > ( cap ) ;
426
+ let elem_layout = Layout :: new :: < T > ( ) ;
427
427
428
428
// `finish_grow` is non-generic over `T`.
429
- let memory = finish_grow ( new_layout , self . current_memory ( ) , & mut self . alloc ) ?;
429
+ let memory = finish_grow ( cap , elem_layout , self . current_memory ( ) , & mut self . alloc ) ?;
430
430
self . set_memory ( memory) ;
431
431
Ok ( ( ) )
432
432
}
@@ -442,10 +442,11 @@ impl<T, A: AllocRef> RawVec<T, A> {
442
442
}
443
443
444
444
let cap = len. checked_add ( additional) . ok_or ( CapacityOverflow ) ?;
445
- let new_layout = Layout :: array :: < T > ( cap) ;
445
+
446
+ let elem_layout = Layout :: new :: < T > ( ) ;
446
447
447
448
// `finish_grow` is non-generic over `T`.
448
- let memory = finish_grow ( new_layout , self . current_memory ( ) , & mut self . alloc ) ?;
449
+ let memory = finish_grow ( cap , elem_layout , self . current_memory ( ) , & mut self . alloc ) ?;
449
450
self . set_memory ( memory) ;
450
451
Ok ( ( ) )
451
452
}
@@ -478,15 +479,16 @@ impl<T, A: AllocRef> RawVec<T, A> {
478
479
// significant, because the number of different `A` types seen in practice is
479
480
// much smaller than the number of `T` types.)
480
481
fn finish_grow < A > (
481
- new_layout : Result < Layout , LayoutErr > ,
482
+ cap : usize ,
483
+ elem_layout : Layout ,
482
484
current_memory : Option < ( NonNull < u8 > , Layout ) > ,
483
485
alloc : & mut A ,
484
486
) -> Result < MemoryBlock , TryReserveError >
485
487
where
486
488
A : AllocRef ,
487
489
{
488
490
// Check for the error here to minimize the size of `RawVec::grow_*`.
489
- let new_layout = new_layout . map_err ( |_| CapacityOverflow ) ?;
491
+ let new_layout = array_layout ( elem_layout , cap ) ?;
490
492
491
493
alloc_guard ( new_layout. size ( ) ) ?;
492
494
@@ -501,6 +503,15 @@ where
501
503
Ok ( memory)
502
504
}
503
505
506
+ // This is equivalent to Layout::array, but is non-generic and has a different
507
+ // error type in its result. It helps reduce the amount of LLVM IR generated.
508
+ #[ inline]
509
+ fn array_layout ( elem_layout : Layout , n : usize ) -> Result < Layout , TryReserveError > {
510
+ let ( new_layout, offset) = elem_layout. repeat ( n) . map_err ( |_| CapacityOverflow ) ?;
511
+ debug_assert_eq ! ( offset, elem_layout. size( ) ) ;
512
+ Ok ( new_layout. pad_to_align ( ) )
513
+ }
514
+
504
515
unsafe impl < #[ may_dangle] T , A : AllocRef > Drop for RawVec < T , A > {
505
516
/// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
506
517
fn drop ( & mut self ) {
0 commit comments