Title: [222658] trunk
Revision
222658
Author
[email protected]
Date
2017-09-29 11:49:37 -0700 (Fri, 29 Sep 2017)

Log Message

Unreviewed, rolling out r222563, r222565, and r222581.
https://bugs.webkit.org/show_bug.cgi?id=177675

"It causes a crash when playing youtube videos" (Requested by
saamyjoon on #webkit).

Reverted changesets:

"[DFG] Support ArrayPush with multiple args"
https://bugs.webkit.org/show_bug.cgi?id=175823
http://trac.webkit.org/changeset/222563

"Unreviewed, build fix after r222563"
https://bugs.webkit.org/show_bug.cgi?id=175823
http://trac.webkit.org/changeset/222565

"Unreviewed, fix x86 breaking due to exhausted registers"
https://bugs.webkit.org/show_bug.cgi?id=175823
http://trac.webkit.org/changeset/222581

Modified Paths

Removed Paths

Diff

Modified: trunk/JSTests/ChangeLog (222657 => 222658)


--- trunk/JSTests/ChangeLog	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/ChangeLog	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,3 +1,25 @@
+2017-09-29  Commit Queue  <[email protected]>
+
+        Unreviewed, rolling out r222563, r222565, and r222581.
+        https://bugs.webkit.org/show_bug.cgi?id=177675
+
+        "It causes a crash when playing youtube videos" (Requested by
+        saamyjoon on #webkit).
+
+        Reverted changesets:
+
+        "[DFG] Support ArrayPush with multiple args"
+        https://bugs.webkit.org/show_bug.cgi?id=175823
+        http://trac.webkit.org/changeset/222563
+
+        "Unreviewed, build fix after r222563"
+        https://bugs.webkit.org/show_bug.cgi?id=175823
+        http://trac.webkit.org/changeset/222565
+
+        "Unreviewed, fix x86 breaking due to exhausted registers"
+        https://bugs.webkit.org/show_bug.cgi?id=175823
+        http://trac.webkit.org/changeset/222581
+
 2017-09-28  Mark Lam  <[email protected]>
 
         test262: Unexpected passes after r222617 and r222618.

Deleted: trunk/JSTests/microbenchmarks/array-push-0.js (222657 => 222658)


--- trunk/JSTests/microbenchmarks/array-push-0.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/microbenchmarks/array-push-0.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,9 +0,0 @@
-function arrayPush0() {
-  var ret = [1];
-  ret.push();
-  return ret;
-}
-noInline(arrayPush0);
-
-for (var i = 0; i < 1e7; ++i)
-    arrayPush0();

Deleted: trunk/JSTests/microbenchmarks/array-push-1.js (222657 => 222658)


--- trunk/JSTests/microbenchmarks/array-push-1.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/microbenchmarks/array-push-1.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,9 +0,0 @@
-function arrayPush1() {
-  var ret = [1];
-  ret.push(1);
-  return ret;
-}
-noInline(arrayPush1);
-
-for (var i = 0; i < 1e7; ++i)
-    arrayPush1();

Deleted: trunk/JSTests/microbenchmarks/array-push-2.js (222657 => 222658)


--- trunk/JSTests/microbenchmarks/array-push-2.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/microbenchmarks/array-push-2.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,9 +0,0 @@
-function arrayPush2() {
-  var ret = [1];
-  ret.push(1, 2);
-  return ret;
-}
-noInline(arrayPush2);
-
-for (var i = 0; i < 1e7; ++i)
-    arrayPush2();

Deleted: trunk/JSTests/microbenchmarks/array-push-3.js (222657 => 222658)


--- trunk/JSTests/microbenchmarks/array-push-3.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/microbenchmarks/array-push-3.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,9 +0,0 @@
-function arrayPush3() {
-  var ret = [1];
-  ret.push(1, 2, 3);
-  return ret;
-}
-noInline(arrayPush3);
-
-for (var i = 0; i < 1e7; ++i)
-    arrayPush3();

Deleted: trunk/JSTests/stress/array-push-multiple-contiguous.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-contiguous.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-contiguous.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,19 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3)
-{
-    return array.push(val1, val2, val3);
-}
-noInline(test);
-
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    shouldBe(test(array, "Cocoa", "Cappuccino", "Matcha"), 3);
-    shouldBe(array[0], "Cocoa");
-    shouldBe(array[1], "Cappuccino");
-    shouldBe(array[2], "Matcha");
-}

Deleted: trunk/JSTests/stress/array-push-multiple-double-nan.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-double-nan.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-double-nan.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,25 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3)
-{
-    return array.push(val1, val2, val3);
-}
-noInline(test);
-
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    var value = 3.3;
-    if (i === 1e5 - 1)
-        value = NaN;
-    shouldBe(test(array, 1.1, 2.2, value), 3);
-    shouldBe(array[0], 1.1);
-    shouldBe(array[1], 2.2);
-    if (i === 1e5 - 1)
-        shouldBe(Number.isNaN(array[2]), true);
-    else
-        shouldBe(array[2], 3.3);
-}

Deleted: trunk/JSTests/stress/array-push-multiple-double.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-double.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-double.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,32 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3)
-{
-    return array.push(val1, val2, val3);
-}
-noInline(test);
-
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    shouldBe(test(array, 1.1, 2.2, 3.3), 3);
-    shouldBe(array[0], 1.1);
-    shouldBe(array[1], 2.2);
-    shouldBe(array[2], 3.3);
-}
-
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    shouldBe(test(array, 1.1, 2.2, 4), 3);
-    shouldBe(array[0], 1.1);
-    shouldBe(array[1], 2.2);
-    shouldBe(array[2], 4);
-}
-var array = [];
-shouldBe(test(array, 1.1, 2.2, "String"), 3);
-shouldBe(array[0], 1.1);
-shouldBe(array[1], 2.2);
-shouldBe(array[2], "String");

Deleted: trunk/JSTests/stress/array-push-multiple-int32.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-int32.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-int32.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,24 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3)
-{
-    return array.push(val1, val2, val3);
-}
-noInline(test);
-
-for (var i = 0; i < 1e7; ++i) {
-    var array = [];
-    shouldBe(test(array, 1, 2, 3), 3);
-    shouldBe(array[0], 1);
-    shouldBe(array[1], 2);
-    shouldBe(array[2], 3);
-}
-var array = [];
-shouldBe(test(array, 1, 2, 3.3), 3);
-shouldBe(array[0], 1);
-shouldBe(array[1], 2);
-shouldBe(array[2], 3.3);

Deleted: trunk/JSTests/stress/array-push-multiple-many-contiguous.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-many-contiguous.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-many-contiguous.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,20 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12)
-{
-    return array.push(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12);
-}
-noInline(test);
-
-var values = [ "AB", "BC", "CD", "DE", "EF", "FG", "GH", "HI", "IJ", "JK", "KL", "LM" ];
-shouldBe(values.length, 12);
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    shouldBe(test(array, values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9], values[10], values[11]), 12);
-    for (var j = 0; j < values.length; ++j)
-        shouldBe(array[j], values[j]);
-}

