DFG JIT should not eagerly initialize integer tags in the register file
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 24 Sep 2011 21:23:24 +0000 (21:23 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 24 Sep 2011 21:23:24 +0000 (21:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=68763

Reviewed by Oliver Hunt.

* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::ValueRecovery::dump):
(JSC::DFG::OSRExit::OSRExit):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::ValueRecovery::alreadyInRegisterFileAsUnboxedInt32):
(JSC::DFG::OSRExit::operandForArgument):
(JSC::DFG::OSRExit::operandForIndex):
(JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95910 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

index af4dcc9..6695628 100644 (file)
@@ -1,3 +1,23 @@
+2011-09-24  Filip Pizlo  <fpizlo@apple.com>
+
+        DFG JIT should not eagerly initialize integer tags in the register file
+        https://bugs.webkit.org/show_bug.cgi?id=68763
+
+        Reviewed by Oliver Hunt.
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::ValueRecovery::dump):
+        (JSC::DFG::OSRExit::OSRExit):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::ValueRecovery::alreadyInRegisterFileAsUnboxedInt32):
+        (JSC::DFG::OSRExit::operandForArgument):
+        (JSC::DFG::OSRExit::operandForIndex):
+        (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
+
 2011-09-23  Yuqiang Xian  <yuqiang.xian@intel.com>
 
         Add JSVALUE32_64 support to DFG JIT
index 08a7643..fa541eb 100644 (file)
@@ -201,6 +201,7 @@ void JITCompiler::exitSpeculativeWithOSR(const OSRExit& exit, SpeculationRecover
             break;
             
         case UnboxedInt32InGPR:
+        case AlreadyInRegisterFileAsUnboxedInt32:
             haveUnboxedInt32s = true;
             break;
             
@@ -229,8 +230,19 @@ void JITCompiler::exitSpeculativeWithOSR(const OSRExit& exit, SpeculationRecover
     if (haveUnboxedInt32s) {
         for (int index = 0; index < exit.numberOfRecoveries(); ++index) {
             const ValueRecovery& recovery = exit.valueRecovery(index);
-            if (recovery.technique() == UnboxedInt32InGPR && recovery.gpr() != alreadyBoxed)
-                orPtr(GPRInfo::tagTypeNumberRegister, recovery.gpr());
+            switch (recovery.technique()) {
+            case UnboxedInt32InGPR:
+                if (recovery.gpr() != alreadyBoxed)
+                    orPtr(GPRInfo::tagTypeNumberRegister, recovery.gpr());
+                break;
+                
+            case AlreadyInRegisterFileAsUnboxedInt32:
+                store32(Imm32(static_cast<uint32_t>(TagTypeNumber >> 32)), tagFor(static_cast<VirtualRegister>(exit.operandForIndex(index))));
+                break;
+                
+            default:
+                break;
+            }
         }
     }
     
index eb05730..4dbc74a 100644 (file)
@@ -164,6 +164,9 @@ void ValueRecovery::dump(FILE* out) const
     case AlreadyInRegisterFile:
         fprintf(out, "-");
         break;
+    case AlreadyInRegisterFileAsUnboxedInt32:
+        fprintf(out, "(int32)");
+        break;
     case InGPR:
         fprintf(out, "%%%s", GPRInfo::debugName(gpr()));
         break;
@@ -200,9 +203,9 @@ OSRExit::OSRExit(MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned recov
 {
     ASSERT(m_bytecodeIndex != std::numeric_limits<uint32_t>::max());
     for (unsigned argument = 0; argument < m_arguments.size(); ++argument)
-        m_arguments[argument] = jit->computeValueRecoveryFor(jit->m_arguments[argument]);
+        m_arguments[argument] = jit->computeValueRecoveryFor(operandForArgument(argument), jit->m_arguments[argument]);
     for (unsigned variable = 0; variable < m_variables.size(); ++variable)
-        m_variables[variable] = jit->computeValueRecoveryFor(jit->m_variables[variable]);
+        m_variables[variable] = jit->computeValueRecoveryFor(variable, jit->m_variables[variable]);
 }
 
 #ifndef NDEBUG
@@ -2206,23 +2209,9 @@ void SpeculativeJIT::checkArgumentTypes()
     }
 }
 
-// For any vars that we will be treating as numeric, write 0 to
-// the var on entry. Throughout the block we will only read/write
-// to the payload, by writing the tag now we prevent the GC from
-// misinterpreting values as pointers.
-void SpeculativeJIT::initializeVariableTypes()
-{
-    ASSERT(!m_compileIndex);
-    for (int var = 0; var < (int)m_jit.graph().predictions().numberOfVariables(); ++var) {
-        if (isInt32Prediction(m_jit.graph().getPrediction(var)))
-            m_jit.storePtr(GPRInfo::tagTypeNumberRegister, JITCompiler::addressFor((VirtualRegister)var));
-    }
-}
-
 bool SpeculativeJIT::compile()
 {
     checkArgumentTypes();
-    initializeVariableTypes();
 
     ASSERT(!m_compileIndex);
     for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block)
@@ -2231,10 +2220,13 @@ bool SpeculativeJIT::compile()
     return true;
 }
 
-ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource)
+ValueRecovery SpeculativeJIT::computeValueRecoveryFor(int operand, const ValueSource& valueSource)
 {
-    if (!valueSource.isSet())
+    if (!valueSource.isSet()) {
+        if (m_bytecodeIndexForOSR && isInt32Prediction(m_jit.graph().getPrediction(operand)))
+            return ValueRecovery::alreadyInRegisterFileAsUnboxedInt32();
         return ValueRecovery::alreadyInRegisterFile();
+    }
 
     if (m_jit.isConstant(valueSource.nodeIndex()))
         return ValueRecovery::constant(m_jit.valueOfJSConstant(valueSource.nodeIndex()));
index c74d7c2..5b4fe1b 100644 (file)
@@ -102,6 +102,8 @@ private:
 enum ValueRecoveryTechnique {
     // It's already in the register file at the right location.
     AlreadyInRegisterFile,
+    // It's already in the register file but unboxed.
+    AlreadyInRegisterFileAsUnboxedInt32,
     // It's in a register.
     InGPR,
     UnboxedInt32InGPR,
@@ -131,6 +133,13 @@ public:
         return result;
     }
     
+    static ValueRecovery alreadyInRegisterFileAsUnboxedInt32()
+    {
+        ValueRecovery result;
+        result.m_technique = AlreadyInRegisterFileAsUnboxedInt32;
+        return result;
+    }
+    
     static ValueRecovery inGPR(GPRReg gpr, DataFormat dataFormat)
     {
         ASSERT(dataFormat != DataFormatNone);
@@ -273,10 +282,14 @@ struct OSRExit {
     {
         return index - m_arguments.size();
     }
+    int operandForArgument(int argument) const
+    {
+        return argument - m_arguments.size() - RegisterFile::CallFrameHeaderSize;
+    }
     int operandForIndex(int index) const
     {
         if (index < (int)m_arguments.size())
-            return index - m_arguments.size() - RegisterFile::CallFrameHeaderSize;
+            return operandForArgument(index);
         return index - m_arguments.size();
     }
     
@@ -336,7 +349,6 @@ private:
     void compile(BasicBlock&);
 
     void checkArgumentTypes();
-    void initializeVariableTypes();
 
     bool isInteger(NodeIndex nodeIndex)
     {
@@ -590,11 +602,11 @@ private:
     int m_lastSetOperand;
     uint32_t m_bytecodeIndexForOSR;
     
-    ValueRecovery computeValueRecoveryFor(const ValueSource&);
+    ValueRecovery computeValueRecoveryFor(int operand, const ValueSource&);
 
     ValueRecovery computeValueRecoveryFor(int operand)
     {
-        return computeValueRecoveryFor(valueSourceForOperand(operand));
+        return computeValueRecoveryFor(operand, valueSourceForOperand(operand));
     }
 };