DFG should trigger rage conversion from double to contiguous if it sees a GetByVal on Double being used in an integer context
https://bugs.webkit.org/show_bug.cgi?id=103858
Reviewed by Gavin Barraclough.
A rage conversion from double to contiguous is one where you try to convert each
double to an int32.
This is probably not the last we'll hear of rage conversion from double to contiguous.
It may be better to do this right during parsing, which will result in fewer cases of
Arrayification. But even so, this looks like a straight win already - 1% speed-up on
Kraken, no major regression anywhere else.
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGArrayMode.cpp:
(JSC::DFG::ArrayMode::refine):
(JSC::DFG::arrayConversionToString):
(JSC::DFG::ArrayMode::dump):
(WTF):
(WTF::printInternal):
* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::withConversion):
(ArrayMode):
(JSC::DFG::ArrayMode::doesConversion):
(WTF):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupBlock):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::checkArray):
(FixupPhase):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGNodeFlags.h:
(DFG):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::arrayify):
* dfg/DFGStructureCheckHoistingPhase.cpp:
(JSC::DFG::StructureCheckHoistingPhase::run):
* runtime/JSObject.cpp:
(JSC):
(JSC::JSObject::genericConvertDoubleToContiguous):
(JSC::JSObject::convertDoubleToContiguous):
(JSC::JSObject::rageConvertDoubleToContiguous):
(JSC::JSObject::ensureContiguousSlow):
(JSC::JSObject::rageEnsureContiguousSlow):
* runtime/JSObject.h:
(JSObject):
(JSC::JSObject::rageEnsureContiguous):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@136372 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 1ba40de..64a778e 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -54,6 +54,7 @@
if (!block)
return;
ASSERT(block->isReachable);
+ m_block = block;
for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
m_compileIndex = block->at(m_indexInBlock);
fixupNode(m_graph[m_compileIndex]);
@@ -131,7 +132,8 @@
node.setArrayMode(
node.arrayMode().refine(
m_graph[node.child1()].prediction(),
- m_graph[node.child2()].prediction()));
+ m_graph[node.child2()].prediction(),
+ SpecNone, node.flags()));
blessArrayOperation(node.child1(), node.child2(), 2);
@@ -442,6 +444,16 @@
m_graph.ref(index);
if (structure) {
+ if (m_indexInBlock > 0) {
+ // If the previous node was a CheckStructure inserted because of stuff
+ // that the array profile told us, then remove it.
+ Node& previousNode = m_graph[m_block->at(m_indexInBlock - 1)];
+ if (previousNode.op() == CheckStructure
+ && previousNode.child1() == array
+ && previousNode.codeOrigin == codeOrigin)
+ previousNode.setOpAndDefaultFlags(Phantom);
+ }
+
Node arrayify(ArrayifyToStructure, codeOrigin, OpInfo(structure), OpInfo(arrayMode.asWord()), array, index);
arrayify.ref();
NodeIndex arrayifyIndex = m_graph.size();
@@ -564,7 +576,8 @@
int32ToDouble.predict(SpecDouble);
int32ToDouble.ref();
}
-
+
+ BasicBlock* m_block;
unsigned m_indexInBlock;
NodeIndex m_compileIndex;
InsertionSet<NodeIndex> m_insertionSet;