Title: [96415] trunk/Source/_javascript_Core
Revision
96415
Author
[email protected]
Date
2011-09-30 13:01:38 -0700 (Fri, 30 Sep 2011)

Log Message

Merge some more of DFGSpeculativeJIT 32_64/64
https://bugs.webkit.org/show_bug.cgi?id=69164

Reviewed by Oliver Hunt.

* dfg/DFGJITCodeGenerator.h:
* dfg/DFGJITCodeGenerator32_64.cpp:
* dfg/DFGJITCodeGenerator64.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileValueAdd):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileValueAdd):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::compile):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (96414 => 96415)


--- trunk/Source/_javascript_Core/ChangeLog	2011-09-30 19:34:33 UTC (rev 96414)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-09-30 20:01:38 UTC (rev 96415)
@@ -1,3 +1,28 @@
+2011-09-30  Gavin Barraclough  <[email protected]>
+
+        Merge some more of DFGSpeculativeJIT 32_64/64
+        https://bugs.webkit.org/show_bug.cgi?id=69164
+
+        Reviewed by Oliver Hunt.
+
+        * dfg/DFGJITCodeGenerator.h:
+        * dfg/DFGJITCodeGenerator32_64.cpp:
+        * dfg/DFGJITCodeGenerator64.cpp:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+        (JSC::DFG::SpeculativeJIT::compare):
+        (JSC::DFG::SpeculativeJIT::compileValueAdd):
+        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compare):
+        (JSC::DFG::SpeculativeJIT::compileValueAdd):
+        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+        (JSC::DFG::SpeculativeJIT::compile):
+
 2011-09-30  Mark Hahnenberg  <[email protected]>
 
         Add getCallData to MethodTable in ClassInfo

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (96414 => 96415)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-09-30 19:34:33 UTC (rev 96414)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-09-30 20:01:38 UTC (rev 96415)
@@ -779,8 +779,6 @@
     
     void emitBranch(Node&);
     
-    void nonSpeculativeLogicalNot(Node&);
-    
     MacroAssembler::Address addressOfCallData(int idx)
     {
         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register)));

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp (96414 => 96415)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp	2011-09-30 19:34:33 UTC (rev 96414)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp	2011-09-30 20:01:38 UTC (rev 96415)
@@ -1554,38 +1554,6 @@
     noResult(m_compileIndex, UseChildrenCalledExplicitly);
 }
 
-void JITCodeGenerator::nonSpeculativeLogicalNot(Node& node)
-{
-    JSValueOperand arg1(this, node.child1());
-    GPRTemporary resultTag(this, arg1);
-    GPRTemporary resultPayload(this, arg1, false);
-    GPRReg arg1TagGPR = arg1.tagGPR();
-    GPRReg arg1PayloadGPR = arg1.payloadGPR();
-    GPRReg resultTagGPR = resultTag.gpr();
-    GPRReg resultPayloadGPR = resultPayload.gpr();
-        
-    arg1.use();
-
-    JITCompiler::Jump fastCase = m_jit.branch32(JITCompiler::Equal, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
-        
-    silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);
-    m_jit.push(arg1TagGPR);
-    m_jit.push(arg1PayloadGPR);
-    m_jit.push(GPRInfo::callFrameRegister);
-    appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
-    m_jit.move(GPRInfo::returnValueGPR, resultPayloadGPR);
-    silentFillAllRegisters(resultTagGPR, resultPayloadGPR);
-    JITCompiler::Jump doNot = m_jit.jump();
-        
-    fastCase.link(&m_jit);
-    m_jit.move(arg1PayloadGPR, resultPayloadGPR);
-
-    doNot.link(&m_jit);
-    m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
-    m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTagGPR);
-    jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
-}
-
 void JITCodeGenerator::emitCall(Node& node)
 {
     P_DFGOperation_E slowCallFunction;

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp (96414 => 96415)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp	2011-09-30 19:34:33 UTC (rev 96414)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator64.cpp	2011-09-30 20:01:38 UTC (rev 96415)
@@ -1525,33 +1525,6 @@
     }
 }
 
