FTL should not flush strict arguments unless it really needs to
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Mar 2017 18:00:25 +0000 (18:00 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Mar 2017 18:00:25 +0000 (18:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169519

Reviewed by Mark Lam.

JSTests:

This benchmark runs 3.5x faster thanks to this patch.

* microbenchmarks/strict-arguments-no-escape.js: Added.
(foo):
(bar):
(baz):

Source/JavaScriptCore:

This is a refinement that we should have done ages ago. This kills some pointless PutStacks
in DFG SSA IR. It can sometimes unlock other optimizations.

* dfg/DFGPreciseLocalClobberize.h:
(JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213856 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/microbenchmarks/strict-arguments-no-escape.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h

index f138ad9..5bbc211 100644 (file)
@@ -1,3 +1,17 @@
+2017-03-11  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should not flush strict arguments unless it really needs to
+        https://bugs.webkit.org/show_bug.cgi?id=169519
+
+        Reviewed by Mark Lam.
+        
+        This benchmark runs 3.5x faster thanks to this patch.
+
+        * microbenchmarks/strict-arguments-no-escape.js: Added.
+        (foo):
+        (bar):
+        (baz):
+
 2017-03-13  Caio Lima  <ticaiolima@gmail.com>
 
         [JSC] It should be possible create a label named let when parsing Statement in non strict mode
diff --git a/JSTests/microbenchmarks/strict-arguments-no-escape.js b/JSTests/microbenchmarks/strict-arguments-no-escape.js
new file mode 100644 (file)
index 0000000..1f939bf
--- /dev/null
@@ -0,0 +1,26 @@
+"use strict";
+
+function foo()
+{
+}
+
+noInline(foo);
+
+function bar(o)
+{
+    foo();
+    return o.f.f.f.f.f;
+}
+
+function baz()
+{
+    for (var i = 0; i < 100; ++i) {
+        if (bar({f: {f: {f: {f: {f: 42}}}}}) != 42)
+            throw "Error: bad result: " + result;
+    }
+}
+
+noInline(baz);
+
+for (var i = 0; i < 20000; ++i)
+    baz();
index 4eafa8f..2211734 100644 (file)
@@ -1,3 +1,16 @@
+2017-03-11  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should not flush strict arguments unless it really needs to
+        https://bugs.webkit.org/show_bug.cgi?id=169519
+
+        Reviewed by Mark Lam.
+        
+        This is a refinement that we should have done ages ago. This kills some pointless PutStacks
+        in DFG SSA IR. It can sometimes unlock other optimizations.
+
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+
 2017-03-13  Caio Lima  <ticaiolima@gmail.com>
 
         [JSC] It should be possible create a label named let when parsing Statement in non strict mode
index baf0ad9..6697974 100644 (file)
@@ -197,9 +197,11 @@ private:
 
             
         default: {
-            // All of the outermost arguments, except this, are definitely read.
-            for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;)
-                m_read(virtualRegisterForArgument(i));
+            // All of the outermost arguments, except this, are read in sloppy mode.
+            if (!m_graph.m_codeBlock->isStrictMode()) {
+                for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;)
+                    m_read(virtualRegisterForArgument(i));
+            }
         
             // The stack header is read.
             for (unsigned i = 0; i < CallFrameSlot::thisArgument; ++i)
@@ -207,8 +209,10 @@ private:
         
             // Read all of the inline arguments and call frame headers that we didn't already capture.
             for (InlineCallFrame* inlineCallFrame = m_node->origin.semantic.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->getCallerInlineFrameSkippingTailCalls()) {
-                for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;)
-                    m_read(VirtualRegister(inlineCallFrame->stackOffset + virtualRegisterForArgument(i).offset()));
+                if (!inlineCallFrame->isStrictMode()) {
+                    for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;)
+                        m_read(VirtualRegister(inlineCallFrame->stackOffset + virtualRegisterForArgument(i).offset()));
+                }
                 if (inlineCallFrame->isClosureCall)
                     m_read(VirtualRegister(inlineCallFrame->stackOffset + CallFrameSlot::callee));
                 if (inlineCallFrame->isVarargs())