Truncating multiplication on integers should not OSR exit every time
https://bugs.webkit.org/show_bug.cgi?id=85752

Reviewed by Gavin Barraclough.
        
Merge r116264 from dfgopt.

* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::mulShouldSpeculateInteger):
(Graph):
(JSC::DFG::Graph::mulImmediateShouldSpeculateInteger):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
(JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithMul):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@117993 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index 1e2ed5a..cf2f71b 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -468,7 +468,26 @@
         break;
     }
         
-    case ArithMul:
+    case ArithMul: {
+        JSValue left = forNode(node.child1()).value();
+        JSValue right = forNode(node.child2()).value();
+        if (left && right && left.isNumber() && right.isNumber()) {
+            forNode(nodeIndex).set(JSValue(left.asNumber() * right.asNumber()));
+            m_foundConstants = true;
+            break;
+        }
+        if (m_graph.mulShouldSpeculateInteger(node)) {
+            forNode(node.child1()).filter(PredictInt32);
+            forNode(node.child2()).filter(PredictInt32);
+            forNode(nodeIndex).set(PredictInt32);
+            break;
+        }
+        forNode(node.child1()).filter(PredictNumber);
+        forNode(node.child2()).filter(PredictNumber);
+        forNode(nodeIndex).set(PredictDouble);
+        break;
+    }
+        
     case ArithDiv:
     case ArithMin:
     case ArithMax:
@@ -479,9 +498,6 @@
             double a = left.asNumber();
             double b = right.asNumber();
             switch (node.op()) {
-            case ArithMul:
-                forNode(nodeIndex).set(JSValue(a * b));
-                break;
             case ArithDiv:
                 forNode(nodeIndex).set(JSValue(a / b));
                 break;