Title: [91280] trunk/Source/_javascript_Core
Revision
91280
Author
[email protected]
Date
2011-07-19 11:55:16 -0700 (Tue, 19 Jul 2011)

Log Message

DFG JIT sometimes emits spill code even when the respective values
are never needed.
https://bugs.webkit.org/show_bug.cgi?id=64774

Patch by Filip Pizlo <[email protected]> on 2011-07-19
Reviewed by Gavin Barraclough.

The main high-level change is that it is now easier to call use() on a
virtual register.  JSValueOperand and its other-typed relatives now have
a handy use() method, and jsValueResult() and friends now make it easier to
pass UseChildrenCalledExplicitly.

The rest of this patch hoists the call to use() as high as possible for
all of those cases where either flushRegisters() or silentSpillAllRegisters()
may be called.

* dfg/DFGJITCodeGenerator.cpp:
(JSC::DFG::JITCodeGenerator::cachedGetById):
(JSC::DFG::JITCodeGenerator::cachedGetMethod):
(JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranch):
(JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeCompare):
(JSC::DFG::JITCodeGenerator::nonSpeculativeCompare):
(JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeStrictEq):
(JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeStrictEq):
(JSC::DFG::JITCodeGenerator::nonSpeculativeStrictEq):
(JSC::DFG::JITCodeGenerator::emitBranch):
* dfg/DFGJITCodeGenerator.h:
(JSC::DFG::JITCodeGenerator::use):
(JSC::DFG::JITCodeGenerator::integerResult):
(JSC::DFG::JITCodeGenerator::jsValueResult):
(JSC::DFG::IntegerOperand::use):
(JSC::DFG::DoubleOperand::use):
(JSC::DFG::JSValueOperand::use):
* dfg/DFGNonSpeculativeJIT.cpp:
(JSC::DFG::NonSpeculativeJIT::valueToNumber):
(JSC::DFG::NonSpeculativeJIT::valueToInt32):
(JSC::DFG::NonSpeculativeJIT::knownConstantArithOp):
(JSC::DFG::NonSpeculativeJIT::basicArithOp):
(JSC::DFG::NonSpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculateStrictInt32Operand::use):
(JSC::DFG::SpeculateCellOperand::use):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (91279 => 91280)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-19 18:55:16 UTC (rev 91280)
@@ -1,3 +1,49 @@
+2011-07-19  Filip Pizlo  <[email protected]>
+
+        DFG JIT sometimes emits spill code even when the respective values
+        are never needed.
+        https://bugs.webkit.org/show_bug.cgi?id=64774
+
+        Reviewed by Gavin Barraclough.
+        
+        The main high-level change is that it is now easier to call use() on a
+        virtual register.  JSValueOperand and its other-typed relatives now have
+        a handy use() method, and jsValueResult() and friends now make it easier to
+        pass UseChildrenCalledExplicitly.
+        
+        The rest of this patch hoists the call to use() as high as possible for
+        all of those cases where either flushRegisters() or silentSpillAllRegisters()
+        may be called.
+
+        * dfg/DFGJITCodeGenerator.cpp:
+        (JSC::DFG::JITCodeGenerator::cachedGetById):
+        (JSC::DFG::JITCodeGenerator::cachedGetMethod):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranch):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeCompare):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativeCompare):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeStrictEq):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeStrictEq):
+        (JSC::DFG::JITCodeGenerator::nonSpeculativeStrictEq):
+        (JSC::DFG::JITCodeGenerator::emitBranch):
+        * dfg/DFGJITCodeGenerator.h:
+        (JSC::DFG::JITCodeGenerator::use):
+        (JSC::DFG::JITCodeGenerator::integerResult):
+        (JSC::DFG::JITCodeGenerator::jsValueResult):
+        (JSC::DFG::IntegerOperand::use):
+        (JSC::DFG::DoubleOperand::use):
+        (JSC::DFG::JSValueOperand::use):
+        * dfg/DFGNonSpeculativeJIT.cpp:
+        (JSC::DFG::NonSpeculativeJIT::valueToNumber):
+        (JSC::DFG::NonSpeculativeJIT::valueToInt32):
+        (JSC::DFG::NonSpeculativeJIT::knownConstantArithOp):
+        (JSC::DFG::NonSpeculativeJIT::basicArithOp):
+        (JSC::DFG::NonSpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculateStrictInt32Operand::use):
+        (JSC::DFG::SpeculateCellOperand::use):
+
 2011-07-19  Xan Lopez  <[email protected]>
 
         ARMv7 backend broken, lacks 3 parameter rshift32 method

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (91279 => 91280)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-07-19 18:55:16 UTC (rev 91280)
@@ -391,15 +391,8 @@
         || (node.isConstant() && !valueOfJSConstant(nodeIndex).isInt32());
 }
 