Deleted: trunk/JSTests/stress/array-push-multiple-many-double.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-many-double.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-many-double.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,20 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12)
-{
-    return array.push(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12);
-}
-noInline(test);
-
-var values = [ 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2 ];
-shouldBe(values.length, 12);
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    shouldBe(test(array, values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9], values[10], values[11]), 12);
-    for (var j = 0; j < values.length; ++j)
-        shouldBe(array[j], values[j]);
-}

Deleted: trunk/JSTests/stress/array-push-multiple-many-int32.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-many-int32.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-many-int32.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,20 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12)
-{
-    return array.push(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12);
-}
-noInline(test);
-
-var values = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ];
-shouldBe(values.length, 12);
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    shouldBe(test(array, values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9], values[10], values[11]), 12);
-    for (var j = 0; j < values.length; ++j)
-        shouldBe(array[j], values[j]);
-}

Deleted: trunk/JSTests/stress/array-push-multiple-many-storage.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-many-storage.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-many-storage.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,21 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12)
-{
-    return array.push(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12);
-}
-noInline(test);
-
-var values = [ "AB", "BC", "CD", "DE", "EF", "FG", "GH", "HI", "IJ", "JK", "KL", "LM" ];
-shouldBe(values.length, 12);
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    ensureArrayStorage(array);
-    shouldBe(test(array, values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9], values[10], values[11]), 12);
-    for (var j = 0; j < values.length; ++j)
-        shouldBe(array[j], values[j]);
-}

Deleted: trunk/JSTests/stress/array-push-multiple-storage.js (222657 => 222658)


--- trunk/JSTests/stress/array-push-multiple-storage.js	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/JSTests/stress/array-push-multiple-storage.js	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,29 +0,0 @@
-function shouldBe(actual, expected)
-{
-    if (actual !== expected)
-        throw new Error('bad value: ' + actual);
-}
-
-function test(array, val1, val2, val3)
-{
-    return array.push(val1, val2, val3);
-}
-noInline(test);
-
-for (var i = 0; i < 1e5; ++i) {
-    var array = [];
-    ensureArrayStorage(array);
-    shouldBe(test(array, "Cocoa", "Cappuccino", "Matcha"), 3);
-    shouldBe(array[0], "Cocoa");
-    shouldBe(array[1], "Cappuccino");
-    shouldBe(array[2], "Matcha");
-}
-for (var i = 0; i < 1e5; ++i) {
-    var array = [0];
-    ensureArrayStorage(array);
-    shouldBe(test(array, "Cocoa", "Cappuccino", "Matcha"), 4);
-    shouldBe(array[0], 0);
-    shouldBe(array[1], "Cocoa");
-    shouldBe(array[2], "Cappuccino");
-    shouldBe(array[3], "Matcha");
-}

Modified: trunk/Source/_javascript_Core/ChangeLog (222657 => 222658)


--- trunk/Source/_javascript_Core/ChangeLog	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1,5 +1,27 @@
 2017-09-29  Commit Queue  <[email protected]>
 
+        Unreviewed, rolling out r222563, r222565, and r222581.
+        https://bugs.webkit.org/show_bug.cgi?id=177675
+
+        "It causes a crash when playing youtube videos" (Requested by
+        saamyjoon on #webkit).
+
+        Reverted changesets:
+
+        "[DFG] Support ArrayPush with multiple args"
+        https://bugs.webkit.org/show_bug.cgi?id=175823
+        http://trac.webkit.org/changeset/222563
+
+        "Unreviewed, build fix after r222563"
+        https://bugs.webkit.org/show_bug.cgi?id=175823
+        http://trac.webkit.org/changeset/222565
+
+        "Unreviewed, fix x86 breaking due to exhausted registers"
+        https://bugs.webkit.org/show_bug.cgi?id=175823
+        http://trac.webkit.org/changeset/222581
+
+2017-09-29  Commit Queue  <[email protected]>
+
         Unreviewed, rolling out r222625.
         https://bugs.webkit.org/show_bug.cgi?id=177664
 

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -2334,14 +2334,7 @@
     }
         
     case ArrayPushIntrinsic: {
-#if USE(JSVALUE32_64)
-        if (isX86() || isMIPS()) {
-            if (argumentCountIncludingThis > 2)
-                return false;
-        }
-#endif
-
-        if (static_cast<unsigned>(argumentCountIncludingThis) >= MIN_SPARSE_ARRAY_INDEX)
+        if (argumentCountIncludingThis != 2)
             return false;
         
         ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile);
@@ -2353,11 +2346,7 @@
         case Array::Contiguous:
         case Array::ArrayStorage: {
             insertChecks();
-
-            addVarArgChild(nullptr); // For storage.
-            for (int i = 0; i < argumentCountIncludingThis; ++i)
-                addVarArgChild(get(virtualRegisterForArgument(i, registerOffset)));
-            Node* arrayPush = addToGraph(Node::VarArg, ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction));
+            Node* arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
             set(VirtualRegister(resultOperand), arrayPush);
             
             return true;

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1008,54 +1008,29 @@
             // ignored. That's because ArrayPush can't handle any array modes that aren't
             // array-related - so if refine() turned this into a "Generic" ArrayPush then
             // that would break things.
-            Edge& storageEdge = m_graph.varArgChild(node, 0);
-            Edge& arrayEdge = m_graph.varArgChild(node, 1);
-            unsigned elementOffset = 2;
-            unsigned elementCount = node->numChildren() - elementOffset;
-            for (unsigned i = 0; i < elementCount; ++i) {
-                Edge& element = m_graph.varArgChild(node, i + elementOffset);
-                node->setArrayMode(
-                    node->arrayMode().refine(
-                        m_graph, node,
-                        arrayEdge->prediction() & SpecCell,
-                        SpecInt32Only,
-                        element->prediction()));
-            }
-            blessArrayOperation(arrayEdge, Edge(), storageEdge);
-            fixEdge<KnownCellUse>(arrayEdge);
-
-            // Convert `array.push()` to GetArrayLength.
-            ASSERT(node->arrayMode().supportsSelfLength());
-            if (!elementCount) {
-                node->setOpAndDefaultFlags(GetArrayLength);
-                node->child1() = arrayEdge;
-                node->child2() = storageEdge;
-                fixEdge<KnownCellUse>(node->child1());
+            node->setArrayMode(
+                node->arrayMode().refine(
+                    m_graph, node,
+                    node->child1()->prediction() & SpecCell,
+                    SpecInt32Only,
+                    node->child2()->prediction()));
+            blessArrayOperation(node->child1(), Edge(), node->child3());
+            fixEdge<KnownCellUse>(node->child1());
+            
+            switch (node->arrayMode().type()) {
+            case Array::Int32:
+                fixEdge<Int32Use>(node->child2());
                 break;
+            case Array::Double:
+                fixEdge<DoubleRepRealUse>(node->child2());
+                break;
+            case Array::Contiguous:
+            case Array::ArrayStorage:
+                speculateForBarrier(node->child2());
+                break;
+            default:
+                break;
             }
-
-            // We do not want to perform osr exit and retry for ArrayPush. We insert Check with appropriate type,
-            // and ArrayPush uses the edge as known typed edge. Therefore, ArrayPush do not need to perform type checks.
-            for (unsigned i = 0; i < elementCount; ++i) {
-                Edge& element = m_graph.varArgChild(node, i + elementOffset);
-                switch (node->arrayMode().type()) {
-                case Array::Int32:
-                    insertCheck<Int32Use>(element.node());
-                    fixEdge<KnownInt32Use>(element);
-                    break;
-                case Array::Double:
-                    insertCheck<DoubleRepRealUse>(element.node());
-                    fixEdge<DoubleRepUse>(element);
-                    break;
-                case Array::Contiguous:
-                case Array::ArrayStorage:
-                    speculateForBarrier(element);
-                    break;
-                default:
-                    RELEASE_ASSERT_NOT_REACHED();
-                }
-                ASSERT(shouldNotHaveTypeCheck(element.useKind()));
-            }
             break;
         }
             

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2017-09-29 18:49:37 UTC (rev 222658)
@@ -265,7 +265,7 @@
     macro(AtomicsXor, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
     \
     /* Optimizations for array mutation. */\
-    macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
+    macro(ArrayPush, NodeResultJS | NodeMustGenerate) \
     macro(ArrayPop, NodeResultJS | NodeMustGenerate) \
     macro(ArraySlice, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
     macro(ArrayIndexOf, NodeResultInt32 | NodeHasVarArgs) \

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -869,7 +869,7 @@
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    array->pushInline(exec, JSValue::decode(encodedValue));
+    array->push(exec, JSValue::decode(encodedValue));
     return JSValue::encode(jsNumber(array->length()));
 }
 
@@ -878,54 +878,10 @@
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
     
-    array->pushInline(exec, JSValue(JSValue::EncodeAsDouble, value));
+    array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
     return JSValue::encode(jsNumber(array->length()));
 }
 
