1212
1313use cast:: { forget, transmute} ;
1414use clone:: Clone ;
15- use cmp:: { Ord , Eq , Ordering , TotalEq , TotalOrd } ;
15+ use cmp:: { Ord , Eq , Ordering , TotalEq , TotalOrd , max } ;
1616use container:: { Container , Mutable } ;
1717use default:: Default ;
1818use fmt;
1919use iter:: { DoubleEndedIterator , FromIterator , Extendable , Iterator , range} ;
20- use libc:: { free, c_void} ;
21- use mem:: { size_of, move_val_init} ;
20+ use mem:: { min_align_of, move_val_init, size_of} ;
2221use mem;
2322use num;
2423use num:: { CheckedMul , CheckedAdd } ;
2524use ops:: { Add , Drop } ;
2625use option:: { None , Option , Some , Expect } ;
2726use ptr:: RawPtr ;
2827use ptr;
29- use rt:: global_heap:: { malloc_raw, realloc_raw} ;
3028use raw:: Slice ;
3129use RawVec = raw :: Vec ;
30+ use rt:: heap:: { allocate, reallocate, deallocate} ;
3231use slice:: { ImmutableEqVector , ImmutableVector , Items , MutItems , MutableVector } ;
3332use slice:: { MutableTotalOrdVector , OwnedVector , Vector } ;
3433use slice:: { MutableVectorAllocating } ;
@@ -96,7 +95,7 @@ impl<T> Vec<T> {
9695 Vec :: new ( )
9796 } else {
9897 let size = capacity. checked_mul ( & size_of :: < T > ( ) ) . expect ( "capacity overflow" ) ;
99- let ptr = unsafe { malloc_raw ( size) } ;
98+ let ptr = unsafe { allocate ( size, min_align_of :: < T > ( ) ) } ;
10099 Vec { len : 0 , cap : capacity, ptr : ptr as * mut T }
101100 }
102101 }
@@ -401,6 +400,16 @@ impl<T> Container for Vec<T> {
401400 }
402401}
403402
403+ // FIXME: #13996: need a way to mark the return value as `noalias`
404+ #[ inline( never) ]
405+ unsafe fn alloc_or_realloc ( ptr : * mut u8 , size : uint , align : uint , old_size : uint ) -> * mut u8 {
406+ if old_size == 0 {
407+ allocate ( size, align)
408+ } else {
409+ reallocate ( ptr, size, align, old_size)
410+ }
411+ }
412+
404413impl < T > Vec < T > {
405414 /// Returns the number of elements the vector can hold without
406415 /// reallocating.
@@ -479,31 +488,35 @@ impl<T> Vec<T> {
479488 pub fn reserve_exact ( & mut self , capacity : uint ) {
480489 if capacity > self . cap {
481490 let size = capacity. checked_mul ( & size_of :: < T > ( ) ) . expect ( "capacity overflow" ) ;
482- self . cap = capacity;
483491 unsafe {
484- self . ptr = realloc_raw ( self . ptr as * mut u8 , size) as * mut T ;
492+ self . ptr = alloc_or_realloc ( self . ptr as * mut u8 , size, min_align_of :: < T > ( ) ,
493+ self . cap * size_of :: < T > ( ) ) as * mut T ;
485494 }
495+ self . cap = capacity;
486496 }
487497 }
488498
489- /// Shrink the capacity of the vector to match the length
499+ /// Shrink the capacity of the vector as much as possible
490500 ///
491501 /// # Example
492502 ///
493503 /// ```rust
494504 /// let mut vec = vec!(1, 2, 3);
495505 /// vec.shrink_to_fit();
496- /// assert_eq!(vec.capacity(), vec.len());
497506 /// ```
498507 pub fn shrink_to_fit ( & mut self ) {
499508 if self . len == 0 {
500- unsafe { free ( self . ptr as * mut c_void ) } ;
501- self . cap = 0 ;
502- self . ptr = 0 as * mut T ;
509+ if self . cap != 0 {
510+ unsafe {
511+ deallocate ( self . ptr as * mut u8 , self . cap * size_of :: < T > ( ) , min_align_of :: < T > ( ) )
512+ }
513+ self . cap = 0 ;
514+ }
503515 } else {
504516 unsafe {
505517 // Overflow check is unnecessary as the vector is already at least this large.
506- self . ptr = realloc_raw ( self . ptr as * mut u8 , self . len * size_of :: < T > ( ) ) as * mut T ;
518+ self . ptr = reallocate ( self . ptr as * mut u8 , self . len * size_of :: < T > ( ) ,
519+ min_align_of :: < T > ( ) , self . cap * size_of :: < T > ( ) ) as * mut T ;
507520 }
508521 self . cap = self . len ;
509522 }
@@ -547,14 +560,14 @@ impl<T> Vec<T> {
547560 #[ inline]
548561 pub fn push ( & mut self , value : T ) {
549562 if self . len == self . cap {
550- if self . cap == 0 { self . cap += 2 }
551563 let old_size = self . cap * size_of :: < T > ( ) ;
552- self . cap = self . cap * 2 ;
553- let size = old_size * 2 ;
564+ let size = max ( old_size, 2 * size_of :: < T > ( ) ) * 2 ;
554565 if old_size > size { fail ! ( "capacity overflow" ) }
555566 unsafe {
556- self . ptr = realloc_raw ( self . ptr as * mut u8 , size) as * mut T ;
567+ self . ptr = alloc_or_realloc ( self . ptr as * mut u8 , size, min_align_of :: < T > ( ) ,
568+ self . cap * size_of :: < T > ( ) ) as * mut u8 as * mut T ;
557569 }
570+ self . cap = max ( self . cap , 2 ) * 2 ;
558571 }
559572
560573 unsafe {
@@ -638,9 +651,10 @@ impl<T> Vec<T> {
638651 pub fn move_iter ( self ) -> MoveItems < T > {
639652 unsafe {
640653 let iter = transmute ( self . as_slice ( ) . iter ( ) ) ;
641- let ptr = self . ptr as * mut c_void ;
654+ let ptr = self . ptr as * mut u8 ;
655+ let cap = self . cap ;
642656 forget ( self ) ;
643- MoveItems { allocation : ptr, iter : iter }
657+ MoveItems { allocation : ptr, cap : cap , iter : iter }
644658 }
645659 }
646660
@@ -1386,11 +1400,13 @@ impl<T> Drop for Vec<T> {
13861400 fn drop ( & mut self ) {
13871401 // This is (and should always remain) a no-op if the fields are
13881402 // zeroed (when moving out, because of #[unsafe_no_drop_flag]).
1389- unsafe {
1390- for x in self . as_mut_slice ( ) . iter ( ) {
1391- ptr:: read ( x) ;
1403+ if self . cap != 0 {
1404+ unsafe {
1405+ for x in self . as_mut_slice ( ) . iter ( ) {
1406+ ptr:: read ( x) ;
1407+ }
1408+ deallocate ( self . ptr as * mut u8 , self . cap * size_of :: < T > ( ) , min_align_of :: < T > ( ) )
13921409 }
1393- free ( self . ptr as * mut c_void )
13941410 }
13951411 }
13961412}
@@ -1409,7 +1425,8 @@ impl<T:fmt::Show> fmt::Show for Vec<T> {
14091425
14101426/// An iterator that moves out of a vector.
14111427pub struct MoveItems < T > {
1412- allocation : * mut c_void , // the block of memory allocated for the vector
1428+ allocation : * mut u8 , // the block of memory allocated for the vector
1429+ cap : uint , // the capacity of the vector
14131430 iter : Items < ' static , T >
14141431}
14151432
@@ -1440,9 +1457,11 @@ impl<T> DoubleEndedIterator<T> for MoveItems<T> {
14401457impl < T > Drop for MoveItems < T > {
14411458 fn drop ( & mut self ) {
14421459 // destroy the remaining elements
1443- for _x in * self { }
1444- unsafe {
1445- free ( self . allocation )
1460+ if self . cap != 0 {
1461+ for _x in * self { }
1462+ unsafe {
1463+ deallocate ( self . allocation , self . cap * size_of :: < T > ( ) , min_align_of :: < T > ( ) )
1464+ }
14461465 }
14471466 }
14481467}
0 commit comments