Support CanvasPixelArray in the DFG
https://bugs.webkit.org/show_bug.cgi?id=70384

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Add support for the old CanvasPixelArray optimisations to the
DFG.  This removes the regression seen in the DFG when using
a CPA.

* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::store8):
(JSC::MacroAssemblerX86Common::truncateDoubleToInt32):
* assembler/X86Assembler.h:
(JSC::X86Assembler::movb_rm):
(JSC::X86Assembler::X86InstructionFormatter::oneByteOp8):
* bytecode/PredictedType.cpp:
(JSC::predictionToString):
(JSC::predictionFromClassInfo):
* bytecode/PredictedType.h:
(JSC::isByteArrayPrediction):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::initialize):
(JSC::DFG::AbstractState::execute):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateByteArray):
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
(JSC::DFG::Propagator::fixupNode):
(JSC::DFG::Propagator::performNodeCSE):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::checkArgumentTypes):
(JSC::DFG::compileClampDoubleToByte):
(JSC::DFG::SpeculativeJIT::compilePutByValForByteArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnByteArray):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* runtime/JSByteArray.h:
(JSC::JSByteArray::offsetOfStorage):
* wtf/ByteArray.cpp:
* wtf/ByteArray.h:
(WTF::ByteArray::offsetOfSize):
(WTF::ByteArray::offsetOfData):

Source/WebCore:

Make CanvasPixelArray inherit from ByteArray's ClassInfo so
can identify it more sensibly.

* bindings/js/JSImageDataCustom.cpp:
(WebCore::toJS):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@97876 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index 4617982..13d867a 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -105,6 +105,8 @@
             root->valuesAtHead.argument(i).set(PredictInt32);
         else if (isArrayPrediction(prediction))
             root->valuesAtHead.argument(i).set(PredictArray);
+        else if (isByteArrayPrediction(prediction))
+            root->valuesAtHead.argument(i).set(PredictByteArray);
         else if (isBooleanPrediction(prediction))
             root->valuesAtHead.argument(i).set(PredictBoolean);
         else
@@ -181,6 +183,8 @@
             forNode(node.child1()).filter(PredictInt32);
         else if (isArrayPrediction(predictedType))
             forNode(node.child1()).filter(PredictArray);
+        else if (isByteArrayPrediction(predictedType))
+            forNode(node.child1()).filter(PredictByteArray);
         else if (isBooleanPrediction(predictedType))
             forNode(node.child1()).filter(PredictBoolean);
         
@@ -375,6 +379,12 @@
             forNode(nodeIndex).set(PredictString);
             break;
         }
+        if (m_graph[node.child1()].shouldSpeculateByteArray()) {
+            forNode(node.child1()).filter(PredictByteArray);
+            forNode(node.child2()).filter(PredictInt32);
+            forNode(nodeIndex).set(PredictInt32);
+            break;
+        }
         forNode(node.child1()).filter(PredictArray);
         forNode(node.child2()).filter(PredictInt32);
         forNode(nodeIndex).makeTop();
@@ -389,6 +399,12 @@
             forNode(nodeIndex).makeTop();
             break;
         }
+        if (m_graph[node.child1()].shouldSpeculateByteArray()) {
+            forNode(node.child1()).filter(PredictByteArray);
+            forNode(node.child2()).filter(PredictInt32);
+            forNode(node.child3()).filter(PredictNumber);
+            break;
+        }
         forNode(node.child1()).filter(PredictArray);
         forNode(node.child2()).filter(PredictInt32);
         break;
@@ -540,11 +556,16 @@
         forNode(node.child1()).filter(PredictArray);
         forNode(nodeIndex).set(PredictInt32);
         break;
-            
+
     case GetStringLength:
         forNode(node.child1()).filter(PredictString);
         forNode(nodeIndex).set(PredictInt32);
         break;
+        
+    case GetByteArrayLength:
+        forNode(node.child1()).filter(PredictByteArray);
+        forNode(nodeIndex).set(PredictInt32);
+        break;
             
     case CheckStructure:
         // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).