-EncodedJSValue JIT_OPERATION operationArrayPushMultiple(ExecState* exec, JSArray* array, void* buffer, int32_t elementCount)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    // We assume that multiple JSArray::push calls with ArrayWithInt32/ArrayWithContiguous do not cause JS traps.
-    // If it can cause any JS interactions, we can call the caller JS function of this function and overwrite the
-    // content of ScratchBuffer. If the IndexingType is now ArrayWithInt32/ArrayWithContiguous, we can ensure
-    // that there is no indexed accessors in this object and its prototype chain.
-    //
-    // ArrayWithArrayStorage is also OK. It can have indexed accessors. But if you define an indexed accessor, the array's length
-    // becomes larger than that index. So Array#push never overlaps with this accessor. So accessors are never called unless
-    // the IndexingType is ArrayWithSlowPutArrayStorage which could have an indexed accessor in a prototype chain.
-    RELEASE_ASSERT(!shouldUseSlowPut(array->indexingType()));
-
-    EncodedJSValue* values = static_cast<EncodedJSValue*>(buffer);
-    for (int32_t i = 0; i < elementCount; ++i) {
-        array->pushInline(exec, JSValue::decode(values[i]));
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
-    }
-    return JSValue::encode(jsNumber(array->length()));
-}
-
-EncodedJSValue JIT_OPERATION operationArrayPushDoubleMultiple(ExecState* exec, JSArray* array, void* buffer, int32_t elementCount)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    // We assume that multiple JSArray::push calls with ArrayWithDouble do not cause JS traps.
-    // If it can cause any JS interactions, we can call the caller JS function of this function and overwrite the
-    // content of ScratchBuffer. If the IndexingType is now ArrayWithDouble, we can ensure
-    // that there is no indexed accessors in this object and its prototype chain.
-    ASSERT(array->indexingType() == ArrayWithDouble);
-
-    double* values = static_cast<double*>(buffer);
-    for (int32_t i = 0; i < elementCount; ++i) {
-        array->pushInline(exec, JSValue(JSValue::EncodeAsDouble, values[i]));
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
-    }
-    return JSValue::encode(jsNumber(array->length()));
-}
-
 EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
 {
     VM* vm = &exec->vm();

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2017-09-29 18:49:37 UTC (rev 222658)
@@ -136,9 +136,7 @@
 void JIT_OPERATION operationDefineAccessorPropertyStringIdent(ExecState*, JSObject*, UniquedStringImpl*, JSObject*, JSObject*, int32_t) WTF_INTERNAL;
 void JIT_OPERATION operationDefineAccessorPropertySymbol(ExecState*, JSObject*, Symbol*, JSObject*, JSObject*, int32_t) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArrayPushMultiple(ExecState*, JSArray*, void* buffer, int32_t elementCount) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState*, double value, JSArray*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArrayPushDoubleMultiple(ExecState*, JSArray*, void* buffer, int32_t elementCount) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPop(ExecState*, JSArray*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState*, JSArray*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState*, JSGlobalObject*, RegExpObject*, JSString*) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -7871,278 +7871,6 @@
     }
 }
 
