Title: [110631] trunk/Source/_javascript_Core
Revision
110631
Author
[email protected]
Date
2012-03-13 15:59:43 -0700 (Tue, 13 Mar 2012)

Log Message

Loads from UInt32Arrays should not result in a double up-convert if it isn't necessary
https://bugs.webkit.org/show_bug.cgi?id=80979
<rdar://problem/11036848>

Reviewed by Oliver Hunt.
        
Also improved DFG IR dumping to include type information in a somewhat more
intuitive way.

* bytecode/PredictedType.cpp:
(JSC::predictionToAbbreviatedString):
(JSC):
* bytecode/PredictedType.h:
(JSC):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileUInt32ToNumber):
(JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (110630 => 110631)


--- trunk/Source/_javascript_Core/ChangeLog	2012-03-13 22:57:43 UTC (rev 110630)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-03-13 22:59:43 UTC (rev 110631)
@@ -1,3 +1,31 @@
+2012-03-13  Filip Pizlo  <[email protected]>
+
+        Loads from UInt32Arrays should not result in a double up-convert if it isn't necessary
+        https://bugs.webkit.org/show_bug.cgi?id=80979
+        <rdar://problem/11036848>
+
+        Reviewed by Oliver Hunt.
+        
+        Also improved DFG IR dumping to include type information in a somewhat more
+        intuitive way.
+
+        * bytecode/PredictedType.cpp:
+        (JSC::predictionToAbbreviatedString):
+        (JSC):
+        * bytecode/PredictedType.h:
+        (JSC):
+        * dfg/DFGAbstractState.cpp:
+        (JSC::DFG::AbstractState::execute):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileUInt32ToNumber):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
+
 2012-03-13  George Staikos  <[email protected]>
 
         The callback is only used if SA_RESTART is defined.  Compile it out

Modified: trunk/Source/_javascript_Core/bytecode/PredictedType.cpp (110630 => 110631)


--- trunk/Source/_javascript_Core/bytecode/PredictedType.cpp	2012-03-13 22:57:43 UTC (rev 110630)
+++ trunk/Source/_javascript_Core/bytecode/PredictedType.cpp	2012-03-13 22:59:43 UTC (rev 110631)
@@ -166,6 +166,51 @@
     return description;
 }
 
+const char* predictionToAbbreviatedString(PredictedType prediction)
+{
+    if (isFinalObjectPrediction(prediction))
+        return "<Final>";
+    if (isArrayPrediction(prediction))
+        return "<Array>";
+    if (isStringPrediction(prediction))
+        return "<String>";
+    if (isFunctionPrediction(prediction))
+        return "<Function>";
+    if (isByteArrayPrediction(prediction))
+        return "<Bytearray>";
+    if (isInt8ArrayPrediction(prediction))
+        return "<Int8array>";
+    if (isInt16ArrayPrediction(prediction))
+        return "<Int16array>";
+    if (isInt32ArrayPrediction(prediction))
+        return "<Int32array>";
+    if (isUint8ArrayPrediction(prediction))
+        return "<Uint8array>";
+    if (isUint16ArrayPrediction(prediction))
+        return "<Uint16array>";
+    if (isUint32ArrayPrediction(prediction))
+        return "<Uint32array>";
+    if (isFloat32ArrayPrediction(prediction))
+        return "<Float32array>";
+    if (isFloat64ArrayPrediction(prediction))
+        return "<Float64array>";
+    if (isObjectPrediction(prediction))
+        return "<Object>";
+    if (isCellPrediction(prediction))
+        return "<Cell>";
+    if (isInt32Prediction(prediction))
+        return "<Int32>";
+    if (isDoublePrediction(prediction))
+        return "<Double>";
+    if (isNumberPrediction(prediction))
+        return "<Number>";
+    if (isBooleanPrediction(prediction))
+        return "<Boolean>";
+    if (isOtherPrediction(prediction))
+        return "<Other>";
+    return "";
+}
+
 PredictedType predictionFromClassInfo(const ClassInfo* classInfo)
 {
     if (classInfo == &JSFinalObject::s_info)

Modified: trunk/Source/_javascript_Core/bytecode/PredictedType.h (110630 => 110631)


--- trunk/Source/_javascript_Core/bytecode/PredictedType.h	2012-03-13 22:57:43 UTC (rev 110630)
+++ trunk/Source/_javascript_Core/bytecode/PredictedType.h	2012-03-13 22:59:43 UTC (rev 110631)
@@ -225,6 +225,7 @@
 }
 
 const char* predictionToString(PredictedType value);
