]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - dfg/DFGVariableEventStream.cpp
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / dfg / DFGVariableEventStream.cpp
index a3f2ac6ff7f1770665cd55aff86a78f9194454e2..c209ce45b2e4047b9c2036324f0259f4034f6331 100644 (file)
@@ -29,8 +29,9 @@
 #if ENABLE(DFG_JIT)
 
 #include "CodeBlock.h"
+#include "DFGJITCode.h"
 #include "DFGValueSource.h"
-#include "Operations.h"
+#include "JSCInlines.h"
 #include <wtf/DataLog.h>
 #include <wtf/HashMap.h>
 
@@ -109,12 +110,12 @@ void VariableEventStream::reconstruct(
     CodeBlock* codeBlock, CodeOrigin codeOrigin, MinifiedGraph& graph,
     unsigned index, Operands<ValueRecovery>& valueRecoveries) const
 {
-    ASSERT(codeBlock->getJITType() == JITCode::DFGJIT);
+    ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
     CodeBlock* baselineCodeBlock = codeBlock->baselineVersion();
     
     unsigned numVariables;
     if (codeOrigin.inlineCallFrame)
-        numVariables = baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame)->m_numCalleeRegisters + codeOrigin.inlineCallFrame->stackOffset;
+        numVariables = baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame)->m_numCalleeRegisters + VirtualRegister(codeOrigin.inlineCallFrame->stackOffset).toLocal() + 1;
     else
         numVariables = baselineCodeBlock->m_numCalleeRegisters;
     