-void SpeculativeJIT::compileArrayPush(Node* node)
-{
-    ASSERT(node->arrayMode().isJSArray());
-
-    Edge& storageEdge = m_jit.graph().varArgChild(node, 0);
-    Edge& arrayEdge = m_jit.graph().varArgChild(node, 1);
-
-    SpeculateCellOperand base(this, arrayEdge);
-    GPRTemporary storageLength(this);
-
-    GPRReg baseGPR = base.gpr();
-    GPRReg storageLengthGPR = storageLength.gpr();
-
-    StorageOperand storage(this, storageEdge);
-    GPRReg storageGPR = storage.gpr();
-    unsigned elementOffset = 2;
-    unsigned elementCount = node->numChildren() - elementOffset;
-
-#if USE(JSVALUE32_64)
-    GPRTemporary tag(this);
-    GPRReg tagGPR = tag.gpr();
-    JSValueRegs resultRegs { tagGPR, storageLengthGPR };
-#else
-    JSValueRegs resultRegs { storageLengthGPR };
-#endif
-
-    auto getStorageBufferAddress = [&] (GPRReg storageGPR, GPRReg indexGPR, int32_t offset, GPRReg bufferGPR) {
-#if USE(JSVALUE32_64)
-        static_assert(sizeof(JSValue) == 8 && 1 << 3 == 8, "This is strongly assumed in the code below.");
-        m_jit.move(indexGPR, bufferGPR);
-        m_jit.lshift32(TrustedImm32(3), bufferGPR);
-        m_jit.add32(storageGPR, bufferGPR);
-        if (offset)
-            m_jit.add32(TrustedImm32(offset), bufferGPR);
-#else
-        m_jit.getEffectiveAddress64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, offset), bufferGPR);
-#endif
-    };
-
-    switch (node->arrayMode().type()) {
-    case Array::Int32:
-    case Array::Contiguous: {
-        if (elementCount == 1) {
-            Edge& element = m_jit.graph().varArgChild(node, elementOffset);
-            JSValueOperand value(this, element, ManualOperandSpeculation);
-            JSValueRegs valueRegs = value.jsValueRegs();
-
-            if (node->arrayMode().type() == Array::Int32)
-                RELEASE_ASSERT(!needsTypeCheck(element, SpecInt32Only));
-
-            m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
-            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
-            m_jit.storeValue(valueRegs, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
-            m_jit.add32(TrustedImm32(1), storageLengthGPR);
-            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
-            m_jit.boxInt32(storageLengthGPR, resultRegs);
-
-            addSlowPathGenerator(
-                slowPathCall(slowPath, this, operationArrayPush, resultRegs, valueRegs, baseGPR));
-
-            jsValueResult(resultRegs, node);
-            return;
-        }
-
-        GPRTemporary buffer(this);
-        GPRReg bufferGPR = buffer.gpr();
-
-        m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
-        m_jit.move(storageLengthGPR, bufferGPR);
-        m_jit.add32(TrustedImm32(elementCount), bufferGPR);
-        MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::Above, bufferGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
-
-        m_jit.store32(bufferGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
-        getStorageBufferAddress(storageGPR, storageLengthGPR, 0, bufferGPR);
-        m_jit.add32(TrustedImm32(elementCount), storageLengthGPR);
-        m_jit.boxInt32(storageLengthGPR, resultRegs);
-        auto storageDone = m_jit.jump();
-
-        slowPath.link(&m_jit);
-
-        size_t scratchSize = sizeof(EncodedJSValue) * elementCount;
-        ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(scratchSize);
-        m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR);
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);
-        m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));
-
-        storageDone.link(&m_jit);
-        for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
-            Edge& element = m_jit.graph().varArgChild(node, elementIndex + elementOffset);
-            JSValueOperand value(this, element, ManualOperandSpeculation);
-            JSValueRegs valueRegs = value.jsValueRegs();
-
-            if (node->arrayMode().type() == Array::Int32)
-                RELEASE_ASSERT(!needsTypeCheck(element, SpecInt32Only));
-
-            m_jit.storeValue(valueRegs, MacroAssembler::Address(bufferGPR, sizeof(EncodedJSValue) * elementIndex));
-            value.use();
-        }
-
-        MacroAssembler::Jump fastPath = m_jit.branchPtr(MacroAssembler::NotEqual, bufferGPR, TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())));
-
-        addSlowPathGenerator(slowPathCall(m_jit.jump(), this, operationArrayPushMultiple, resultRegs, baseGPR, bufferGPR, TrustedImm32(elementCount)));
-
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);
-        m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));
-
-        base.use();
-        storage.use();
-
-        fastPath.link(&m_jit);
-        jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
-        return;
-    }
-
-    case Array::Double: {
-        if (elementCount == 1) {
-            Edge& element = m_jit.graph().varArgChild(node, elementOffset);
-            SpeculateDoubleOperand value(this, element);
-            FPRReg valueFPR = value.fpr();
-
-            RELEASE_ASSERT(!needsTypeCheck(element, SpecDoubleReal));
-
-            m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
-            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
-            m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
-            m_jit.add32(TrustedImm32(1), storageLengthGPR);
-            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
-            m_jit.boxInt32(storageLengthGPR, resultRegs);
-
-            addSlowPathGenerator(
-                slowPathCall(slowPath, this, operationArrayPushDouble, resultRegs, valueFPR, baseGPR));
-
-            jsValueResult(resultRegs, node);
-            return;
-        }
-
-        GPRTemporary buffer(this);
-        GPRReg bufferGPR = buffer.gpr();
-
-        m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
-        m_jit.move(storageLengthGPR, bufferGPR);
-        m_jit.add32(TrustedImm32(elementCount), bufferGPR);
-        MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::Above, bufferGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
-
-        m_jit.store32(bufferGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
-        getStorageBufferAddress(storageGPR, storageLengthGPR, 0, bufferGPR);
-        m_jit.add32(TrustedImm32(elementCount), storageLengthGPR);
-        m_jit.boxInt32(storageLengthGPR, resultRegs);
-        auto storageDone = m_jit.jump();
-
-        slowPath.link(&m_jit);
-
-        size_t scratchSize = sizeof(double) * elementCount;
-        ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(scratchSize);
-        m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR);
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);
-        m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));
-
-        storageDone.link(&m_jit);
-        for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
-            Edge& element = m_jit.graph().varArgChild(node, elementIndex + elementOffset);
-            SpeculateDoubleOperand value(this, element);
-            FPRReg valueFPR = value.fpr();
-
-            RELEASE_ASSERT(!needsTypeCheck(element, SpecDoubleReal));
-
-            m_jit.storeDouble(valueFPR, MacroAssembler::Address(bufferGPR, sizeof(double) * elementIndex));
-            value.use();
-        }
-
-        MacroAssembler::Jump fastPath = m_jit.branchPtr(MacroAssembler::NotEqual, bufferGPR, TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())));
-
-        addSlowPathGenerator(slowPathCall(m_jit.jump(), this, operationArrayPushDoubleMultiple, resultRegs, baseGPR, bufferGPR, TrustedImm32(elementCount)));
-
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);
-        m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));
-
-        base.use();
-        storage.use();
-
-        fastPath.link(&m_jit);
-        jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
-        return;
-    }
-
-    case Array::ArrayStorage: {
-        // This ensures that the result of ArrayPush is Int32 in AI.
-        int32_t largestPositiveInt32Length = 0x7fffffff - elementCount;
-        if (elementCount == 1) {
-            Edge& element = m_jit.graph().varArgChild(node, elementOffset);
-            JSValueOperand value(this, element);
-            JSValueRegs valueRegs = value.jsValueRegs();
-
-            m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
-
-            // Refuse to handle bizarre lengths.
-            speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(largestPositiveInt32Length)));
-
-            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
-
-            m_jit.storeValue(valueRegs, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()));
-
-            m_jit.add32(TrustedImm32(1), storageLengthGPR);
-            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
-            m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
-            m_jit.boxInt32(storageLengthGPR, resultRegs);
-
-            addSlowPathGenerator(
-                slowPathCall(slowPath, this, operationArrayPush, resultRegs, valueRegs, baseGPR));
-
-            jsValueResult(resultRegs, node);
-            return;
-        }
-
-        GPRTemporary buffer(this);
-        GPRReg bufferGPR = buffer.gpr();
-
-        m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
-
-        // Refuse to handle bizarre lengths.
-        speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(largestPositiveInt32Length)));
-
-        m_jit.move(storageLengthGPR, bufferGPR);
-        m_jit.add32(TrustedImm32(elementCount), bufferGPR);
-        MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::Above, bufferGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
-
-        m_jit.store32(bufferGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
-        getStorageBufferAddress(storageGPR, storageLengthGPR, ArrayStorage::vectorOffset(), bufferGPR);
-        m_jit.add32(TrustedImm32(elementCount), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
-        m_jit.add32(TrustedImm32(elementCount), storageLengthGPR);
-        m_jit.boxInt32(storageLengthGPR, resultRegs);
-        auto storageDone = m_jit.jump();
-
-        slowPath.link(&m_jit);
-
-        size_t scratchSize = sizeof(EncodedJSValue) * elementCount;
-        ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(scratchSize);
-        m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR);
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);
-        m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));
-
-        storageDone.link(&m_jit);
-        for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
-            Edge& element = m_jit.graph().varArgChild(node, elementIndex + elementOffset);
-            JSValueOperand value(this, element);
-            JSValueRegs valueRegs = value.jsValueRegs();
-
-            m_jit.storeValue(valueRegs, MacroAssembler::Address(bufferGPR, sizeof(EncodedJSValue) * elementIndex));
-            value.use();
-        }
-
-        MacroAssembler::Jump fastPath = m_jit.branchPtr(MacroAssembler::NotEqual, bufferGPR, TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())));
-
-        addSlowPathGenerator(
-            slowPathCall(m_jit.jump(), this, operationArrayPushMultiple, resultRegs, baseGPR, bufferGPR, TrustedImm32(elementCount)));
-
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);
-        m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));
-
-        base.use();
-        storage.use();
-
-        fastPath.link(&m_jit);
-        jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
-        return;
-    }
-
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-}
-
 void SpeculativeJIT::compileNotifyWrite(Node* node)
 {
     WatchpointSet* set = node->watchpointSet();

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2017-09-29 18:49:37 UTC (rev 222658)
@@ -1613,14 +1613,9 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EJA operation, JSValueRegs result, JSValueRegs arg1, GPRReg arg2)
+    JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     {
-        m_jit.setupArgumentsWithExecState(arg1.gpr(), arg2);
-        return appendCallSetResult(operation, result.payloadGPR());
-    }
-    JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg result, JSValueRegs arg1, GPRReg arg2)
-    {
-        m_jit.setupArgumentsWithExecState(arg1.gpr(), arg2);
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result);
     }
     JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, GPRReg arg1)
