Support integer typed arrays in the DFG JIT
https://bugs.webkit.org/show_bug.cgi?id=73608
Reviewed by Filip Pizlo.
Add support for all the integral typed arrays in the DFG JIT.
Currently this loads the contents of Uint32 arrays as doubles,
which is clearly not as efficient as it could be, but this is
still in the order of 10-20x faster than the existing behaviour.
This needed us to add support for writing 16bit values to the
macroassembler, and also to support double<->unsigned conversion.
* assembler/ARMv7Assembler.h:
(JSC::ARMv7Assembler::strh):
(JSC::ARMv7Assembler::vcvt_floatingPointToUnsigned):
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::store16):
(JSC::MacroAssemblerARMv7::truncateDoubleToUint32):
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::store16):
(JSC::MacroAssemblerX86Common::truncateDoubleToUint32):
* assembler/X86Assembler.h:
(JSC::X86Assembler::movw_rm):
(JSC::X86Assembler::cvttsd2siq_rr):
* bytecode/PredictedType.cpp:
(JSC::predictionToString):
(JSC::predictionFromClassInfo):
* bytecode/PredictedType.h:
(JSC::isInt8ArrayPrediction):
(JSC::isInt16ArrayPrediction):
(JSC::isInt32ArrayPrediction):
(JSC::isUint8ArrayPrediction):
(JSC::isUint16ArrayPrediction):
(JSC::isUint32ArrayPrediction):
(JSC::isFloat32ArrayPrediction):
(JSC::isFloat64ArrayPrediction):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::initialize):
(JSC::DFG::AbstractState::execute):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateInt8Array):
(JSC::DFG::Node::shouldSpeculateInt16Array):
(JSC::DFG::Node::shouldSpeculateInt32Array):
(JSC::DFG::Node::shouldSpeculateUint8Array):
(JSC::DFG::Node::shouldSpeculateUint16Array):
(JSC::DFG::Node::shouldSpeculateUint32Array):
(JSC::DFG::Node::shouldSpeculateFloat32Array):
(JSC::DFG::Node::shouldSpeculateFloat64Array):
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
(JSC::DFG::Propagator::fixupNode):
(JSC::DFG::Propagator::performNodeCSE):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::checkArgumentTypes):
(JSC::DFG::SpeculativeJIT::compileGetTypedArrayLength):
(JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* runtime/JSGlobalData.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@101729 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index f516bee..4176129 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -113,6 +113,22 @@
root->valuesAtHead.argument(i).set(PredictByteArray);
else if (isBooleanPrediction(prediction))
root->valuesAtHead.argument(i).set(PredictBoolean);
+ else if (isInt8ArrayPrediction(prediction))
+ root->valuesAtHead.argument(i).set(PredictInt8Array);
+ else if (isInt16ArrayPrediction(prediction))
+ root->valuesAtHead.argument(i).set(PredictInt16Array);
+ else if (isInt32ArrayPrediction(prediction))
+ root->valuesAtHead.argument(i).set(PredictInt32Array);
+ else if (isUint8ArrayPrediction(prediction))
+ root->valuesAtHead.argument(i).set(PredictUint8Array);
+ else if (isUint16ArrayPrediction(prediction))
+ root->valuesAtHead.argument(i).set(PredictUint16Array);
+ else if (isUint32ArrayPrediction(prediction))
+ root->valuesAtHead.argument(i).set(PredictUint32Array);
+ else if (isFloat32ArrayPrediction(prediction))
+ root->valuesAtHead.argument(i).set(PredictFloat32Array);
+ else if (isFloat64ArrayPrediction(prediction))
+ root->valuesAtHead.argument(i).set(PredictFloat64Array);
else
root->valuesAtHead.argument(i).makeTop();
}
@@ -198,6 +214,22 @@
forNode(node.child1()).filter(PredictArray);
else if (isByteArrayPrediction(predictedType))
forNode(node.child1()).filter(PredictByteArray);
+ else if (isInt8ArrayPrediction(predictedType))
+ forNode(node.child1()).filter(PredictInt8Array);
+ else if (isInt16ArrayPrediction(predictedType))
+ forNode(node.child1()).filter(PredictInt16Array);
+ else if (isInt32ArrayPrediction(predictedType))
+ forNode(node.child1()).filter(PredictInt32Array);
+ else if (isUint8ArrayPrediction(predictedType))
+ forNode(node.child1()).filter(PredictUint8Array);
+ else if (isUint16ArrayPrediction(predictedType))
+ forNode(node.child1()).filter(PredictUint16Array);
+ else if (isUint32ArrayPrediction(predictedType))
+ forNode(node.child1()).filter(PredictUint32Array);
+ else if (isFloat32ArrayPrediction(predictedType))
+ forNode(node.child1()).filter(PredictFloat32Array);
+ else if (isFloat64ArrayPrediction(predictedType))
+ forNode(node.child1()).filter(PredictFloat64Array);
else if (isBooleanPrediction(predictedType))
forNode(node.child1()).filter(PredictBoolean);
@@ -398,6 +430,43 @@
forNode(nodeIndex).set(PredictInt32);
break;
}
+
+ if (m_graph[node.child1()].shouldSpeculateInt8Array()) {
+ forNode(node.child1()).filter(PredictInt8Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateInt16Array()) {
+ forNode(node.child1()).filter(PredictInt16Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateInt32Array()) {
+ forNode(node.child1()).filter(PredictInt32Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateUint8Array()) {
+ forNode(node.child1()).filter(PredictUint8Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateUint16Array()) {
+ forNode(node.child1()).filter(PredictUint16Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateUint32Array()) {
+ forNode(node.child1()).filter(PredictUint32Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictDouble);
+ break;
+ }
forNode(node.child1()).filter(PredictArray);
forNode(node.child2()).filter(PredictInt32);
forNode(nodeIndex).makeTop();
@@ -418,6 +487,44 @@
forNode(node.child3()).filter(PredictNumber);
break;
}
+
+ if (m_graph[node.child1()].shouldSpeculateInt8Array()) {
+ forNode(node.child1()).filter(PredictInt8Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(node.child3()).filter(PredictNumber);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateInt16Array()) {
+ forNode(node.child1()).filter(PredictInt16Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(node.child3()).filter(PredictNumber);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateInt32Array()) {
+ forNode(node.child1()).filter(PredictInt32Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(node.child3()).filter(PredictNumber);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateUint8Array()) {
+ forNode(node.child1()).filter(PredictUint8Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(node.child3()).filter(PredictNumber);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateUint16Array()) {
+ forNode(node.child1()).filter(PredictUint16Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(node.child3()).filter(PredictNumber);
+ break;
+ }
+ if (m_graph[node.child1()].shouldSpeculateUint32Array()) {
+ forNode(node.child1()).filter(PredictUint32Array);
+ forNode(node.child2()).filter(PredictInt32);
+ forNode(node.child3()).filter(PredictNumber);
+ break;
+ }
+
forNode(node.child1()).filter(PredictArray);
forNode(node.child2()).filter(PredictInt32);
break;
@@ -583,6 +690,38 @@
forNode(node.child1()).filter(PredictByteArray);
forNode(nodeIndex).set(PredictInt32);
break;
+ case GetInt8ArrayLength:
+ forNode(node.child1()).filter(PredictInt8Array);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ case GetInt16ArrayLength:
+ forNode(node.child1()).filter(PredictInt16Array);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ case GetInt32ArrayLength:
+ forNode(node.child1()).filter(PredictInt32Array);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ case GetUint8ArrayLength:
+ forNode(node.child1()).filter(PredictUint8Array);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ case GetUint16ArrayLength:
+ forNode(node.child1()).filter(PredictUint16Array);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ case GetUint32ArrayLength:
+ forNode(node.child1()).filter(PredictUint32Array);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ case GetFloat32ArrayLength:
+ forNode(node.child1()).filter(PredictFloat32Array);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ case GetFloat64ArrayLength:
+ forNode(node.child1()).filter(PredictFloat64Array);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
case CheckStructure:
// FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).