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