summaryrefslogtreecommitdiffstats
path: root/chromium/v8/src/builtins/array-splice.tq
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/builtins/array-splice.tq')
-rw-r--r--chromium/v8/src/builtins/array-splice.tq103
1 files changed, 62 insertions, 41 deletions
diff --git a/chromium/v8/src/builtins/array-splice.tq b/chromium/v8/src/builtins/array-splice.tq
index 16a192d2c00..5746f4cdf67 100644
--- a/chromium/v8/src/builtins/array-splice.tq
+++ b/chromium/v8/src/builtins/array-splice.tq
@@ -9,8 +9,12 @@ module array {
// zero-length input FixedArray is handled here.
macro Extract<FixedArrayType: type>(
elements: FixedArrayBase, first: Smi, count: Smi,
- capacity: Smi): FixedArrayType {
- return UnsafeCast<FixedArrayType>(
+ capacity: Smi): FixedArrayType;
+
+ Extract<FixedArray>(
+ elements: FixedArrayBase, first: Smi, count: Smi,
+ capacity: Smi): FixedArray {
+ return UnsafeCast<FixedArray>(
ExtractFixedArray(elements, first, count, capacity));
}
@@ -24,31 +28,73 @@ module array {
ExtractFixedArray(elements, first, count, capacity));
}
+ macro DoMoveElements<FixedArrayType: type>(
+ elements: FixedArrayType, dstIndex: Smi, srcIndex: Smi,
+ count: Smi): void {
+ TorqueMoveElements(
+ elements, Convert<intptr>(dstIndex), Convert<intptr>(srcIndex),
+ Convert<intptr>(count));
+ }
+
+ macro StoreHoles<FixedArrayType: type>(
+ elements: FixedArrayType, holeStartIndex: Smi, holeEndIndex: Smi): void {
+ for (let i: Smi = holeStartIndex; i < holeEndIndex; i++) {
+ StoreArrayHole(elements, i);
+ }
+ }
+
+ macro DoCopyElements<FixedArrayType: type>(
+ dstElements: FixedArrayType, dstIndex: Smi, srcElements: FixedArrayType,
+ srcIndex: Smi, count: Smi): void {
+ TorqueCopyElements(
+ dstElements, Convert<intptr>(dstIndex), srcElements,
+ Convert<intptr>(srcIndex), Convert<intptr>(count));
+ }
+
macro FastSplice<FixedArrayType: type, ElementType: type>(
args: constexpr Arguments, a: JSArray, length: Smi, newLength: Smi,
lengthDelta: Smi, actualStart: Smi, insertCount: Smi,
actualDeleteCount: Smi): void
labels Bailout {
- const elements: FixedArrayBase = a.elements;
- const elementsMap: Map = elements.map;
-
- // If the spliced array is larger then the
- // source array, then allocate a new FixedArrayType to hold the result.
- let newElements: FixedArrayBase = elements;
- if (elementsMap == kCOWMap || lengthDelta > 0) {
- newElements =
- Extract<FixedArrayType>(elements, 0, actualStart, newLength);
- if (elementsMap == kCOWMap) {
- newElements.map = elementsMap;
+ // Make sure elements are writable.
+ EnsureWriteableFastElements(a);
+
+ if (insertCount != actualDeleteCount) {
+ const elements: FixedArrayBase = a.elements;
+ const dstIndex: Smi = actualStart + insertCount;
+ const srcIndex: Smi = actualStart + actualDeleteCount;
+ const count: Smi = length - actualDeleteCount - actualStart;
+ if (insertCount < actualDeleteCount) {
+ // Shrink.
+ DoMoveElements<FixedArrayType>(
+ UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
+ StoreHoles<FixedArrayType>(
+ UnsafeCast<FixedArrayType>(elements), newLength, length);
+ } else if (insertCount > actualDeleteCount) {
+ // If the backing store is big enough, then moving elements is enough.
+ if (newLength <= elements.length) {
+ DoMoveElements<FixedArrayType>(
+ UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
+ } else {
+ // Grow.
+ let capacity: Smi = CalculateNewElementsCapacity(newLength);
+ const newElements: FixedArrayType =
+ Extract<FixedArrayType>(elements, 0, actualStart, capacity);
+ a.elements = newElements;
+ if (elements.length > 0) {
+ DoCopyElements<FixedArrayType>(
+ newElements, dstIndex, UnsafeCast<FixedArrayType>(elements),
+ srcIndex, count);
+ }
+ }
}
- a.elements = newElements;
}
- // Copy over inserted elements.
+ // Copy arguments.
let k: Smi = actualStart;
if (insertCount > 0) {
const typedNewElements: FixedArrayType =
- UnsafeCast<FixedArrayType>(newElements);
+ UnsafeCast<FixedArrayType>(a.elements);
for (let e: Object of args [2: ]) {
// The argument elements were already validated to be an appropriate
// {ElementType} to store in {FixedArrayType}.
@@ -56,31 +102,6 @@ module array {
}
}
- // Copy over elements after deleted elements.
- let count: Smi = length - actualStart - actualDeleteCount;
- while (count > 0) {
- const typedElements: FixedArrayType =
- UnsafeCast<FixedArrayType>(elements);
- const typedNewElements: FixedArrayType =
- UnsafeCast<FixedArrayType>(newElements);
- CopyArrayElement(typedElements, typedNewElements, k - lengthDelta, k);
- k++;
- count--;
- }
-
- // Fill rest of spliced FixedArray with the hole, but only if the
- // destination FixedArray is the original array's, since otherwise the array
- // is pre-filled with holes.
- if (elements == newElements) {
- const typedNewElements: FixedArrayType =
- UnsafeCast<FixedArrayType>(newElements);
- const limit: Smi = elements.length;
- while (k < limit) {
- StoreArrayHole(typedNewElements, k);
- k++;
- }
- }
-
// Update the array's length after all the FixedArray shuffling is done.
a.length = newLength;
}