-void JITCodeGenerator::nonSpeculativeLogicalNot(Node& node)
-{
-    JSValueOperand arg1(this, node.child1());
-    GPRTemporary result(this);
-    
-    GPRReg arg1GPR = arg1.gpr();
-    GPRReg resultGPR = result.gpr();
-    
-    arg1.use();
-    
-    m_jit.move(arg1GPR, resultGPR);
-    m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
-    JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
-    
-    silentSpillAllRegisters(resultGPR);
-    m_jit.move(arg1GPR, GPRInfo::argumentGPR1);
-    m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-    appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
-    m_jit.move(GPRInfo::returnValueGPR, resultGPR);
-    silentFillAllRegisters(resultGPR);
-    
-    fastCase.link(&m_jit);
-    
-    m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
-    jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
-}
-
 void JITCodeGenerator::emitCall(Node& node)
 {
     P_DFGOperation_E slowCallFunction;

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (96414 => 96415)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-09-30 19:34:33 UTC (rev 96414)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-09-30 20:01:38 UTC (rev 96415)
@@ -194,6 +194,41 @@
         addBranch(m_jit.jump(), notTaken);
 }
 
+// Returns true if the compare is fused with a subsequent branch.
+bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
+{
+    // Fused compare & branch.
+    NodeIndex branchNodeIndex = detectPeepHoleBranch();
+    if (branchNodeIndex != NoNode) {
+        // detectPeepHoleBranch currently only permits the branch to be the very next node,
+        // so can be no intervening nodes to also reference the compare. 
+        ASSERT(node.adjustedRefCount() == 1);
+
+        if (shouldSpeculateInteger(node.child1(), node.child2())) {
+            compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
+            use(node.child1());
+            use(node.child2());
+        } else if (shouldSpeculateNumber(node.child1(), node.child2())) {
+            compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
+            use(node.child1());
+            use(node.child2());
+        } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) {
+            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr);
+            use(node.child1());
+            use(node.child2());
+        } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) {
+            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr);
+            use(node.child1());
+            use(node.child2());
+        } else
+            nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
+
+        m_compileIndex = branchNodeIndex;
+        return true;
+    }
+    return false;
+}
+
 void SpeculativeJIT::compileMovHint(Node& node)
 {
     ASSERT(node.op == SetLocal);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (96414 => 96415)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2011-09-30 19:34:33 UTC (rev 96414)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2011-09-30 20:01:38 UTC (rev 96415)
@@ -570,10 +570,13 @@
     }
     
     bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ);
+    bool compilePeepHoleBranch(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ);
     void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition);
     void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition);
     void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex, void* vptr);
     void compileObjectEquality(Node&, void* vptr);
+    void compileValueAdd(Node&);
+    void compileLogicalNot(Node&);
     
     // It is acceptable to have structure be equal to scratch, so long as you're fine
     // with the structure GPR being clobbered.

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (96414 => 96415)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2011-09-30 19:34:33 UTC (rev 96414)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2011-09-30 20:01:38 UTC (rev 96415)
@@ -101,7 +101,7 @@
     case DataFormatCell:
     case DataFormatBoolean:
     case DataFormatJSDouble:
-    case DataFormatJSCell: 
+    case DataFormatJSCell:
     case DataFormatJSBoolean: {
         terminateSpeculativeExecution();
         returnFormat = DataFormatInteger;
@@ -373,35 +373,8 @@
 // Returns true if the compare is fused with a subsequent branch.
 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
 {
-    // Fused compare & branch.
-    NodeIndex branchNodeIndex = detectPeepHoleBranch();
-    if (branchNodeIndex != NoNode) {
-        // detectPeepHoleBranch currently only permits the branch to be the very next node,
-        // so can be no intervening nodes to also reference the compare. 
-        ASSERT(node.adjustedRefCount() == 1);
-
-        if (shouldSpeculateInteger(node.child1(), node.child2())) {
-            compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
-            use(node.child1());
-            use(node.child2());
-        } else if (shouldSpeculateNumber(node.child1(), node.child2())) {
-            compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
-            use(node.child1());
-            use(node.child2());
-        } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) {
-            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr);
-            use(node.child1());
-            use(node.child2());
-        } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) {
-            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr);
-            use(node.child1());
-            use(node.child2());
-        } else
-            nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
-
-        m_compileIndex = branchNodeIndex;
+    if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
         return true;
-    }
 
     if (shouldSpeculateFinalObject(node.child1(), node.child2()))
         compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr);
@@ -440,6 +413,75 @@
     return false;
 }
 
