Title: [147582] branches/dfgFourthTier/Source/_javascript_Core
Revision
147582
Author
fpi...@apple.com
Date
2013-04-03 13:57:11 -0700 (Wed, 03 Apr 2013)

Log Message

fourthTier: DFG should abstract out how it does forward exits, and that code should be simplified
https://bugs.webkit.org/show_bug.cgi?id=113894

Reviewed by Mark Hahnenberg.
        
1) We previously had two different ways of convertingToForward, one path for
   where we had a ValueRecovery for the current node and one where we didn't.
   But the paths were doing exactly the same thing except that if you have a
   ValueRecovery, you also find the last applicable mov hint and do some
   extra things. This patch combines the two paths and bases both of them on
   the previous no-ValueRecovery path, which was simpler to begin with.
        
2) This moves the logic into DFG::OSRExit, which further simplifies the code
   and makes the logic available to the FTL.

* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::convertToForward):
(DFG):
* dfg/DFGOSRExit.h:
(DFG):
(OSRExit):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):

Modified Paths

Diff

Modified: branches/dfgFourthTier/Source/_javascript_Core/ChangeLog (147581 => 147582)


--- branches/dfgFourthTier/Source/_javascript_Core/ChangeLog	2013-04-03 20:44:22 UTC (rev 147581)
+++ branches/dfgFourthTier/Source/_javascript_Core/ChangeLog	2013-04-03 20:57:11 UTC (rev 147582)
@@ -1,3 +1,29 @@
+2013-04-03  Filip Pizlo  <fpi...@apple.com>
+
+        fourthTier: DFG should abstract out how it does forward exits, and that code should be simplified
+        https://bugs.webkit.org/show_bug.cgi?id=113894
+
+        Reviewed by Mark Hahnenberg.
+        
+        1) We previously had two different ways of convertingToForward, one path for
+           where we had a ValueRecovery for the current node and one where we didn't.
+           But the paths were doing exactly the same thing except that if you have a
+           ValueRecovery, you also find the last applicable mov hint and do some
+           extra things. This patch combines the two paths and bases both of them on
+           the previous no-ValueRecovery path, which was simpler to begin with.
+        
+        2) This moves the logic into DFG::OSRExit, which further simplifies the code
+           and makes the logic available to the FTL.
+
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::OSRExit::convertToForward):
+        (DFG):
+        * dfg/DFGOSRExit.h:
+        (DFG):
+        (OSRExit):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+
 2013-04-02  Filip Pizlo  <fpi...@apple.com>
 
         fourthTier: FTL should have the equivalent of a ValueRecovery

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExit.cpp (147581 => 147582)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2013-04-03 20:44:22 UTC (rev 147581)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2013-04-03 20:57:11 UTC (rev 147582)
@@ -29,6 +29,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGAssemblyHelpers.h"
+#include "DFGGraph.h"
 #include "DFGSpeculativeJIT.h"
 #include "JSCellInlines.h"
 
@@ -89,6 +90,52 @@
     return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOriginForExitProfile, profiledCodeBlock)->addFrequentExitSite(exitSite);
 }
 