+const char* predictionToAbbreviatedString(PredictedType value);
 
 // Merge two predictions. Note that currently this just does left | right. It may
 // seem tempting to do so directly, but you would be doing so at your own peril,

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (110630 => 110631)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp	2012-03-13 22:57:43 UTC (rev 110630)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp	2012-03-13 22:59:43 UTC (rev 110631)
@@ -514,7 +514,10 @@
         if (m_graph[node.child1()].shouldSpeculateUint32Array()) {
             forNode(node.child1()).filter(PredictUint32Array);
             forNode(node.child2()).filter(PredictInt32);
-            forNode(nodeIndex).set(PredictDouble);
+            if (node.shouldSpeculateInteger())
+                forNode(nodeIndex).set(PredictInt32);
+            else
+                forNode(nodeIndex).set(PredictDouble);
             break;
         }
         if (m_graph[node.child1()].shouldSpeculateFloat32Array()) {

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (110630 => 110631)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2012-03-13 22:57:43 UTC (rev 110630)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2012-03-13 22:59:43 UTC (rev 110631)
@@ -164,15 +164,15 @@
                 dataLog(", ");
             else
                 hasPrinted = true;
-            dataLog("@%u", m_varArgChildren[childIdx].index());
+            dataLog("@%u%s", m_varArgChildren[childIdx].index(), predictionToAbbreviatedString(at(childIdx).prediction()));
         }
     } else {
         if (!!node.child1())
-            dataLog("@%u", node.child1().index());
+            dataLog("@%u%s", node.child1().index(), predictionToAbbreviatedString(at(node.child1()).prediction()));
         if (!!node.child2())
-            dataLog(", @%u", node.child2().index());
+            dataLog(", @%u%s", node.child2().index(), predictionToAbbreviatedString(at(node.child2()).prediction()));
         if (!!node.child3())
-            dataLog(", @%u", node.child3().index());
+            dataLog(", @%u%s", node.child3().index(), predictionToAbbreviatedString(at(node.child3()).prediction()));
         hasPrinted = !!node.child1();
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (110630 => 110631)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2012-03-13 22:57:43 UTC (rev 110630)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2012-03-13 22:59:43 UTC (rev 110631)
@@ -397,7 +397,7 @@
             break;
             
         case GetByVal: {
-            if (m_graph[node.child1()].shouldSpeculateUint32Array() || m_graph[node.child1()].shouldSpeculateFloat32Array() || m_graph[node.child1()].shouldSpeculateFloat64Array())
+            if (m_graph[node.child1()].shouldSpeculateFloat32Array() || m_graph[node.child1()].shouldSpeculateFloat64Array())
                 changed |= mergePrediction(PredictDouble);
             else if (node.getHeapPrediction())
                 changed |= mergePrediction(node.getHeapPrediction());

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (110630 => 110631)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2012-03-13 22:57:43 UTC (rev 110630)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2012-03-13 22:59:43 UTC (rev 110631)
@@ -1547,23 +1547,7 @@
     // instruction that follows us, rather than the one we're executing right now. We have
     // to do this because by this point, the original values necessary to compile whatever
     // operation the UInt32ToNumber originated from might be dead.
-    speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)));
-        
-    // Verify that we can do roll forward.
-    // FIXME: This isn't right, since the next node in the graph may not actually be the next
-    // node in the basic block's execution sequence.
-    ASSERT(at(m_compileIndex + 1).op() == SetLocal);
-    ASSERT(at(m_compileIndex + 1).codeOrigin == node.codeOrigin);
-    ASSERT(at(m_compileIndex + 2).codeOrigin != node.codeOrigin);
-        
-    // Now do the magic.
-    OSRExit& exit = m_jit.codeBlock()->lastOSRExit();
-    Node& setLocal = at(m_compileIndex + 1);
-    exit.m_codeOrigin = at(m_compileIndex + 2).codeOrigin;
-    exit.m_lastSetOperand = setLocal.local();
-        
-    // Create the value recovery, and stuff it into the right place.
-    exit.valueRecoveryForOperand(setLocal.local()) = ValueRecovery::uint32InGPR(op1.gpr());
+    forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)), ValueRecovery::uint32InGPR(op1.gpr()));
 
     m_jit.move(op1.gpr(), result.gpr());
     integerResult(result.gpr(), m_compileIndex, op1.format());
@@ -1760,16 +1744,24 @@
         ASSERT_NOT_REACHED();
     }
     outOfBounds.link(&m_jit);
-    if (elementSize < 4 || signedness == SignedTypedArray)
+    if (elementSize < 4 || signedness == SignedTypedArray) {
         integerResult(resultReg, m_compileIndex);
-    else {
-        FPRTemporary fresult(this);
-        m_jit.convertInt32ToDouble(resultReg, fresult.fpr());
-        JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, resultReg, TrustedImm32(0));
-        m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), fresult.fpr());
-        positive.link(&m_jit);
-        doubleResult(fresult.fpr(), m_compileIndex);
+        return;
     }
+    
+    ASSERT(elementSize == 4 && signedness == UnsignedTypedArray);
+    if (node.shouldSpeculateInteger()) {
+        forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultReg, TrustedImm32(0)), ValueRecovery::uint32InGPR(resultReg));
+        integerResult(resultReg, m_compileIndex);
+        return;
+    }
+    
+    FPRTemporary fresult(this);
+    m_jit.convertInt32ToDouble(resultReg, fresult.fpr());
+    JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, resultReg, TrustedImm32(0));
+    m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), fresult.fpr());
+    positive.link(&m_jit);
+    doubleResult(fresult.fpr(), m_compileIndex);
 }
 
 void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness, TypedArrayRounding rounding)

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (110630 => 110631)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2012-03-13 22:57:43 UTC (rev 110630)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2012-03-13 22:59:43 UTC (rev 110631)
@@ -1823,6 +1823,22 @@
     {
         speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail, recovery);
     }
+    void forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
+    {
+        speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail);
+        
+        Node& setLocal = at(m_jit.graph().m_blocks[m_block]->at(m_indexInBlock + 1));
+        Node& nextNode = at(m_jit.graph().m_blocks[m_block]->at(m_indexInBlock + 2));
+        ASSERT(setLocal.op() == SetLocal);
+        ASSERT(setLocal.codeOrigin == at(m_compileIndex).codeOrigin);
+        ASSERT(nextNode.codeOrigin != at(m_compileIndex).codeOrigin);
+        
+        OSRExit& exit = m_jit.codeBlock()->lastOSRExit();
+        exit.m_codeOrigin = nextNode.codeOrigin;
+        exit.m_lastSetOperand = setLocal.local();
+        
+        exit.valueRecoveryForOperand(setLocal.local()) = valueRecovery;
+    }
 
     // Called when we statically determine that a speculation will fail.
     void terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, NodeIndex nodeIndex)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to