@@ -1794,16 +1789,6 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EAPZ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
-    {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
-        return appendCallSetResult(operation, result.payloadGPR());
-    }
-    JITCompiler::Call callOperation(J_JITOperation_EAPZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
-    {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
-        return appendCallSetResult(operation, result);
-    }
     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2);
@@ -2129,11 +2114,6 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
     }
-    JITCompiler::Call callOperation(J_JITOperation_EAPZ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
-    {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
-        return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
-    }
     JITCompiler::Call callOperation(J_JITOperation_EP operation, JSValueRegs result, GPRReg arg1)
     {
         m_jit.setupArgumentsWithExecState(arg1);
@@ -2948,7 +2928,6 @@
     void compileGetRestLength(Node*);
     void compileArraySlice(Node*);
     void compileArrayIndexOf(Node*);
-    void compileArrayPush(Node*);
     void compileNotifyWrite(Node*);
     bool compileRegExpExec(Node*);
     void compileIsObjectOrNull(Node*);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -3384,7 +3384,119 @@
     }
         
     case ArrayPush: {
-        compileArrayPush(node);
+        ASSERT(node->arrayMode().isJSArray());
+        
+        SpeculateCellOperand base(this, node->child1());
+        GPRTemporary storageLength(this);
+        
+        GPRReg baseGPR = base.gpr();
+        GPRReg storageLengthGPR = storageLength.gpr();
+        
+        StorageOperand storage(this, node->child3());
+        GPRReg storageGPR = storage.gpr();
+        
+        switch (node->arrayMode().type()) {
+        case Array::Int32: {
+            SpeculateInt32Operand value(this, node->child2());
+            GPRReg valuePayloadGPR = value.gpr();
+            
+            m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
+            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
+            m_jit.store32(TrustedImm32(JSValue::Int32Tag), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+            m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+            m_jit.add32(TrustedImm32(1), storageLengthGPR);
+            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+            m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
+            
+            addSlowPathGenerator(
+                slowPathCall(
+                    slowPath, this, operationArrayPush,
+                    JSValueRegs(storageGPR, storageLengthGPR),
+                    TrustedImm32(JSValue::Int32Tag), valuePayloadGPR, baseGPR));
+        
+            jsValueResult(storageGPR, storageLengthGPR, node);
+            break;
+        }
+            
+        case Array::Contiguous: {
+            JSValueOperand value(this, node->child2());
+            GPRReg valueTagGPR = value.tagGPR();
+            GPRReg valuePayloadGPR = value.payloadGPR();
+
+            m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
+            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
+            m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+            m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+            m_jit.add32(TrustedImm32(1), storageLengthGPR);
+            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+            m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
+            
+            addSlowPathGenerator(
+                slowPathCall(
+                    slowPath, this, operationArrayPush,
+                    JSValueRegs(storageGPR, storageLengthGPR),
+                    JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
+        
+            jsValueResult(storageGPR, storageLengthGPR, node);
+            break;
+        }
+            
+        case Array::Double: {
+            SpeculateDoubleOperand value(this, node->child2());
+            FPRReg valueFPR = value.fpr();
+
+            DFG_TYPE_CHECK(
+                JSValueRegs(), node->child2(), SpecDoubleReal,
+                m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
+            
+            m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
+            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
+            m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
+            m_jit.add32(TrustedImm32(1), storageLengthGPR);
+            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+            m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
+            
+            addSlowPathGenerator(
+                slowPathCall(
+                    slowPath, this, operationArrayPushDouble,
+                    JSValueRegs(storageGPR, storageLengthGPR),
+                    valueFPR, baseGPR));
+        
+            jsValueResult(storageGPR, storageLengthGPR, node);
+            break;
+        }
+            
+        case Array::ArrayStorage: {
+            JSValueOperand value(this, node->child2());
+            GPRReg valueTagGPR = value.tagGPR();
+            GPRReg valuePayloadGPR = value.payloadGPR();
+
+            m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
+        
+            // Refuse to handle bizarre lengths.
+            speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
+        
+            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
+        
+            m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+            m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+        
+            m_jit.add32(TrustedImm32(1), storageLengthGPR);
+            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
+            m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+            m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
+        
+            addSlowPathGenerator(slowPathCall(slowPath, this, operationArrayPush, JSValueRegs(storageGPR, storageLengthGPR),
+                JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
+        
+            jsValueResult(storageGPR, storageLengthGPR, node);
+            break;
+        }
+            
+        default:
+            CRASH();
+            break;
+        }
         break;
     }
         

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -3663,7 +3663,101 @@
     }
         
     case ArrayPush: {
-        compileArrayPush(node);
+        ASSERT(node->arrayMode().isJSArray());
+        
+        SpeculateCellOperand base(this, node->child1());
+        GPRTemporary storageLength(this);
+        
+        GPRReg baseGPR = base.gpr();
+        GPRReg storageLengthGPR = storageLength.gpr();
+        
+        StorageOperand storage(this, node->child3());
+        GPRReg storageGPR = storage.gpr();
+
+        switch (node->arrayMode().type()) {
+        case Array::Int32:
+        case Array::Contiguous: {
+            JSValueOperand value(this, node->child2(), ManualOperandSpeculation);
+            GPRReg valueGPR = value.gpr();
+
+            if (node->arrayMode().type() == Array::Int32) {
+                DFG_TYPE_CHECK(
+                    JSValueRegs(valueGPR), node->child2(), SpecInt32Only,
+                    m_jit.branch64(
+                        MacroAssembler::Below, valueGPR, GPRInfo::tagTypeNumberRegister));
+            }
+
+            m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
+            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
+            m_jit.store64(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
+            m_jit.add32(TrustedImm32(1), storageLengthGPR);
+            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+            m_jit.or64(GPRInfo::tagTypeNumberRegister, storageLengthGPR);
+            
+            addSlowPathGenerator(
+                slowPathCall(
+                    slowPath, this, operationArrayPush, storageLengthGPR,
+                    valueGPR, baseGPR));
+        
+            jsValueResult(storageLengthGPR, node);
+            break;
+        }
+            
+        case Array::Double: {
+            SpeculateDoubleOperand value(this, node->child2());
+            FPRReg valueFPR = value.fpr();
+
+            DFG_TYPE_CHECK(
+                JSValueRegs(), node->child2(), SpecDoubleReal,
+                m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
+            
+            m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
+            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
+            m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
+            m_jit.add32(TrustedImm32(1), storageLengthGPR);
+            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+            m_jit.or64(GPRInfo::tagTypeNumberRegister, storageLengthGPR);
+            
+            addSlowPathGenerator(
+                slowPathCall(
+                    slowPath, this, operationArrayPushDouble, storageLengthGPR,
+                    valueFPR, baseGPR));
+        
+            jsValueResult(storageLengthGPR, node);
+            break;
+        }
+            
+        case Array::ArrayStorage: {
+            JSValueOperand value(this, node->child2());
+            GPRReg valueGPR = value.gpr();
+
+            m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
+        
+            // Refuse to handle bizarre lengths.
+            speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
+        
+            MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
+        
+            m_jit.store64(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()));
+        
+            m_jit.add32(TrustedImm32(1), storageLengthGPR);
+            m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
+            m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+            m_jit.or64(GPRInfo::tagTypeNumberRegister, storageLengthGPR);
+        
+            addSlowPathGenerator(
+                slowPathCall(
+                    slowPath, this, operationArrayPush, NoResult, storageLengthGPR,
+                    valueGPR, baseGPR));
+        
+            jsValueResult(storageLengthGPR, node);
+            break;
+        }
+            
+        default:
+            CRASH();
+            break;
+        }
         break;
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -250,16 +250,9 @@
             case ArrayPush: {
                 switch (m_node->arrayMode().type()) {
                 case Array::Contiguous:
-                case Array::ArrayStorage: {
-                    unsigned elementOffset = 2;
-                    unsigned elementCount = m_node->numChildren() - elementOffset;
-                    Edge& arrayEdge = m_graph.varArgChild(m_node, 1);
-                    for (unsigned i = 0; i < elementCount; ++i) {
-                        Edge& element = m_graph.varArgChild(m_node, i + elementOffset);
-                        considerBarrier(arrayEdge, element);
-                    }
+                case Array::ArrayStorage:
+                    considerBarrier(m_node->child1(), m_node->child2());
                     break;
-                }
                 default:
                     break;
                 }

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -4088,134 +4088,68 @@
     
     void compileArrayPush()
     {
-        LValue base = lowCell(m_graph.varArgChild(m_node, 1));
-        LValue storage = lowStorage(m_graph.varArgChild(m_node, 0));
-        unsigned elementOffset = 2;
-        unsigned elementCount = m_node->numChildren() - elementOffset;
-
+        LValue base = lowCell(m_node->child1());
+        LValue storage = lowStorage(m_node->child3());
+        
         switch (m_node->arrayMode().type()) {
         case Array::Int32:
         case Array::Contiguous:
         case Array::Double: {
-            IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
-
-            if (elementCount == 1) {
-                LValue value;
-                Output::StoreType storeType;
-                
-                Edge& element = m_graph.varArgChild(m_node, elementOffset);
-                if (m_node->arrayMode().type() != Array::Double) {
-                    value = lowJSValue(element, ManualOperandSpeculation);
-                    if (m_node->arrayMode().type() == Array::Int32)
-                        RELEASE_ASSERT(!m_interpreter.needsTypeCheck(element, SpecInt32Only));
-                    storeType = Output::Store64;
-                } else {
-                    value = lowDouble(element);
-                    RELEASE_ASSERT(!m_interpreter.needsTypeCheck(element, SpecDoubleReal));
-                    storeType = Output::StoreDouble;
+            LValue value;
+            Output::StoreType storeType;
+            
+            if (m_node->arrayMode().type() != Array::Double) {
+                value = lowJSValue(m_node->child2(), ManualOperandSpeculation);
+                if (m_node->arrayMode().type() == Array::Int32) {
+                    FTL_TYPE_CHECK(
+                        jsValueValue(value), m_node->child2(), SpecInt32Only, isNotInt32(value));
                 }
-
-                LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
-                
-                LBasicBlock fastPath = m_out.newBlock();
-                LBasicBlock slowPath = m_out.newBlock();
-                LBasicBlock continuation = m_out.newBlock();
-                
-                m_out.branch(
-                    m_out.aboveOrEqual(
-                        prevLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength)),
-                    unsure(slowPath), unsure(fastPath));
-                
-                LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
-                m_out.store(
-                    value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), storeType);
-                LValue newLength = m_out.add(prevLength, m_out.int32One);
-                m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
-                
-                ValueFromBlock fastResult = m_out.anchor(boxInt32(newLength));
-                m_out.jump(continuation);
-                
-                m_out.appendTo(slowPath, continuation);
-                LValue operation;
-                if (m_node->arrayMode().type() != Array::Double)
-                    operation = m_out.operation(operationArrayPush);
-                else
-                    operation = m_out.operation(operationArrayPushDouble);
-                ValueFromBlock slowResult = m_out.anchor(
-                    vmCall(Int64, operation, m_callFrame, value, base));
-                m_out.jump(continuation);
-                
-                m_out.appendTo(continuation, lastNext);
-                setJSValue(m_out.phi(Int64, fastResult, slowResult));
-                return;
+                storeType = Output::Store64;
+            } else {
+                value = lowDouble(m_node->child2());
+                FTL_TYPE_CHECK(
+                    doubleValue(value), m_node->child2(), SpecDoubleReal,
+                    m_out.doubleNotEqualOrUnordered(value, value));
+                storeType = Output::StoreDouble;
             }
+            
+            IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
 
             LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
-            LValue newLength = m_out.add(prevLength, m_out.constInt32(elementCount));
-
+            
             LBasicBlock fastPath = m_out.newBlock();
             LBasicBlock slowPath = m_out.newBlock();
-            LBasicBlock setup = m_out.newBlock();
-            LBasicBlock slowCallPath = m_out.newBlock();
             LBasicBlock continuation = m_out.newBlock();
-
-            LValue beyondVectorLength = m_out.above(newLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength));
-
-            m_out.branch(beyondVectorLength, unsure(slowPath), unsure(fastPath));
-
+            
+            m_out.branch(
+                m_out.aboveOrEqual(
+                    prevLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength)),
+                unsure(slowPath), unsure(fastPath));
+            
             LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
+            m_out.store(
+                value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), storeType);
+            LValue newLength = m_out.add(prevLength, m_out.int32One);
             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
-            ValueFromBlock fastBufferResult = m_out.anchor(m_out.baseIndex(storage, m_out.zeroExtPtr(prevLength), ScaleEight));
-            m_out.jump(setup);
-
-            m_out.appendTo(slowPath, setup);
-            size_t scratchSize = sizeof(EncodedJSValue) * elementCount;
-            static_assert(sizeof(EncodedJSValue) == sizeof(double), "");
-            ASSERT(scratchSize);
-            ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
-            m_out.storePtr(m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength()));
-            ValueFromBlock slowBufferResult = m_out.anchor(m_out.constIntPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())));
-            m_out.jump(setup);
-
-            m_out.appendTo(setup, slowCallPath);
-            LValue buffer = m_out.phi(pointerType(), fastBufferResult, slowBufferResult);
-            for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
-                Edge& element = m_graph.varArgChild(m_node, elementIndex + elementOffset);
-
-                LValue value;
-                Output::StoreType storeType;
-                if (m_node->arrayMode().type() != Array::Double) {
-                    value = lowJSValue(element, ManualOperandSpeculation);
-                    if (m_node->arrayMode().type() == Array::Int32)
-                        RELEASE_ASSERT(!m_interpreter.needsTypeCheck(element, SpecInt32Only));
-                    storeType = Output::Store64;
-                } else {
-                    value = lowDouble(element);
-                    RELEASE_ASSERT(!m_interpreter.needsTypeCheck(element, SpecDoubleReal));
-                    storeType = Output::StoreDouble;
-                }
-
-                m_out.store(value, m_out.baseIndex(heap, buffer, m_out.constInt32(elementIndex), jsNumber(elementIndex)), storeType);
-            }
+            
             ValueFromBlock fastResult = m_out.anchor(boxInt32(newLength));
-
-            m_out.branch(beyondVectorLength, unsure(slowCallPath), unsure(continuation));
-
-            m_out.appendTo(slowCallPath, continuation);
+            m_out.jump(continuation);
+            
+            m_out.appendTo(slowPath, continuation);
             LValue operation;
             if (m_node->arrayMode().type() != Array::Double)
-                operation = m_out.operation(operationArrayPushMultiple);
+                operation = m_out.operation(operationArrayPush);
             else
-                operation = m_out.operation(operationArrayPushDoubleMultiple);
-            ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, operation, m_callFrame, base, buffer, m_out.constInt32(elementCount)));
-            m_out.storePtr(m_out.constIntPtr(0), m_out.absolute(scratchBuffer->addressOfActiveLength()));
+                operation = m_out.operation(operationArrayPushDouble);
+            ValueFromBlock slowResult = m_out.anchor(
+                vmCall(Int64, operation, m_callFrame, value, base));
             m_out.jump(continuation);
-
+            
             m_out.appendTo(continuation, lastNext);
             setJSValue(m_out.phi(Int64, fastResult, slowResult));
             return;
         }
-
+            
         default:
             DFG_CRASH(m_graph, m_node, "Bad array type");
             return;

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (222657 => 222658)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2017-09-29 18:49:37 UTC (rev 222658)
@@ -141,7 +141,6 @@
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJC)(ExecState*, EncodedJSValue, JSCell*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJA)(ExecState*, EncodedJSValue, JSArray*);
-typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EAPZ)(ExecState*, JSArray*, void*, int32_t);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJArp)(ExecState*, EncodedJSValue, ArithProfile*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJI)(ExecState*, EncodedJSValue, UniquedStringImpl*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);

Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -764,10 +764,10 @@
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
 