-JITCompiler::Call JITCodeGenerator::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, NodeType nodeType)
+JITCompiler::Call JITCodeGenerator::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, NodeType nodeType)
 {
-    GPRReg scratchGPR;
-    
-    if (resultGPR == baseGPR)
-        scratchGPR = tryAllocate();
-    else
-        scratchGPR = resultGPR;
-    
     JITCompiler::DataLabelPtr structureToCompare;
     JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
     
@@ -511,7 +504,7 @@
     m_jit.addPropertyAccess(functionCall, checkImmToCall, callToCheck, callToStore, callToSlowCase, callToDone, static_cast<int8_t>(baseGPR), static_cast<int8_t>(valueGPR), static_cast<int8_t>(scratchGPR));
 }
 
-void JITCodeGenerator::cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget)
+void JITCodeGenerator::cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget)
 {
     JITCompiler::Call slowCall;
     JITCompiler::DataLabelPtr structToCompare, protoObj, protoStructToCompare, putFunction;
@@ -527,7 +520,7 @@
     wrongStructure.link(&m_jit);
     wrongProtoStructure.link(&m_jit);
     
-    slowCall = cachedGetById(baseGPR, resultGPR, identifierNumber, slowPathTarget, GetMethod);
+    slowCall = cachedGetById(baseGPR, resultGPR, scratchGPR, identifierNumber, slowPathTarget, GetMethod);
     
     done.link(&m_jit);
     
@@ -653,17 +646,23 @@
     JITCompiler::JumpList slowPath;
     
     if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
-        flushRegisters();
-
         GPRResult result(this);
         GPRReg resultGPR = result.gpr();
     
+        arg1.use();
+        arg2.use();
+    
+        flushRegisters();
+
         callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
         addBranch(m_jit.branchTest8(callResultCondition, resultGPR), taken);
     } else {
         GPRTemporary result(this, arg2);
         GPRReg resultGPR = result.gpr();
     
+        arg1.use();
+        arg2.use();
+    
         if (!isKnownInteger(node.child1()))
             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
         if (!isKnownInteger(node.child2()))
@@ -701,18 +700,24 @@
     JITCompiler::JumpList slowPath;
     
     if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
-        flushRegisters();
-        
         GPRResult result(this);
         GPRReg resultGPR = result.gpr();
     
+        arg1.use();
+        arg2.use();
+    
+        flushRegisters();
+        
         callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
         
         m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
-        jsValueResult(resultGPR, m_compileIndex);
+        jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
     } else {
         GPRTemporary result(this, arg2);
         GPRReg resultGPR = result.gpr();
+
+        arg1.use();
+        arg2.use();
     
         if (!isKnownInteger(node.child1()))
             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
@@ -740,7 +745,7 @@
         
         m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
         
-        jsValueResult(resultGPR, m_compileIndex);
+        jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
     }
 }
 
@@ -752,8 +757,6 @@
         
         nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
     
-        use(node.child1());
-        use(node.child2());
         m_compileIndex = branchNodeIndex;
         
         return true;
@@ -787,6 +790,9 @@
     GPRTemporary result(this);
     GPRReg resultGPR = result.gpr();
     
+    arg1.use();
+    arg2.use();
+    
     if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
         // see if we get lucky: if the arguments are cells and they reference the same
         // cell, then they must be strictly equal.
