Title: [90502] trunk/Source/_javascript_Core
Revision
90502
Author
[email protected]
Date
2011-07-06 14:40:11 -0700 (Wed, 06 Jul 2011)

Log Message

2011-07-06  Filip Pizlo  <[email protected]>

        DFG JIT op_call implementation will flush registers even when those registers are dead
        https://bugs.webkit.org/show_bug.cgi?id=64023

        Reviewed by Gavin Barraclough.

        * dfg/DFGJITCodeGenerator.cpp:
        (JSC::DFG::JITCodeGenerator::emitCall):
        * dfg/DFGJITCodeGenerator.h:
        (JSC::DFG::JITCodeGenerator::integerResult):
        (JSC::DFG::JITCodeGenerator::noResult):
        (JSC::DFG::JITCodeGenerator::cellResult):
        (JSC::DFG::JITCodeGenerator::jsValueResult):
        (JSC::DFG::JITCodeGenerator::doubleResult):
        * dfg/DFGNonSpeculativeJIT.cpp:
        (JSC::DFG::NonSpeculativeJIT::compile):
        * dfg/DFGSpeculativeJIT.cpp:
        (JSC::DFG::SpeculativeJIT::compile):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (90501 => 90502)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-06 21:40:11 UTC (rev 90502)
@@ -1,5 +1,25 @@
 2011-07-06  Filip Pizlo  <[email protected]>
 
+        DFG JIT op_call implementation will flush registers even when those registers are dead
+        https://bugs.webkit.org/show_bug.cgi?id=64023
+
+        Reviewed by Gavin Barraclough.
+
+        * dfg/DFGJITCodeGenerator.cpp:
+        (JSC::DFG::JITCodeGenerator::emitCall):
+        * dfg/DFGJITCodeGenerator.h:
+        (JSC::DFG::JITCodeGenerator::integerResult):
+        (JSC::DFG::JITCodeGenerator::noResult):
+        (JSC::DFG::JITCodeGenerator::cellResult):
+        (JSC::DFG::JITCodeGenerator::jsValueResult):
+        (JSC::DFG::JITCodeGenerator::doubleResult):
+        * dfg/DFGNonSpeculativeJIT.cpp:
+        (JSC::DFG::NonSpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2011-07-06  Filip Pizlo  <[email protected]>
+
         DFG speculative JIT may crash when speculating int on a non-int JSConstant.
         https://bugs.webkit.org/show_bug.cgi?id=64017
 

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (90501 => 90502)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-07-06 21:40:11 UTC (rev 90502)
@@ -430,8 +430,13 @@
     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::emitCall(Node& node, GPRReg targetGPR)
+void JITCodeGenerator::emitCall(Node& node)
 {
+    NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()];
+    JSValueOperand callee(this, calleeNodeIndex);
+    GPRReg calleeGPR = callee.gpr();
+    use(calleeNodeIndex);
+    
     // the call instruction's first child is either the function (normal call) or the
     // receiver (method call). subsequent children are the arguments.
     int numArgs = node.numChildren() - 1;
@@ -450,15 +455,17 @@
     m_jit.storePtr(GPRInfo::callFrameRegister, addressOfCallData(RegisterFile::CallerFrame));
     
     for (int argIdx = 0; argIdx < numArgs; argIdx++) {
-        JSValueOperand arg(this, m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx]);
+        NodeIndex argNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx];
+        JSValueOperand arg(this, argNodeIndex);
         GPRReg argGPR = arg.gpr();
+        use(argNodeIndex);
         
         m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx));
     }
     
     switch (node.op) {
     case Call:
-        m_jit.storePtr(targetGPR, addressOfCallData(RegisterFile::Callee));
+        m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
         break;
         
     default:
@@ -475,8 +482,8 @@
     
     switch (node.op) {
     case Call:
-        slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, targetGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
-        m_jit.loadPtr(MacroAssembler::Address(targetGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
+        slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
+        m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
         m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain));
         break;
         
@@ -503,7 +510,7 @@
     
     m_jit.move(GPRInfo::returnValueGPR, resultGPR);
     
-    jsValueResult(resultGPR, m_compileIndex);
+    jsValueResult(resultGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
     
     m_jit.addJSCall(fastCall, slowCall, targetToCheck, true, m_jit.graph()[m_compileIndex].exceptionInfo);
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (90501 => 90502)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-07-06 21:40:11 UTC (rev 90502)
@@ -64,6 +64,8 @@
         SpillOrderInteger = 5,  // needs spill and box
         SpillOrderDouble = 6,   // needs spill and convert
     };
+    
+    enum UseChildrenMode { CallUseChildren, UseChildrenCalledExplicitly };
 
 
 public:
@@ -528,7 +530,7 @@
         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register)));
     }
     