+void OSRExit::convertToForward(BasicBlock* block, Node* currentNode, unsigned nodeIndex, const ValueRecovery& valueRecovery)
+{
+    // Check that either the current node is a SetLocal, or the preceding node was a
+    // SetLocal with the same code origin, or that we've provided a valueRecovery.
+    if (!ASSERT_DISABLED
+        && !valueRecovery
+        && !currentNode->containsMovHint()) {
+        Node* setLocal = block->at(nodeIndex - 1);
+        ASSERT_UNUSED(setLocal, setLocal->containsMovHint());
+        ASSERT_UNUSED(setLocal, setLocal->codeOrigin == currentNode->codeOrigin);
+    }
+    
+    // Find the first node for the next bytecode instruction. Also track the last mov hint
+    // on this node.
+    unsigned indexInBlock = nodeIndex + 1;
+    Node* node = 0;
+    Node* lastMovHint = 0;
+    for (;;) {
+        if (indexInBlock == block->size()) {
+            // This is an inline return. Give up and do a backwards speculation. This is safe
+            // because an inline return has its own bytecode index and it's always safe to
+            // reexecute that bytecode.
+            ASSERT(node->op() == Jump);
+            return;
+        }
+        node = block->at(indexInBlock);
+        if (node->containsMovHint() && node->child1() == currentNode)
+            lastMovHint = node;
+        if (node->codeOrigin != currentNode->codeOrigin)
+            break;
+        indexInBlock++;
+    }
+    
+    ASSERT(node->codeOrigin != currentNode->codeOrigin);
+    m_codeOrigin = node->codeOrigin;
+    
+    if (!valueRecovery)
+        return;
+    
+    ASSERT(lastMovHint);
+    ASSERT(lastMovHint->child1() == currentNode);
+    m_lastSetOperand = lastMovHint->local();
+    m_valueRecoveryOverride = adoptRef(
+        new ValueRecoveryOverride(lastMovHint->local(), valueRecovery));
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExit.h (147581 => 147582)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExit.h	2013-04-03 20:44:22 UTC (rev 147581)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExit.h	2013-04-03 20:57:11 UTC (rev 147582)
@@ -45,6 +45,8 @@
 namespace JSC { namespace DFG {
 
 class SpeculativeJIT;
+struct BasicBlock;
+struct Node;
 
 // This enum describes the types of additional recovery that
 // may need be performed should a speculation check fail.
@@ -111,6 +113,8 @@
     MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
     CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
     void correctJump(LinkBuffer&);
+    
+    void convertToForward(BasicBlock*, Node*, unsigned nodeIndex, const ValueRecovery&);
 
     unsigned m_streamIndex;
     int m_lastSetOperand;

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (147581 => 147582)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2013-04-03 20:44:22 UTC (rev 147581)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2013-04-03 20:57:11 UTC (rev 147582)
@@ -223,70 +223,8 @@
 
 void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecovery)
 {
-    if (!valueRecovery) {
-        // Check that either the current node is a SetLocal, or the preceding node was a
-        // SetLocal with the same code origin.
-        if (!m_currentNode->containsMovHint()) {
-            Node* setLocal = m_jit.graph().m_blocks[m_block]->at(m_indexInBlock - 1);
-            ASSERT_UNUSED(setLocal, setLocal->containsMovHint());
-            ASSERT_UNUSED(setLocal, setLocal->codeOrigin == m_currentNode->codeOrigin);
-        }
-        
-        // Find the next node.
-        unsigned indexInBlock = m_indexInBlock + 1;
-        Node* node = 0;
-        for (;;) {
-            if (indexInBlock == m_jit.graph().m_blocks[m_block]->size()) {
-                // This is an inline return. Give up and do a backwards speculation. This is safe
-                // because an inline return has its own bytecode index and it's always safe to
-                // reexecute that bytecode.
-                ASSERT(node->op() == Jump);
-                return;
-            }
-            node = m_jit.graph().m_blocks[m_block]->at(indexInBlock);
-            if (node->codeOrigin != m_currentNode->codeOrigin)
-                break;
-            indexInBlock++;
-        }
-        
-        ASSERT(node->codeOrigin != m_currentNode->codeOrigin);
-        OSRExit& exit = m_jit.codeBlock()->lastOSRExit();
-        exit.m_codeOrigin = node->codeOrigin;
-        return;
-    }
-    
-    unsigned setLocalIndexInBlock = m_indexInBlock + 1;
-    
-    Node* setLocal = m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock);
-    bool hadInt32ToDouble = false;
-    
-    if (setLocal->op() == ForwardInt32ToDouble) {
-        setLocal = m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock);
-        hadInt32ToDouble = true;
-    }
-    if (setLocal->op() == Flush || setLocal->op() == Phantom)
-        setLocal = m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock);
-        
-    if (hadInt32ToDouble)
-        ASSERT(setLocal->child1()->child1() == m_currentNode);
-    else
-        ASSERT(setLocal->child1() == m_currentNode);
-    ASSERT(setLocal->containsMovHint());
-    ASSERT(setLocal->codeOrigin == m_currentNode->codeOrigin);
-
-    Node* nextNode = m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock + 1);
-    if (nextNode->op() == Jump && nextNode->codeOrigin == m_currentNode->codeOrigin) {
-        // We're at an inlined return. Use a backward speculation instead.
-        return;
-    }
-    ASSERT(nextNode->codeOrigin != m_currentNode->codeOrigin);
-        
-    OSRExit& exit = m_jit.codeBlock()->lastOSRExit();
-    exit.m_codeOrigin = nextNode->codeOrigin;
-        
-    exit.m_lastSetOperand = setLocal->local();
-    exit.m_valueRecoveryOverride = adoptRef(
-        new ValueRecoveryOverride(setLocal->local(), valueRecovery));
+    m_jit.codeBlock()->lastOSRExit().convertToForward(
+        m_jit.graph().m_blocks[m_block].get(), m_currentNode, m_indexInBlock, valueRecovery);
 }
 
 void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to