@@ -123,8 +124,10 @@ void VariableEventStream::reconstruct(
     // reflect this.
     if (!index) {
         valueRecoveries = Operands<ValueRecovery>(codeBlock->numParameters(), numVariables);
-        for (size_t i = 0; i < valueRecoveries.size(); ++i)
-            valueRecoveries[i] = ValueRecovery::alreadyInJSStack();
+        for (size_t i = 0; i < valueRecoveries.size(); ++i) {
+            valueRecoveries[i] = ValueRecovery::displacedInJSStack(
+                VirtualRegister(valueRecoveries.operandForIndex(i)), DataFormatJS);
+        }
         return;
     }
     
@@ -133,12 +136,10 @@ void VariableEventStream::reconstruct(
     while (at(startIndex).kind() != Reset)
         startIndex--;
     
-#if DFG_ENABLE(DEBUG_VERBOSE)
-    dataLogF("Computing OSR exit recoveries starting at seq#%u.\n", startIndex);
-#endif
-
     // Step 2: Create a mock-up of the DFG's state and execute the events.
     Operands<ValueSource> operandSources(codeBlock->numParameters(), numVariables);
+    for (unsigned i = operandSources.size(); i--;)
+        operandSources[i] = ValueSource(SourceIsDead);
     HashMap<MinifiedID, MinifiedGenerationInfo> generationInfos;
     for (unsigned i = startIndex; i < index; ++i) {
         const VariableEvent& event = at(i);
@@ -162,12 +163,12 @@ void VariableEventStream::reconstruct(
             break;
         }
         case MovHintEvent:
-            if (operandSources.hasOperand(event.operand()))
-                operandSources.setOperand(event.operand(), ValueSource(event.id()));
+            if (operandSources.hasOperand(event.bytecodeRegister()))
+                operandSources.setOperand(event.bytecodeRegister(), ValueSource(event.id()));
             break;
         case SetLocalEvent:
-            if (operandSources.hasOperand(event.operand()))
-                operandSources.setOperand(event.operand(), ValueSource::forDataFormat(event.dataFormat()));
+            if (operandSources.hasOperand(event.bytecodeRegister()))
+                operandSources.setOperand(event.bytecodeRegister(), ValueSource::forDataFormat(event.machineRegister(), event.dataFormat()));
             break;
         default:
             RELEASE_ASSERT_NOT_REACHED();
@@ -191,96 +192,8 @@ void VariableEventStream::reconstruct(
         
         MinifiedGenerationInfo info = generationInfos.get(source.id());
         if (info.format == DataFormatNone) {
-            // Try to see if there is an alternate node that would contain the value we want.
-            // There are four possibilities:
-            //
-            // Int32ToDouble: We can use this in place of the original node, but
-            //    we'd rather not; so we use it only if it is the only remaining
-            //    live version.
-            //
-            // ValueToInt32: If the only remaining live version of the value is
-            //    ValueToInt32, then we can use it.
-            //
-            // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
-            //    then the only remaining uses are ones that want a properly formed number
-            //    rather than a UInt32 intermediate.
-            //
-            // DoubleAsInt32: Same as UInt32ToNumber.
-            //
-            // The reverse of the above: This node could be a UInt32ToNumber, but its
-            //    alternative is still alive. This means that the only remaining uses of
-            //    the number would be fine with a UInt32 intermediate.
-            
-            bool found = false;
-            
-            if (node && node->op() == UInt32ToNumber) {
-                MinifiedID id = node->child1();
-                if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, graph.at(id)))
-                    continue;
-                info = generationInfos.get(id);
-                if (info.format != DataFormatNone)
-                    found = true;
-            }
-            
-            if (!found) {
-                MinifiedID int32ToDoubleID;
-                MinifiedID valueToInt32ID;
-                MinifiedID uint32ToNumberID;
-                MinifiedID doubleAsInt32ID;
-                
-                HashMap<MinifiedID, MinifiedGenerationInfo>::iterator iter = generationInfos.begin();
-                HashMap<MinifiedID, MinifiedGenerationInfo>::iterator end = generationInfos.end();
-                for (; iter != end; ++iter) {
-                    MinifiedID id = iter->key;
-                    node = graph.at(id);
-                    if (!node)
-                        continue;
-                    if (!node->hasChild1())
-                        continue;
-                    if (node->child1() != source.id())
-                        continue;
-                    if (iter->value.format == DataFormatNone)
-                        continue;
-                    switch (node->op()) {
-                    case Int32ToDouble:
-                    case ForwardInt32ToDouble:
-                        int32ToDoubleID = id;
-                        break;
-                    case ValueToInt32:
-                        valueToInt32ID = id;
-                        break;
-                    case UInt32ToNumber:
-                        uint32ToNumberID = id;
-                        break;
-                    case DoubleAsInt32:
-                        doubleAsInt32ID = id;
-                        break;
-                    default:
-                        break;
-                    }
-                }
-                
-                MinifiedID idToUse;
-                if (!!doubleAsInt32ID)
-                    idToUse = doubleAsInt32ID;
-                else if (!!int32ToDoubleID)
-                    idToUse = int32ToDoubleID;
-                else if (!!valueToInt32ID)
-                    idToUse = valueToInt32ID;
-                else if (!!uint32ToNumberID)
-                    idToUse = uint32ToNumberID;
-                
-                if (!!idToUse) {
-                    info = generationInfos.get(idToUse);
-                    ASSERT(info.format != DataFormatNone);
-                    found = true;
-                }
-            }
-            
-            if (!found) {
-                valueRecoveries[i] = ValueRecovery::constant(jsUndefined());
-                continue;
-            }
+            valueRecoveries[i] = ValueRecovery::constant(jsUndefined());
+            continue;
         }
         
         ASSERT(info.format != DataFormatNone);
@@ -303,13 +216,6 @@ void VariableEventStream::reconstruct(
         valueRecoveries[i] =
             ValueRecovery::displacedInJSStack(static_cast<VirtualRegister>(info.u.virtualReg), info.format);
     }
-    
-    // Step 4: Make sure that for locals that coincide with true call frame headers, the exit compiler knows
-    // that those values don't have to be recovered. Signal this by using ValueRecovery::alreadyInJSStack()
-    for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
-        for (unsigned i = JSStack::CallFrameHeaderSize; i--;)
-            valueRecoveries.setLocal(inlineCallFrame->stackOffset - i - 1, ValueRecovery::alreadyInJSStack());
-    }
 }
 
 } } // namespace JSC::DFG