-    void emitCall(Node&, GPRReg targetGPR);
+    void emitCall(Node&);
 
     // Called once a node has completed code generation but prior to setting
     // its result, to free up its children. (This must happen prior to setting
@@ -538,10 +540,11 @@
 
     // These method called to initialize the the GenerationInfo
     // to describe the result of an operation.
-    void integerResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatInteger)
+    void integerResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatInteger, UseChildrenMode mode = CallUseChildren)
     {
         Node& node = m_jit.graph()[nodeIndex];
-        useChildren(node);
+        if (mode == CallUseChildren)
+            useChildren(node);
 
         VirtualRegister virtualRegister = node.virtualRegister();
         GenerationInfo& info = m_generationInfo[virtualRegister];
@@ -557,38 +560,43 @@
             info.initJSValue(nodeIndex, node.refCount(), reg, format);
         }
     }
-    void noResult(NodeIndex nodeIndex)
+    void noResult(NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
     {
+        if (mode == UseChildrenCalledExplicitly)
+            return;
         Node& node = m_jit.graph()[nodeIndex];
         useChildren(node);
     }
-    void cellResult(GPRReg reg, NodeIndex nodeIndex)
+    void cellResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
     {
         Node& node = m_jit.graph()[nodeIndex];
-        useChildren(node);
+        if (mode == CallUseChildren)
+            useChildren(node);
 
         VirtualRegister virtualRegister = node.virtualRegister();
         m_gprs.retain(reg, virtualRegister, SpillOrderCell);
         GenerationInfo& info = m_generationInfo[virtualRegister];
         info.initCell(nodeIndex, node.refCount(), reg);
     }
-    void jsValueResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatJS)
+    void jsValueResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
     {
         if (format == DataFormatJSInteger)
             m_jit.jitAssertIsJSInt32(reg);
         
         Node& node = m_jit.graph()[nodeIndex];
-        useChildren(node);
+        if (mode == CallUseChildren)
+            useChildren(node);
 
         VirtualRegister virtualRegister = node.virtualRegister();
         m_gprs.retain(reg, virtualRegister, SpillOrderJS);
         GenerationInfo& info = m_generationInfo[virtualRegister];
         info.initJSValue(nodeIndex, node.refCount(), reg, format);
     }
-    void doubleResult(FPRReg reg, NodeIndex nodeIndex)
+    void doubleResult(FPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
     {
         Node& node = m_jit.graph()[nodeIndex];
-        useChildren(node);
+        if (mode == CallUseChildren)
+            useChildren(node);
 
         VirtualRegister virtualRegister = node.virtualRegister();
         m_fprs.retain(reg, virtualRegister, SpillOrderDouble);

Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (90501 => 90502)


--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-07-06 21:40:11 UTC (rev 90502)
@@ -1054,9 +1054,7 @@
         break;
         
     case Call:
-        JSValueOperand callee(this, m_jit.graph().m_varArgChildren[node.firstChild()]);
-        GPRReg calleeGPR = callee.gpr();
-        emitCall(node, calleeGPR);
+        emitCall(node);
         break;
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (90501 => 90502)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-07-06 21:40:11 UTC (rev 90502)
@@ -1133,9 +1133,7 @@
         break;
         
     case Call:
-        JSValueOperand callee(this, m_jit.graph().m_varArgChildren[node.firstChild()]);
-        GPRReg calleeGPR = callee.gpr();
-        emitCall(node, calleeGPR);
+        emitCall(node);
         break;
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to