-    if (LIKELY(isJSArray(thisValue) && exec->argumentCount() == 1)) {
+    if (isJSArray(thisValue) && exec->argumentCount() == 1) {
         JSArray* array = asArray(thisValue);
         scope.release();
-        array->pushInline(exec, exec->uncheckedArgument(0));
+        array->push(exec, exec->uncheckedArgument(0));
         return JSValue::encode(jsNumber(array->length()));
     }
     

Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (222657 => 222658)


--- trunk/Source/_javascript_Core/runtime/JSArray.cpp	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp	2017-09-29 18:49:37 UTC (rev 222658)
@@ -40,7 +40,7 @@
 
 namespace JSC {
 
-const char* const LengthExceededTheMaximumArrayLengthError = "Length exceeded the maximum array length";
+static const char* const LengthExceededTheMaximumArrayLengthError = "Length exceeded the maximum array length";
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSArray);
 
@@ -725,9 +725,153 @@
 // Push & putIndex are almost identical, with two small differences.
 //  - we always are writing beyond the current array bounds, so it is always necessary to update m_length & m_numValuesInVector.
 //  - pushing to an array of length 2^32-1 stores the property, but throws a range error.
-NEVER_INLINE void JSArray::push(ExecState* exec, JSValue value)
+void JSArray::push(ExecState* exec, JSValue value)
 {
-    pushInline(exec, value);
+    VM& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    Butterfly* butterfly = m_butterfly.getMayBeNull();
+    
+    switch (indexingType()) {
+    case ArrayClass: {
+        createInitialUndecided(vm, 0);
+        FALLTHROUGH;
+    }
+        
+    case ArrayWithUndecided: {
+        convertUndecidedForValue(vm, value);
+        scope.release();
+        push(exec, value);
+        return;
+    }
+        
+    case ArrayWithInt32: {
+        if (!value.isInt32()) {
+            convertInt32ForValue(vm, value);
+            scope.release();
+            push(exec, value);
+            return;
+        }
+
+        unsigned length = butterfly->publicLength();
+        ASSERT(length <= butterfly->vectorLength());
+        if (length < butterfly->vectorLength()) {
+            butterfly->contiguousInt32()[length].setWithoutWriteBarrier(value);
+            butterfly->setPublicLength(length + 1);
+            return;
+        }
+        
+        if (UNLIKELY(length > MAX_ARRAY_INDEX)) {
+            methodTable(vm)->putByIndex(this, exec, length, value, true);
+            if (!scope.exception())
+                throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError)));
+            return;
+        }
+
+        scope.release();
+        putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, length, value);
+        return;
+    }
+
+    case ArrayWithContiguous: {
+        unsigned length = butterfly->publicLength();
+        ASSERT(length <= butterfly->vectorLength());
+        if (length < butterfly->vectorLength()) {
+            butterfly->contiguous()[length].set(vm, this, value);
+            butterfly->setPublicLength(length + 1);
+            return;
+        }
+        
+        if (UNLIKELY(length > MAX_ARRAY_INDEX)) {
+            methodTable(vm)->putByIndex(this, exec, length, value, true);
+            if (!scope.exception())
+                throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError)));
+            return;
+        }
+
+        scope.release();
+        putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, length, value);
+        return;
+    }
+        
+    case ArrayWithDouble: {
+        if (!value.isNumber()) {
+            convertDoubleToContiguous(vm);
+            scope.release();
+            push(exec, value);
+            return;
+        }
+        double valueAsDouble = value.asNumber();
+        if (valueAsDouble != valueAsDouble) {
+            convertDoubleToContiguous(vm);
+            scope.release();
+            push(exec, value);
+            return;
+        }
+
+        unsigned length = butterfly->publicLength();
+        ASSERT(length <= butterfly->vectorLength());
+        if (length < butterfly->vectorLength()) {
+            butterfly->contiguousDouble()[length] = valueAsDouble;
+            butterfly->setPublicLength(length + 1);
+            return;
+        }
+        
+        if (UNLIKELY(length > MAX_ARRAY_INDEX)) {
+            methodTable(vm)->putByIndex(this, exec, length, value, true);
+            if (!scope.exception())
+                throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError)));
+            return;
+        }
+
+        scope.release();
+        putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, length, value);
+        return;
+    }
+        
+    case ArrayWithSlowPutArrayStorage: {
+        unsigned oldLength = length();
+        bool putResult = false;
+        if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true, putResult)) {
+            if (!scope.exception() && oldLength < 0xFFFFFFFFu) {
+                scope.release();
+                setLength(exec, oldLength + 1, true);
+            }
+            return;
+        }
+        FALLTHROUGH;
+    }
+        
+    case ArrayWithArrayStorage: {
+        ArrayStorage* storage = butterfly->arrayStorage();
+
+        // Fast case - push within vector, always update m_length & m_numValuesInVector.
+        unsigned length = storage->length();
+        if (length < storage->vectorLength()) {
+            storage->m_vector[length].set(vm, this, value);
+            storage->setLength(length + 1);
+            ++storage->m_numValuesInVector;
+            return;
+        }
+
+        // Pushing to an array of invalid length (2^31-1) stores the property, but throws a range error.
+        if (UNLIKELY(storage->length() > MAX_ARRAY_INDEX)) {
+            methodTable(vm)->putByIndex(this, exec, storage->length(), value, true);
+            // Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d.
+            if (!scope.exception())
+                throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError)));
+            return;
+        }
+
+        // Handled the same as putIndex.
+        scope.release();
+        putByIndexBeyondVectorLengthWithArrayStorage(exec, storage->length(), value, true, storage);
+        return;
+    }
+        
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
 }
 
 JSArray* JSArray::fastSlice(ExecState& exec, unsigned startIndex, unsigned count)