@@ -839,6 +845,9 @@
     GPRTemporary result(this);
     GPRReg resultGPR = result.gpr();
     
+    arg1.use();
+    arg2.use();
+    
     if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
         // see if we get lucky: if the arguments are cells and they reference the same
         // cell, then they must be strictly equal.
@@ -898,7 +907,7 @@
         done2.link(&m_jit);
     }
     
-    jsValueResult(resultGPR, m_compileIndex);
+    jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
 }
 
 bool JITCodeGenerator::nonSpeculativeStrictEq(Node& node, bool invert)
@@ -912,8 +921,6 @@
         
         nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert);
     
-        use(node.child1());
-        use(node.child2());
         m_compileIndex = branchNodeIndex;
         
         return true;
@@ -932,6 +939,8 @@
     GPRTemporary result(this);
     GPRReg resultGPR = result.gpr();
     
+    value.use();
+    
     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
 
@@ -951,7 +960,7 @@
     if (notTaken != (m_block + 1))
         addBranch(m_jit.jump(), notTaken);
     
-    noResult(m_compileIndex);
+    noResult(m_compileIndex, UseChildrenCalledExplicitly);
 }
 
 void JITCodeGenerator::emitCall(Node& node)

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (91279 => 91280)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-07-19 18:55:16 UTC (rev 91280)
@@ -157,6 +157,25 @@
         return info.registerFormat() == DataFormatDouble;
     }
 
+    // Called on an operand once it has been consumed by a parent node.
+    void use(NodeIndex nodeIndex)
+    {
+        VirtualRegister virtualRegister = m_jit.graph()[nodeIndex].virtualRegister();
+        GenerationInfo& info = m_generationInfo[virtualRegister];
+
+        // use() returns true when the value becomes dead, and any
+        // associated resources may be freed.
+        if (!info.use())
+            return;
+
+        // Release the associated machine registers.
+        DataFormat registerFormat = info.registerFormat();
+        if (registerFormat == DataFormatDouble)
+            m_fprs.release(info.fpr());
+        else if (registerFormat != DataFormatNone)
+            m_gprs.release(info.gpr());
+    }
+
     static void writeBarrier(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR);
 
     static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg)
@@ -357,25 +376,6 @@
         return unboxDouble(gpr, fprAllocate());
     }
 
-    // Called on an operand once it has been consumed by a parent node.
-    void use(NodeIndex nodeIndex)
-    {
-        VirtualRegister virtualRegister = m_jit.graph()[nodeIndex].virtualRegister();
-        GenerationInfo& info = m_generationInfo[virtualRegister];
-
-        // use() returns true when the value becomes dead, and any
-        // associated resources may be freed.
-        if (!info.use())
-            return;
-
-        // Release the associated machine registers.
-        DataFormat registerFormat = info.registerFormat();
-        if (registerFormat == DataFormatDouble)
-            m_fprs.release(info.fpr());
-        else if (registerFormat != DataFormatNone)
-            m_gprs.release(info.gpr());
-    }
-
     // Spill a VirtualRegister to the RegisterFile.
     void spill(VirtualRegister spillMe)
     {
@@ -559,9 +559,9 @@
         return lastNode.op == Branch && lastNode.child1() == m_compileIndex ? lastNodeIndex : NoNode;
     }
 
-    JITCompiler::Call cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), NodeType = GetById);
+    JITCompiler::Call cachedGetById(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), NodeType = GetById);
     void cachedPutById(GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
-    void cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
+    void cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
     
     void nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, bool invert = false);
     void nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeIndex branchNodeIndex, bool invert = false);
@@ -612,6 +612,10 @@
             info.initJSValue(nodeIndex, node.refCount(), reg, format);
         }
     }
