Skip to content

Commit 827bb4a

Browse files
committed
Use move_memory in std Array#unshift
1 parent ad469ca commit 827bb4a

File tree

4 files changed

+164
-3287
lines changed

4 files changed

+164
-3287
lines changed

std/assembly/array.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)