@@ -9,8 +9,12 @@ module array {
9
9
// zero-length input FixedArray is handled here.
10
10
macro Extract<FixedArrayType: type>(
11
11
elements: FixedArrayBase, first: Smi, count: Smi,
12
- capacity: Smi): FixedArrayType {
13
- return UnsafeCast<FixedArrayType>(
12
+ capacity: Smi): FixedArrayType;
13
+
14
+ Extract<FixedArray>(
15
+ elements: FixedArrayBase, first: Smi, count: Smi,
16
+ capacity: Smi): FixedArray {
17
+ return UnsafeCast<FixedArray>(
14
18
ExtractFixedArray(elements, first, count, capacity));
15
19
}
16
20
@@ -24,63 +28,80 @@ module array {
24
28
ExtractFixedArray(elements, first, count, capacity));
25
29
}
26
30
31
+ macro DoMoveElements<FixedArrayType: type>(
32
+ elements: FixedArrayType, dstIndex: Smi, srcIndex: Smi,
33
+ count: Smi): void {
34
+ TorqueMoveElements(
35
+ elements, Convert<intptr>(dstIndex), Convert<intptr>(srcIndex),
36
+ Convert<intptr>(count));
37
+ }
38
+
39
+ macro StoreHoles<FixedArrayType: type>(
40
+ elements: FixedArrayType, holeStartIndex: Smi, holeEndIndex: Smi): void {
41
+ for (let i: Smi = holeStartIndex; i < holeEndIndex; i++) {
42
+ StoreArrayHole(elements, i);
43
+ }
44
+ }
45
+
46
+ macro DoCopyElements<FixedArrayType: type>(
47
+ dstElements: FixedArrayType, dstIndex: Smi, srcElements: FixedArrayType,
48
+ srcIndex: Smi, count: Smi): void {
49
+ TorqueCopyElements(
50
+ dstElements, Convert<intptr>(dstIndex), srcElements,
51
+ Convert<intptr>(srcIndex), Convert<intptr>(count));
52
+ }
53
+
27
54
macro FastSplice<FixedArrayType: type, ElementType: type>(
28
55
args: constexpr Arguments, a: JSArray, length: Smi, newLength: Smi,
29
56
lengthDelta: Smi, actualStart: Smi, insertCount: Smi,
30
57
actualDeleteCount: Smi): void
31
58
labels Bailout {
32
- const elements: FixedArrayBase = a.elements;
33
- const elementsMap: Map = elements.map;
34
-
35
- // If the spliced array is larger then the
36
- // source array, then allocate a new FixedArrayType to hold the result.
37
- let newElements: FixedArrayBase = elements;
38
- if (elementsMap == kCOWMap || lengthDelta > 0) {
39
- newElements =
40
- Extract<FixedArrayType>(elements, 0, actualStart, newLength);
41
- if (elementsMap == kCOWMap) {
42
- newElements.map = elementsMap;
59
+ // Make sure elements are writable.
60
+ EnsureWriteableFastElements(a);
61
+
62
+ if (insertCount != actualDeleteCount) {
63
+ const elements: FixedArrayBase = a.elements;
64
+ const dstIndex: Smi = actualStart + insertCount;
65
+ const srcIndex: Smi = actualStart + actualDeleteCount;
66
+ const count: Smi = length - actualDeleteCount - actualStart;
67
+ if (insertCount < actualDeleteCount) {
68
+ // Shrink.
69
+ DoMoveElements<FixedArrayType>(
70
+ UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
71
+ StoreHoles<FixedArrayType>(
72
+ UnsafeCast<FixedArrayType>(elements), newLength, length);
73
+ } else if (insertCount > actualDeleteCount) {
74
+ // If the backing store is big enough, then moving elements is enough.
75
+ if (newLength <= elements.length) {
76
+ DoMoveElements<FixedArrayType>(
77
+ UnsafeCast<FixedArrayType>(elements), dstIndex, srcIndex, count);
78
+ } else {
79
+ // Grow.
80
+ let capacity: Smi = CalculateNewElementsCapacity(newLength);
81
+ const newElements: FixedArrayType =
82
+ Extract<FixedArrayType>(elements, 0, actualStart, capacity);
83
+ a.elements = newElements;
84
+ if (elements.length > 0) {
85
+ DoCopyElements<FixedArrayType>(
86
+ newElements, dstIndex, UnsafeCast<FixedArrayType>(elements),
87
+ srcIndex, count);
88
+ }
89
+ }
43
90
}
44
- a.elements = newElements;
45
91
}
46
92
47
- // Copy over inserted elements .
93
+ // Copy arguments .
48
94
let k: Smi = actualStart;
49
95
if (insertCount > 0) {
50
96
const typedNewElements: FixedArrayType =
51
- UnsafeCast<FixedArrayType>(newElements );
97
+ UnsafeCast<FixedArrayType>(a.elements );
52
98
for (let e: Object of args [2: ]) {
53
99
// The argument elements were already validated to be an appropriate
54
100
// {ElementType} to store in {FixedArrayType}.
55
101
typedNewElements[k++] = UnsafeCast<ElementType>(e);
56
102
}
57
103
}
58
104
59
- // Copy over elements after deleted elements.
60
- let count: Smi = length - actualStart - actualDeleteCount;
61
- while (count > 0) {
62
- const typedElements: FixedArrayType =
63
- UnsafeCast<FixedArrayType>(elements);
64
- const typedNewElements: FixedArrayType =
65
- UnsafeCast<FixedArrayType>(newElements);
66
- CopyArrayElement(typedElements, typedNewElements, k - lengthDelta, k);
67
- k++;
68
- count--;
69
- }
70
-
71
- // Fill rest of spliced FixedArray with the hole, but only if the
72
- // destination FixedArray is the original array's, since otherwise the array
73
- // is pre-filled with holes.
74
- if (elements == newElements) {
75
- const typedNewElements: FixedArrayType =
76
- UnsafeCast<FixedArrayType>(newElements);
77
- const limit: Smi = elements.length;
78
- while (k < limit) {
79
- StoreArrayHole(typedNewElements, k);
80
- k++;
81
- }
82
- }
83
-
84
105
// Update the array's length after all the FixedArray shuffling is done.
85
106
a.length = newLength;
86
107
}
0 commit comments