@@ -71,16 +71,19 @@ export class Array<T> {
7171
7272 unshift ( element : T ) : i32 {
7373 var oldCapacity = this . __capacity ;
74- if ( < u32 > this . length >= oldCapacity )
75- this . __grow ( max ( this . length + 1 , oldCapacity * 2 ) ) ;
76-
77- // FIXME: this is inefficient because of two copies, one in __grow and one here
78- // move_memory(this.__memory + sizeof<T>(), this.__memory, oldCapacity * sizeof<T>());
79-
80- if ( oldCapacity )
81- for ( var index : usize = oldCapacity ; index > 0 ; -- index )
82- store < T > ( this . __memory + index * sizeof < T > ( ) , load < T > ( this . __memory + ( index - 1 ) * sizeof < T > ( ) ) ) ;
83-
74+ if ( < u32 > this . length >= oldCapacity ) {
75+ // inlined `this.__grow(max(this.length + 1, oldCapacity * 2))` (avoids moving twice)
76+ var newCapacity = max ( this . length + 1 , oldCapacity * 2 ) ;
77+ assert ( newCapacity > this . __capacity ) ;
78+ var newMemory = allocate_memory ( < usize > newCapacity * sizeof < T > ( ) ) ;
79+ if ( this . __memory ) {
80+ move_memory ( newMemory + sizeof < T > ( ) , this . __memory , oldCapacity * sizeof < T > ( ) ) ;
81+ free_memory ( this . __memory ) ;
82+ }
83+ this . __memory = newMemory ;
84+ this . __capacity = newCapacity ;
85+ } else
86+ move_memory ( this . __memory + sizeof < T > ( ) , this . __memory , oldCapacity * sizeof < T > ( ) ) ;
8487 store < T > ( this . __memory , element ) ;
8588 return ++ this . length ;
8689 }
0 commit comments