Strange bug in DFG OSR in JSC
https://bugs.webkit.org/show_bug.cgi?id=109491
Source/JavaScriptCore:
Reviewed by Mark Hahnenberg.
Int32ToDouble was being injected after a side-effecting operation and before a SetLocal. Anytime we
inject something just before a SetLocal we should be aware that the previous operation may have been
a side-effect associated with the current code origin. Hence, we should use a forward exit.
Int32ToDouble does not do forward exits by default.
This patch adds a forward-exiting form of Int32ToDouble, for use in SetLocal Int32ToDouble injections.
Changed the CSE and other things to treat these nodes identically, but for the exit strategy to be
distinct (Int32ToDouble -> backward, ForwardInt32ToDouble -> forward). The use of the NodeType for
signaling exit direction is not "great" but it's what we use in other places already (like
ForwardCheckStructure).
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::int32ToDoubleCSE):
(CSEPhase):
(JSC::DFG::CSEPhase::performNodeCSE):
* dfg/DFGCommon.h:
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixDoubleEdge):
(JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::willHaveCodeGenOrOSR):
* dfg/DFGNodeType.h:
(DFG):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
(JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGVariableEventStream.cpp:
(JSC::DFG::VariableEventStream::reconstruct):
LayoutTests:
Reviewed by Mark Hahnenberg.
Added one version of the test (dfg-int32-to-double-on-set-local-and-exit) that is based
exactly on Gabor's original test, and another that ought to fail even if I fix other bugs
in the future (see https://bugs.webkit.org/show_bug.cgi?id=109511).
* fast/js/dfg-int32-to-double-on-set-local-and-exit-expected.txt: Added.
* fast/js/dfg-int32-to-double-on-set-local-and-exit.html: Added.
* fast/js/dfg-int32-to-double-on-set-local-and-sometimes-exit-expected.txt: Added.
* fast/js/dfg-int32-to-double-on-set-local-and-sometimes-exit.html: Added.
* fast/js/script-tests/dfg-int32-to-double-on-set-local-and-exit.js: Added.
(checkpoint):
(func1):
(func2):
(func3):
(test):
* fast/js/script-tests/dfg-int32-to-double-on-set-local-and-sometimes-exit.js: Added.
(checkpoint):
(func1):
(func2):
(func3):
(test):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@142544 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 0217665..1a93765 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -252,7 +252,7 @@
break;
if (!node->variableAccessData()->shouldUseDoubleFormat())
break;
- fixDoubleEdge(0);
+ fixDoubleEdge(0, ForwardSpeculation);
break;
}
@@ -508,7 +508,7 @@
edge = newEdge;
}
- void fixDoubleEdge(unsigned childIndex)
+ void fixDoubleEdge(unsigned childIndex, SpeculationDirection direction = BackwardSpeculation)
{
Node* source = m_currentNode;
Edge& edge = m_graph.child(source, childIndex);
@@ -518,13 +518,14 @@
return;
}
- injectInt32ToDoubleNode(childIndex);
+ injectInt32ToDoubleNode(childIndex, direction);
}
- void injectInt32ToDoubleNode(unsigned childIndex)
+ void injectInt32ToDoubleNode(unsigned childIndex, SpeculationDirection direction = BackwardSpeculation)
{
Node* result = m_insertionSet.insertNode(
- m_indexInBlock, DontRefChildren, RefNode, SpecDouble, Int32ToDouble,
+ m_indexInBlock, DontRefChildren, RefNode, SpecDouble,
+ direction == BackwardSpeculation ? Int32ToDouble : ForwardInt32ToDouble,
m_currentNode->codeOrigin, m_graph.child(m_currentNode, childIndex).node());
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)