+void SpeculativeJIT::compileValueAdd(Node& node)
+{
+    JSValueOperand op1(this, node.child1());
+    JSValueOperand op2(this, node.child2());
+
+    GPRReg op1TagGPR = op1.tagGPR();
+    GPRReg op1PayloadGPR = op1.payloadGPR();
+    GPRReg op2TagGPR = op2.tagGPR();
+    GPRReg op2PayloadGPR = op2.payloadGPR();
+
+    flushRegisters();
+    
+    GPRResult2 resultTag(this);
+    GPRResult resultPayload(this);
+    if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
+        callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
+    else
+        callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
+    
+    jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+}
+
+void SpeculativeJIT::compileLogicalNot(Node& node)
+{
+    // FIXME: Need to add fast paths for known booleans.
+    JSValueOperand value(this, node.child1());
+    GPRTemporary resultTag(this, value);
+    GPRTemporary resultPayload(this, value, false);
+    speculationCheck(m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag)));
+    m_jit.move(value.payloadGPR(), resultPayload.gpr());
+    m_jit.xor32(TrustedImm32(1), resultPayload.gpr());
+    m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr());
+
+    // If we add a DataFormatBool, we should use it here.
+    jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean);
+
+    // This code is moved from nonSpeculativeLogicalNot, currently unused!
+#if 0
+    JSValueOperand arg1(this, node.child1());
+    GPRTemporary resultTag(this, arg1);
+    GPRTemporary resultPayload(this, arg1, false);
+    GPRReg arg1TagGPR = arg1.tagGPR();
+    GPRReg arg1PayloadGPR = arg1.payloadGPR();
+    GPRReg resultTagGPR = resultTag.gpr();
+    GPRReg resultPayloadGPR = resultPayload.gpr();
+        
+    arg1.use();
+
+    JITCompiler::Jump fastCase = m_jit.branch32(JITCompiler::Equal, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
+        
+    silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);
+    m_jit.push(arg1TagGPR);
+    m_jit.push(arg1PayloadGPR);
+    m_jit.push(GPRInfo::callFrameRegister);
+    appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
+    m_jit.move(GPRInfo::returnValueGPR, resultPayloadGPR);
+    silentFillAllRegisters(resultTagGPR, resultPayloadGPR);
+    JITCompiler::Jump doNot = m_jit.jump();
+        
+    fastCase.link(&m_jit);
+    m_jit.move(arg1PayloadGPR, resultPayloadGPR);
+
+    doNot.link(&m_jit);
+    m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
+    m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTagGPR);
+    jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
+#endif
+}
+
 void SpeculativeJIT::compile(Node& node)
 {
     NodeType op = node.op;
@@ -459,31 +501,36 @@
         }
         
         GPRTemporary result(this);
-        VirtualRegister virtualRegister = node.virtualRegister();
-        m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
         if (isInt32Prediction(prediction)) {
+            m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
+
             // Like integerResult, but don't useChildren - our children are phi nodes,
             // and don't represent values within this dataflow with virtual registers.
+            VirtualRegister virtualRegister = node.virtualRegister();
             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
             m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
-        } else {
-            // Like jsValueResult, but don't useChildren - our children are phi nodes,
-            // and don't represent values within this dataflow with virtual registers.
-            GPRTemporary tag(this);
-            m_jit.load32(JITCompiler::tagFor(node.local()), tag.gpr());
-            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
-            m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
+            break;
+        }
 
-            DataFormat format;
-            if (isArrayPrediction(prediction))
-                format = DataFormatJSCell;
-            else if (isBooleanPrediction(prediction))
-                format = DataFormatJSBoolean;
-            else
-                format = DataFormatJS;
+        GPRTemporary tag(this);
+        m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
+        m_jit.load32(JITCompiler::tagFor(node.local()), tag.gpr());
 
-            m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format);
-        }
+        // Like jsValueResult, but don't useChildren - our children are phi nodes,
+        // and don't represent values within this dataflow with virtual registers.
+        VirtualRegister virtualRegister = node.virtualRegister();
+        m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
+        m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
+
+        DataFormat format;
+        if (isArrayPrediction(prediction))
+            format = DataFormatJSCell;
+        else if (isBooleanPrediction(prediction))
+            format = DataFormatJSBoolean;
+        else
+            format = DataFormatJS;
+
+        m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format);
         break;
     }
 
@@ -616,17 +663,14 @@
             
             IntegerOperand op1(this, node.child1());
             FPRTemporary result(this);