Modified: trunk/Source/_javascript_Core/runtime/JSArray.h (222657 => 222658)


--- trunk/Source/_javascript_Core/runtime/JSArray.h	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/runtime/JSArray.h	2017-09-29 18:49:37 UTC (rev 222658)
@@ -31,8 +31,6 @@
 class JSArray;
 class LLIntOffsetsExtractor;
 
-extern const char* const LengthExceededTheMaximumArrayLengthError;
-
 class JSArray : public JSNonFinalObject {
     friend class LLIntOffsetsExtractor;
     friend class Walker;
@@ -92,7 +90,6 @@
     // OK to use on new arrays, but not if it might be a RegExpMatchArray or RuntimeArray.
     JS_EXPORT_PRIVATE bool setLength(ExecState*, unsigned, bool throwException = false);
 
-    void pushInline(ExecState*, JSValue);
     JS_EXPORT_PRIVATE void push(ExecState*, JSValue);
     JS_EXPORT_PRIVATE JSValue pop(ExecState*);
 

Modified: trunk/Source/_javascript_Core/runtime/JSArrayInlines.h (222657 => 222658)


--- trunk/Source/_javascript_Core/runtime/JSArrayInlines.h	2017-09-29 18:48:30 UTC (rev 222657)
+++ trunk/Source/_javascript_Core/runtime/JSArrayInlines.h	2017-09-29 18:49:37 UTC (rev 222658)
@@ -19,7 +19,6 @@
 
 #pragma once
 
-#include "Error.h"
 #include "JSArray.h"
 #include "JSCellInlines.h"
 #include "Structure.h"
@@ -83,153 +82,4 @@
     return lengthValue.toLength(exec);
 }
 