+    void integerResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
+    {
+        integerResult(reg, nodeIndex, DataFormatInteger, mode);
+    }
     void noResult(NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
     {
         if (mode == UseChildrenCalledExplicitly)
@@ -644,6 +648,10 @@
         GenerationInfo& info = m_generationInfo[virtualRegister];
         info.initJSValue(nodeIndex, node.refCount(), reg, format);
     }
+    void jsValueResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
+    {
+        jsValueResult(reg, nodeIndex, DataFormatJS, mode);
+    }
     void doubleResult(FPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
     {
         Node& node = m_jit.graph()[nodeIndex];
@@ -995,6 +1003,11 @@
             m_gprOrInvalid = m_jit->fillInteger(index(), m_format);
         return m_gprOrInvalid;
     }
+    
+    void use()
+    {
+        m_jit->use(m_index);
+    }
 
 private:
     JITCodeGenerator* m_jit;
@@ -1032,6 +1045,11 @@
             m_fprOrInvalid = m_jit->fillDouble(index());
         return m_fprOrInvalid;
     }
+    
+    void use()
+    {
+        m_jit->use(m_index);
+    }
 
 private:
     JITCodeGenerator* m_jit;
@@ -1068,6 +1086,11 @@
             m_gprOrInvalid = m_jit->fillJSValue(index());
         return m_gprOrInvalid;
     }
+    
+    void use()
+    {
+        m_jit->use(m_index);
+    }
 
 private:
     JITCodeGenerator* m_jit;

Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (91279 => 91280)


--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-07-19 18:55:16 UTC (rev 91280)
@@ -59,6 +59,7 @@
 void NonSpeculativeJIT::valueToNumber(JSValueOperand& operand, GPRReg gpr)
 {
     GPRReg jsValueGpr = operand.gpr();
+    operand.use();
 
     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
     JITCompiler::Jump nonNumeric = m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister);
@@ -87,6 +88,7 @@
 void NonSpeculativeJIT::valueToInt32(JSValueOperand& operand, GPRReg result)
 {
     GPRReg jsValueGpr = operand.gpr();
+    operand.use();
 
     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
 
@@ -126,6 +128,9 @@
     GPRReg regArgGPR = regArg.gpr();
     GPRTemporary result(this, regArg);
     GPRReg resultGPR = result.gpr();
+    
+    regArg.use();
+    use(immChild);
 
     JITCompiler::Jump notInt;
     
@@ -220,7 +225,7 @@
     
     done.link(&m_jit);
         
-    jsValueResult(resultGPR, m_compileIndex);
+    jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
 }
 
 void NonSpeculativeJIT::basicArithOp(NodeType op, Node &node)
@@ -235,6 +240,9 @@
 
     GPRReg resultGPR = result.gpr();
     
+    arg1.use();
+    arg2.use();
+    
     JITCompiler::JumpList slowPath;
     
     if (!isKnownInteger(node.child1()))
@@ -299,7 +307,7 @@
     
     done.link(&m_jit);
         
-    jsValueResult(resultGPR, m_compileIndex);
+    jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
 }
 
 void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator, Node& node)
@@ -447,15 +455,16 @@
         if ((childInfo.registerFormat() | DataFormatJS) == DataFormatJSDouble) {
             DoubleOperand op1(this, node.child1());
             GPRTemporary result(this);
+            op1.use();
             numberToInt32(op1.fpr(), result.gpr());
-            integerResult(result.gpr(), m_compileIndex);
+            integerResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
             break;
         }
 
         JSValueOperand op1(this, node.child1());
         GPRTemporary result(this, op1);
         valueToInt32(op1, result.gpr());
-        integerResult(result.gpr(), m_compileIndex);
+        integerResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -474,7 +483,7 @@
         JSValueOperand op1(this, node.child1());
         GPRTemporary result(this);
         valueToNumber(op1, result.gpr());
-        jsValueResult(result.gpr(), m_compileIndex);
+        jsValueResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -537,6 +546,9 @@
     
         FPRReg op1FPR = op1Double.fpr();
         FPRReg op2FPR = op2Double.fpr();
+        
+        op1.use();
+        op2.use();
     
         JITCompiler::Jump firstOpNotInt;
         JITCompiler::Jump secondOpNotInt;