-            GPRTemporary address(this, op1);
             
             GPRReg inputGPR = op1.gpr();
             FPRReg outputFPR = result.fpr();
-            GPRReg addressGPR = address.gpr();
             
             m_jit.convertInt32ToDouble(inputGPR, outputFPR);
             
             JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, inputGPR, TrustedImm32(0));
-            m_jit.move(JITCompiler::TrustedImmPtr(&twoToThe32), addressGPR);
-            m_jit.addDouble(JITCompiler::Address(addressGPR, 0), outputFPR);
+            m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), outputFPR);
             positive.link(&m_jit);
             
             doubleResult(outputFPR, m_compileIndex);
@@ -764,25 +808,7 @@
         }
 
         ASSERT(op == ValueAdd);
-
-        JSValueOperand op1(this, node.child1());
-        JSValueOperand op2(this, node.child2());
-
-        GPRReg op1TagGPR = op1.tagGPR();
-        GPRReg op1PayloadGPR = op1.payloadGPR();
-        GPRReg op2TagGPR = op2.tagGPR();
-        GPRReg op2PayloadGPR = op2.payloadGPR();
-
-        flushRegisters();
-        
-        GPRResult2 resultTag(this);
-        GPRResult resultPayload(this);
-        if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
-            callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
-        else
-            callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
-        
-        jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+        compileValueAdd(node);
         break;
     }
 
@@ -1062,20 +1088,9 @@
         break;
     }
 
-    case LogicalNot: {
-        // FIXME: Need to add fast paths for known booleans.
-        JSValueOperand value(this, node.child1());
-        GPRTemporary resultTag(this, value);
-        GPRTemporary resultPayload(this, value, false);
-        speculationCheck(m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag)));
-        m_jit.move(value.payloadGPR(), resultPayload.gpr());
-        m_jit.xor32(TrustedImm32(1), resultPayload.gpr());
-        m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr());
-
-        // If we add a DataFormatBool, we should use it here.
-        jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean);
+    case LogicalNot:
+        compileLogicalNot(node);
         break;
-    }
 
     case CompareLess:
         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
@@ -1156,7 +1171,7 @@
         SpeculateCellOperand base(this, node.child1());
         SpeculateStrictInt32Operand property(this, node.child2());
         JSValueOperand value(this, node.child3());
-        GPRTemporary scratch(this, base);
+        GPRTemporary scratch(this);
 
         // Map base, property & value into registers, allocate a scratch register.
         GPRReg baseReg = base.gpr();

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (96414 => 96415)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2011-09-30 19:34:33 UTC (rev 96414)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2011-09-30 20:01:38 UTC (rev 96415)
@@ -476,35 +476,8 @@
 // Returns true if the compare is fused with a subsequent branch.
 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
 {
-    // Fused compare & branch.
-    NodeIndex branchNodeIndex = detectPeepHoleBranch();
-    if (branchNodeIndex != NoNode) {
-        // detectPeepHoleBranch currently only permits the branch to be the very next node,
-        // so can be no intervening nodes to also reference the compare. 
-        ASSERT(node.adjustedRefCount() == 1);
-
-        if (shouldSpeculateInteger(node.child1(), node.child2())) {
-            compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
-            use(node.child1());
-            use(node.child2());
-        } else if (shouldSpeculateNumber(node.child1(), node.child2())) {
-            compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
-            use(node.child1());
-            use(node.child2());
-        } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) {
-            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr);
-            use(node.child1());
-            use(node.child2());
-        } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) {
-            compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr);
-            use(node.child1());
-            use(node.child2());
-        } else
-            nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
-
-        m_compileIndex = branchNodeIndex;
+    if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
         return true;
-    }
 
     if (shouldSpeculateInteger(node.child1(), node.child2())) {
         SpeculateIntegerOperand op1(this, node.child1());
@@ -537,6 +510,78 @@
     return false;
 }
 