-ALWAYS_INLINE void JSArray::pushInline(ExecState* exec, JSValue value)
-{
-    VM& vm = exec->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    Butterfly* butterfly = m_butterfly.getMayBeNull();
-
-    switch (indexingType()) {
-    case ArrayClass: {
-        createInitialUndecided(vm, 0);
-        FALLTHROUGH;
-    }
-
-    case ArrayWithUndecided: {
-        convertUndecidedForValue(vm, value);
-        scope.release();
-        push(exec, value);
-        return;
-    }
-
-    case ArrayWithInt32: {
-        if (!value.isInt32()) {
-            convertInt32ForValue(vm, value);
-            scope.release();
-            push(exec, value);
-            return;
-        }
-
-        unsigned length = butterfly->publicLength();
-        ASSERT(length <= butterfly->vectorLength());
-        if (length < butterfly->vectorLength()) {
-            butterfly->contiguousInt32()[length].setWithoutWriteBarrier(value);
-            butterfly->setPublicLength(length + 1);
-            return;
-        }
-
-        if (UNLIKELY(length > MAX_ARRAY_INDEX)) {
-            methodTable(vm)->putByIndex(this, exec, length, value, true);
-            if (!scope.exception())
-                throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError)));
-            return;
-        }
-
-        scope.release();
-        putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, length, value);
-        return;
-    }
-
-    case ArrayWithContiguous: {
-        unsigned length = butterfly->publicLength();
-        ASSERT(length <= butterfly->vectorLength());
-        if (length < butterfly->vectorLength()) {
-            butterfly->contiguous()[length].set(vm, this, value);
-            butterfly->setPublicLength(length + 1);
-            return;
-        }
-
-        if (UNLIKELY(length > MAX_ARRAY_INDEX)) {
-            methodTable(vm)->putByIndex(this, exec, length, value, true);
-            if (!scope.exception())
-                throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError)));
-            return;
-        }
-
-        scope.release();
-        putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, length, value);
-        return;
-    }
-
-    case ArrayWithDouble: {
-        if (!value.isNumber()) {
-            convertDoubleToContiguous(vm);
-            scope.release();
-            push(exec, value);
-            return;
-        }
-        double valueAsDouble = value.asNumber();
-        if (valueAsDouble != valueAsDouble) {
-            convertDoubleToContiguous(vm);
-            scope.release();
-            push(exec, value);
-            return;
-        }
-
-        unsigned length = butterfly->publicLength();
-        ASSERT(length <= butterfly->vectorLength());
-        if (length < butterfly->vectorLength()) {
-            butterfly->contiguousDouble()[length] = valueAsDouble;
-            butterfly->setPublicLength(length + 1);
-            return;
-        }
-
-        if (UNLIKELY(length > MAX_ARRAY_INDEX)) {
-            methodTable(vm)->putByIndex(this, exec, length, value, true);
-            if (!scope.exception())
-                throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError)));
-            return;
-        }
-
-        scope.release();
-        putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, length, value);
-        return;
-    }
-
-    case ArrayWithSlowPutArrayStorage: {
-        unsigned oldLength = length();
-        bool putResult = false;
-        if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true, putResult)) {
-            if (!scope.exception() && oldLength < 0xFFFFFFFFu) {
-                scope.release();
-                setLength(exec, oldLength + 1, true);
-            }
-            return;
-        }
-        FALLTHROUGH;
-    }
-
-    case ArrayWithArrayStorage: {
-        ArrayStorage* storage = butterfly->arrayStorage();
-
-        // Fast case - push within vector, always update m_length & m_numValuesInVector.
-        unsigned length = storage->length();
-        if (length < storage->vectorLength()) {
-            storage->m_vector[length].set(vm, this, value);
-            storage->setLength(length + 1);
-            ++storage->m_numValuesInVector;
-            return;
-        }
-
-        // Pushing to an array of invalid length (2^31-1) stores the property, but throws a range error.
-        if (UNLIKELY(storage->length() > MAX_ARRAY_INDEX)) {
-            methodTable(vm)->putByIndex(this, exec, storage->length(), value, true);
-            // Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d.
-            if (!scope.exception())
-                throwException(exec, scope, createRangeError(exec, ASCIILiteral(LengthExceededTheMaximumArrayLengthError)));
-            return;
-        }
-
-        // Handled the same as putIndex.
-        scope.release();
-        putByIndexBeyondVectorLengthWithArrayStorage(exec, storage->length(), value, true, storage);
-        return;
-    }
-
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-}
-
 } // namespace JSC
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to