@@ -623,17 +635,19 @@
         
         done.link(&m_jit);
     
-        jsValueResult(X86Registers::edx, m_compileIndex);
+        jsValueResult(X86Registers::edx, m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
     case LogicalNot: {
         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)));
@@ -648,7 +662,7 @@
         fastCase.link(&m_jit);
 
         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
-        jsValueResult(resultGPR, m_compileIndex);
+        jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -703,6 +717,9 @@
         GPRReg propertyGPR = property.gpr();
         GPRReg storageGPR = storage.gpr();
         GPRReg cleanIndexGPR = cleanIndex.gpr();
+        
+        base.use();
+        property.use();
 
         JITCompiler::Jump baseNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
 
@@ -739,7 +756,7 @@
 
         done.link(&m_jit);
 
-        jsValueResult(storageGPR, m_compileIndex);
+        jsValueResult(storageGPR, m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -751,12 +768,15 @@
         GPRReg arg1GPR = arg1.gpr();
         GPRReg arg2GPR = arg2.gpr();
         GPRReg arg3GPR = arg3.gpr();
+        
+        arg1.use();
+        arg2.use();
+        arg3.use();
         flushRegisters();
 
-        GPRResult result(this);
         callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
 
-        noResult(m_compileIndex);
+        noResult(m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -765,12 +785,20 @@
         GPRReg baseGPR = base.gpr();
         GPRTemporary result(this, base);
         GPRReg resultGPR = result.gpr();
+        GPRReg scratchGPR;
+        
+        if (resultGPR == baseGPR)
+            scratchGPR = tryAllocate();
+        else
+            scratchGPR = resultGPR;
+        
+        base.use();
 
         JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
 
-        cachedGetById(baseGPR, resultGPR, node.identifierNumber(), notCell);
+        cachedGetById(baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell);
 
-        jsValueResult(resultGPR, m_compileIndex);
+        jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -779,12 +807,19 @@
         GPRReg baseGPR = base.gpr();
         GPRTemporary result(this, base);
         GPRReg resultGPR = result.gpr();
+        GPRReg scratchGPR;
+        if (resultGPR == baseGPR)
+            scratchGPR = tryAllocate();
+        else
+            scratchGPR = resultGPR;
+        
+        base.use();
 
         JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
 
-        cachedGetMethod(baseGPR, resultGPR, node.identifierNumber(), notCell);
+        cachedGetMethod(baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell);
 
-        jsValueResult(resultGPR, m_compileIndex);
+        jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -794,12 +829,16 @@
         GPRTemporary scratch(this);
         GPRReg valueGPR = value.gpr();
         GPRReg baseGPR = base.gpr();
+        GPRReg scratchGPR = scratch.gpr();
         
+        base.use();
+        value.use();
+        
         JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
 
-        cachedPutById(baseGPR, valueGPR, scratch.gpr(), node.identifierNumber(), NotDirect, notCell);
+        cachedPutById(baseGPR, valueGPR, scratchGPR, node.identifierNumber(), NotDirect, notCell);
 
-        noResult(m_compileIndex);
+        noResult(m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -810,11 +849,14 @@
         GPRReg valueGPR = value.gpr();
         GPRReg baseGPR = base.gpr();
         
+        base.use();
+        value.use();
+        
         JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
 
         cachedPutById(baseGPR, valueGPR, scratch.gpr(), node.identifierNumber(), Direct, notCell);
 
-        noResult(m_compileIndex);
+        noResult(m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -924,6 +966,10 @@
         GPRReg baseReg = base.gpr();
         GPRReg prototypeReg = prototype.gpr();
         GPRReg scratchReg = scratch.gpr();
+        
+        value.use();
+        base.use();
+        prototype.use();
 
         // Check that operands are cells (base is checked by CheckHasInstance, so we can just assert).
         MacroAssembler::Jump valueNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueReg, GPRInfo::tagMaskRegister);
@@ -973,7 +1019,7 @@
 
         wasNotInstance.link(&m_jit);
         wasNotDefaultHasInstance.link(&m_jit);
-        jsValueResult(scratchReg, m_compileIndex);
+        jsValueResult(scratchReg, m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (91279 => 91280)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-07-19 18:55:16 UTC (rev 91280)
@@ -849,6 +849,11 @@
         Node& baseNode = m_jit.graph()[node.child1()];
         if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+
+        base.use();
+        property.use();
+        value.use();
+        
         MacroAssembler::Jump withinArrayBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
 
         // Code to handle put beyond array bounds.
@@ -883,7 +888,7 @@
 
         wasBeyondArrayBounds.link(&m_jit);
 
-        noResult(m_compileIndex);
+        noResult(m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -961,12 +966,21 @@
     case GetById: {
         SpeculateCellOperand base(this, node.child1());
         GPRTemporary result(this, base);
-
+        
+        GPRReg baseGPR = base.gpr();
         GPRReg resultGPR = result.gpr();
+        GPRReg scratchGPR;
+        
+        if (resultGPR == baseGPR)
+            scratchGPR = tryAllocate();
+        else
+            scratchGPR = resultGPR;
+        
+        base.use();
 
-        cachedGetById(base.gpr(), resultGPR, node.identifierNumber());
+        cachedGetById(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
 
-        jsValueResult(resultGPR, m_compileIndex);
+        jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
         
@@ -974,11 +988,20 @@
         SpeculateCellOperand base(this, node.child1());
         GPRTemporary result(this, base);
 
+        GPRReg baseGPR = base.gpr();
         GPRReg resultGPR = result.gpr();
+        GPRReg scratchGPR;
+        
+        if (resultGPR == baseGPR)
+            scratchGPR = tryAllocate();
+        else
+            scratchGPR = resultGPR;
+        
+        base.use();
 
-        cachedGetMethod(base.gpr(), resultGPR, node.identifierNumber());
+        cachedGetMethod(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
 
-        jsValueResult(resultGPR, m_compileIndex);
+        jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -986,10 +1009,17 @@
         SpeculateCellOperand base(this, node.child1());
         JSValueOperand value(this, node.child2());
         GPRTemporary scratch(this);
+        
+        GPRReg baseGPR = base.gpr();
+        GPRReg valueGPR = value.gpr();
+        GPRReg scratchGPR = scratch.gpr();
+        
+        base.use();
+        value.use();
 
-        cachedPutById(base.gpr(), value.gpr(), scratch.gpr(), node.identifierNumber(), NotDirect);
+        cachedPutById(baseGPR, valueGPR, scratchGPR, node.identifierNumber(), NotDirect);
         
-        noResult(m_compileIndex);
+        noResult(m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 
@@ -997,10 +1027,17 @@
         SpeculateCellOperand base(this, node.child1());
         JSValueOperand value(this, node.child2());
         GPRTemporary scratch(this);
+        
+        GPRReg baseGPR = base.gpr();
+        GPRReg valueGPR = value.gpr();
+        GPRReg scratchGPR = scratch.gpr();
+        
+        base.use();
+        value.use();
 
-        cachedPutById(base.gpr(), value.gpr(), scratch.gpr(), node.identifierNumber(), Direct);
+        cachedPutById(baseGPR, valueGPR, scratchGPR, node.identifierNumber(), Direct);
 
-        noResult(m_compileIndex);
+        noResult(m_compileIndex, UseChildrenCalledExplicitly);
         break;
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (91279 => 91280)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2011-07-19 18:55:16 UTC (rev 91280)
@@ -293,6 +293,11 @@
             m_gprOrInvalid = m_jit->fillSpeculateIntStrict(index());
         return m_gprOrInvalid;
     }
+    
+    void use()
+    {
+        m_jit->use(m_index);
+    }
 
 private:
     SpeculativeJIT* m_jit;
@@ -365,6 +370,11 @@
             m_gprOrInvalid = m_jit->fillSpeculateCell(index());
         return m_gprOrInvalid;
     }
+    
+    void use()
+    {
+        m_jit->use(m_index);
+    }
 
 private:
     SpeculativeJIT* m_jit;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to