+void SpeculativeJIT::compileValueAdd(Node& node)
+{
+    JSValueOperand op1(this, node.child1());
+    JSValueOperand op2(this, node.child2());
+    
+    GPRReg op1GPR = op1.gpr();
+    GPRReg op2GPR = op2.gpr();
+    
+    flushRegisters();
+    
+    GPRResult result(this);
+    if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
+        callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
+    else
+        callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
+    
+    jsValueResult(result.gpr(), m_compileIndex);
+}
+
+void SpeculativeJIT::compileLogicalNot(Node& node)
+{
+    if (isKnownBoolean(node.child1())) {
+        SpeculateBooleanOperand value(this, node.child1());
+        GPRTemporary result(this, value);
+        
+        m_jit.move(value.gpr(), result.gpr());
+        m_jit.xorPtr(TrustedImm32(true), result.gpr());
+        
+        jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+        return;
+    }
+    
+    PredictedType prediction = m_jit.getPrediction(node.child1());
+    if (isBooleanPrediction(prediction) || !prediction) {
+        JSValueOperand value(this, node.child1());
+        GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
+        
+        m_jit.move(value.gpr(), result.gpr());
+        m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
+        speculationCheck(m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
+        m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
+        
+        // If we add a DataFormatBool, we should use it here.
+        jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+        return;
+    }
+    
+    JSValueOperand arg1(this, node.child1());
+    GPRTemporary result(this);
+    
+    GPRReg arg1GPR = arg1.gpr();
+    GPRReg resultGPR = result.gpr();
+    
+    arg1.use();
+    
+    m_jit.move(arg1GPR, resultGPR);
+    m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
+    JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
+    
+    silentSpillAllRegisters(resultGPR);
+    m_jit.move(arg1GPR, GPRInfo::argumentGPR1);
+    m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
+    m_jit.move(GPRInfo::returnValueGPR, resultGPR);
+    silentFillAllRegisters(resultGPR);
+    
+    fastCase.link(&m_jit);
+    
+    m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
+    jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
+}
+
 void SpeculativeJIT::compile(Node& node)
 {
     NodeType op = node.op;
@@ -564,24 +609,25 @@
             VirtualRegister virtualRegister = node.virtualRegister();
             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
             m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
-        } else {
-            m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr());
+            break;
+        }
 
-            // Like jsValueResult, but don't useChildren - our children are phi nodes,
-            // and don't represent values within this dataflow with virtual registers.
-            VirtualRegister virtualRegister = node.virtualRegister();
-            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
-            
-            DataFormat format;
-            if (isArrayPrediction(prediction))
-                format = DataFormatJSCell;
-            else if (isBooleanPrediction(prediction))
-                format = DataFormatJSBoolean;
-            else
-                format = DataFormatJS;
+        m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr());
 
-            m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format);
-        }
+        // Like jsValueResult, but don't useChildren - our children are phi nodes,
+        // and don't represent values within this dataflow with virtual registers.
+        VirtualRegister virtualRegister = node.virtualRegister();
+        m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
+
+        DataFormat format;
+        if (isArrayPrediction(prediction))
+            format = DataFormatJSCell;
+        else if (isBooleanPrediction(prediction))
+            format = DataFormatJSBoolean;
+        else
+            format = DataFormatJS;
+
+        m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format);
         break;
     }
 
@@ -862,22 +908,7 @@
         }
 
         ASSERT(op == ValueAdd);
-
-        JSValueOperand op1(this, node.child1());
-        JSValueOperand op2(this, node.child2());
-        
-        GPRReg op1GPR = op1.gpr();
-        GPRReg op2GPR = op2.gpr();
-        
-        flushRegisters();
-        
-        GPRResult result(this);
-        if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
-            callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
-        else
-            callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
-        
-        jsValueResult(result.gpr(), m_compileIndex);
+        compileValueAdd(node);
         break;
     }
 
@@ -1157,37 +1188,9 @@
         break;
     }
 
-    case LogicalNot: {
-        if (isKnownBoolean(node.child1())) {
-            SpeculateBooleanOperand value(this, node.child1());
-            GPRTemporary result(this, value);
-            
-            m_jit.move(value.gpr(), result.gpr());
-            m_jit.xorPtr(TrustedImm32(true), result.gpr());
-            
-            jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
-            break;
-        }
-        
-        PredictedType prediction = m_jit.getPrediction(node.child1());
-        if (isBooleanPrediction(prediction) || !prediction) {
-            JSValueOperand value(this, node.child1());
-            GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
-            
-            m_jit.move(value.gpr(), result.gpr());
-            m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
-            speculationCheck(m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
-            m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
-            
-            // If we add a DataFormatBool, we should use it here.
-            jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
-            break;
-        }
-        
-        nonSpeculativeLogicalNot(node);
-        
+    case LogicalNot:
+        compileLogicalNot(node);
         break;
-    }
 
     case CompareLess:
         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to