Title: [171214] branches/ftlopt/Source/_javascript_Core
Revision
171214
Author
[email protected]
Date
2014-07-17 22:55:26 -0700 (Thu, 17 Jul 2014)

Log Message

[ftlopt] DFG Flush(SetLocal) store elimination is overzealous for captured variables in the presence of nodes that have no effects but may throw (merge trunk r171190)
https://bugs.webkit.org/show_bug.cgi?id=135019

Reviewed by Oliver Hunt.
        
Behaviorally, this is just a merge of trunk r171190, except that the relevant functionality
has moved to StrengthReductionPhase and is written in a different style. Same algorithm,
different code.

* dfg/DFGNodeType.h:
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* tests/stress/capture-escape-and-throw.js: Added.
(foo.f):
(foo):
* tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js: Added.
(foo):
(bar):

Modified Paths

Added Paths

Diff

Modified: branches/ftlopt/Source/_javascript_Core/ChangeLog (171213 => 171214)


--- branches/ftlopt/Source/_javascript_Core/ChangeLog	2014-07-18 04:34:16 UTC (rev 171213)
+++ branches/ftlopt/Source/_javascript_Core/ChangeLog	2014-07-18 05:55:26 UTC (rev 171214)
@@ -1,3 +1,24 @@
+2014-07-17  Filip Pizlo  <[email protected]>
+
+        [ftlopt] DFG Flush(SetLocal) store elimination is overzealous for captured variables in the presence of nodes that have no effects but may throw (merge trunk r171190)
+        https://bugs.webkit.org/show_bug.cgi?id=135019
+
+        Reviewed by Oliver Hunt.
+        
+        Behaviorally, this is just a merge of trunk r171190, except that the relevant functionality
+        has moved to StrengthReductionPhase and is written in a different style. Same algorithm,
+        different code.
+
+        * dfg/DFGNodeType.h:
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * tests/stress/capture-escape-and-throw.js: Added.
+        (foo.f):
+        (foo):
+        * tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js: Added.
+        (foo):
+        (bar):
+
 2014-07-15  Filip Pizlo  <[email protected]>
 
         [ftlopt] Constant fold GetGetter and GetSetter if the GetterSetter is a constant

Modified: branches/ftlopt/Source/_javascript_Core/dfg/DFGNodeType.h (171213 => 171214)


--- branches/ftlopt/Source/_javascript_Core/dfg/DFGNodeType.h	2014-07-18 04:34:16 UTC (rev 171213)
+++ branches/ftlopt/Source/_javascript_Core/dfg/DFGNodeType.h	2014-07-18 05:55:26 UTC (rev 171214)
@@ -216,7 +216,7 @@
     /* Allocations. */\
     macro(NewObject, NodeResultJS) \
     macro(NewArray, NodeResultJS | NodeHasVarArgs) \
-    macro(NewArrayWithSize, NodeResultJS) \
+    macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \
     macro(NewArrayBuffer, NodeResultJS) \
     macro(NewTypedArray, NodeResultJS | NodeClobbersWorld | NodeMustGenerate) \
     macro(NewRegexp, NodeResultJS) \

Modified: branches/ftlopt/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (171213 => 171214)


--- branches/ftlopt/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp	2014-07-18 04:34:16 UTC (rev 171213)
+++ branches/ftlopt/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp	2014-07-18 05:55:26 UTC (rev 171214)
@@ -221,14 +221,56 @@
             Node* setLocal = nullptr;
             VirtualRegister local = m_node->local();
             
-            for (unsigned i = m_nodeIndex; i--;) {
-                Node* node = m_block->at(i);
-                if (node->op() == SetLocal && node->local() == local) {
-                    setLocal = node;
-                    break;
+            if (m_node->variableAccessData()->isCaptured()) {
+                for (unsigned i = m_nodeIndex; i--;) {
+                    Node* node = m_block->at(i);
+                    bool done = false;
+                    switch (node->op()) {
+                    case GetLocal:
+                    case Flush:
+                        if (node->local() == local)
+                            done = true;
+                        break;
+                
+                    case GetLocalUnlinked:
+                        if (node->unlinkedLocal() == local)
+                            done = true;
+                        break;
+                
+                    case SetLocal: {
+                        if (node->local() != local)
+                            break;
+                        setLocal = node;
+                        done = true;
+                        break;
+                    }
+                
+                    case Phantom:
+                    case Check:
+                    case HardPhantom:
+                    case MovHint:
+                    case JSConstant:
+                    case DoubleConstant:
+                    case Int52Constant:
+                        break;
+                
+                    default:
+                        done = true;
+                        break;
+                    }
+                    if (done)
+                        break;
                 }
-                if (accessesOverlap(m_graph, node, AbstractHeap(Variables, local)))
-                    break;
+            } else {
+                for (unsigned i = m_nodeIndex; i--;) {
+                    Node* node = m_block->at(i);
+                    if (node->op() == SetLocal && node->local() == local) {
+                        setLocal = node;
+                        break;
+                    }
+                    if (accessesOverlap(m_graph, node, AbstractHeap(Variables, local)))
+                        break;
+                }
             }
             
             if (!setLocal)

Added: branches/ftlopt/Source/_javascript_Core/tests/stress/capture-escape-and-throw.js (0 => 171214)


--- branches/ftlopt/Source/_javascript_Core/tests/stress/capture-escape-and-throw.js	                        (rev 0)
+++ branches/ftlopt/Source/_javascript_Core/tests/stress/capture-escape-and-throw.js	2014-07-18 05:55:26 UTC (rev 171214)
@@ -0,0 +1,28 @@
+var f;
+
+function foo(s) {
+    var x = 1;
+    f = function() { return x; };
+    x = 2;
+    new Array(s);
+    x = 3;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i)
+    foo(1);
+
+var didThrow = false;
+try {
+    foo(-1);
+} catch (e) {
+    didThrow = e;
+}
+
+if (("" + didThrow).indexOf("RangeError") != 0)
+    throw "Error: did not throw right exception: " + didThrow;
+
+var result = f();
+if (result != 2)
+    throw "Error: bad result from f(): " + result;

Added: branches/ftlopt/Source/_javascript_Core/tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js (0 => 171214)


--- branches/ftlopt/Source/_javascript_Core/tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js	                        (rev 0)
+++ branches/ftlopt/Source/_javascript_Core/tests/stress/new-array-with-size-throw-exception-and-tear-off-arguments.js	2014-07-18 05:55:26 UTC (rev 171214)
@@ -0,0 +1,26 @@
+function foo() {
+    var a = arguments;
+    return new Array(a[0]);
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(42);
+    if (result.length != 42)
+        throw "Error: bad result length: " + result;
+}
+
+var didThrow = false;
+try {
+    bar(-1);
+} catch (e) {
+    didThrow = e;
+}
+
+if (("" + didThrow).indexOf("RangeError") != 0)
+    throw "Error: did not throw right exception: " + didThrow;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to