Title: [118126] branches/dfgopt/Source/_javascript_Core
Revision
118126
Author
[email protected]
Date
2012-05-22 23:07:53 -0700 (Tue, 22 May 2012)

Log Message

Unreviewed, rollout http://trac.webkit.org/changeset/118108
https://bugs.webkit.org/show_bug.cgi?id=87161

The redundant store elimination is overzealous in some cases, because
it fails to catch implicit reads of captured local variables.

* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGArgumentsSimplificationPhase.cpp:
(JSC::DFG::ArgumentsSimplificationPhase::run):
(JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse):
(JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUses):
(JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse):
* dfg/DFGCSEPhase.cpp:
(CSEPhase):
(JSC::DFG::CSEPhase::setReplacement):
(JSC::DFG::CSEPhase::performNodeCSE):
* dfg/DFGNode.h:
(Node):
(JSC::DFG::Node::hasConstant):
(JSC::DFG::Node::valueOfJSConstant):
(JSC::DFG::Node::hasStructureTransitionData):
* dfg/DFGNodeType.h:
(DFG):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):

Modified Paths

Diff

Modified: branches/dfgopt/Source/_javascript_Core/ChangeLog (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/ChangeLog	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/ChangeLog	2012-05-23 06:07:53 UTC (rev 118126)
@@ -1,5 +1,40 @@
 2012-05-22  Filip Pizlo  <[email protected]>
 
+        Unreviewed, rollout http://trac.webkit.org/changeset/118108
+        https://bugs.webkit.org/show_bug.cgi?id=87161
+
+        The redundant store elimination is overzealous in some cases, because
+        it fails to catch implicit reads of captured local variables.
+
+        * dfg/DFGAbstractState.cpp:
+        (JSC::DFG::AbstractState::execute):
+        * dfg/DFGArgumentsSimplificationPhase.cpp:
+        (JSC::DFG::ArgumentsSimplificationPhase::run):
+        (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse):
+        (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUses):
+        (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse):
+        * dfg/DFGCSEPhase.cpp:
+        (CSEPhase):
+        (JSC::DFG::CSEPhase::setReplacement):
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        * dfg/DFGNode.h:
+        (Node):
+        (JSC::DFG::Node::hasConstant):
+        (JSC::DFG::Node::valueOfJSConstant):
+        (JSC::DFG::Node::hasStructureTransitionData):
+        * dfg/DFGNodeType.h:
+        (DFG):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+
+2012-05-22  Filip Pizlo  <[email protected]>
+
         DFG CSE should do redundant store elimination
         https://bugs.webkit.org/show_bug.cgi?id=87161
 

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGAbstractState.cpp (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGAbstractState.cpp	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGAbstractState.cpp	2012-05-23 06:07:53 UTC (rev 118126)
@@ -264,8 +264,7 @@
         
     switch (node.op()) {
     case JSConstant:
-    case WeakJSConstant:
-    case PhantomArguments: {
+    case WeakJSConstant: {
         forNode(nodeIndex).set(m_graph.valueOfJSConstant(nodeIndex));
         node.setCanExit(false);
         break;
@@ -1412,7 +1411,6 @@
     }
             
     case PutStructure:
-    case PhantomPutStructure:
         node.setCanExit(false);
         clobberStructures(indexInBlock);
         forNode(node.child1()).set(node.structureTransitionData().newStructure);

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp	2012-05-23 06:07:53 UTC (rev 118126)
@@ -178,7 +178,7 @@
                         // a variable that we think is aliased to the arguments, then it
                         // may escape at this point. In future, we could track transitive
                         // aliasing. But not yet.
-                        observeBadArgumentsUse(node, node.child1());
+                        observeBadArgumentsUse(node.child1());
                         
                         if (variableAccessData->isCaptured())
                             break;
@@ -269,7 +269,7 @@
                         // That's so awful and pretty much impossible since it would
                         // imply that the arguments were predicted integer, but it's
                         // good to be defensive and thorough.
-                        observeBadArgumentsUse(node, node.child2());
+                        observeBadArgumentsUse(node.child2());
                         observeProperArgumentsUse(node, node.child1());
                         break;
                     }
@@ -392,6 +392,31 @@
                     
                     VariableAccessData* variableAccessData = node.variableAccessData();
                     
+                    // If this is a store into the arguments register for an InlineCallFrame*
+                    // that does not create arguments, then kill it.
+                    int argumentsRegister =
+                        m_graph.uncheckedArgumentsRegisterFor(node.codeOrigin);
+                    if ((variableAccessData->local() == argumentsRegister
+                         || variableAccessData->local()
+                             == unmodifiedArgumentsRegister(argumentsRegister))
+                        && !m_createsArguments.contains(source.codeOrigin.inlineCallFrame)) {
+                        // Find the Flush. It should be the next instruction.
+                        Node& flush = m_graph[block->at(indexInBlock + 1)];
+                        ASSERT(flush.op() == Flush);
+                        ASSERT(flush.variableAccessData() == variableAccessData);
+                        ASSERT(flush.child1() == nodeIndex);
+                        // Be defensive in release mode.
+                        if (flush.op() != Flush
+                            || flush.variableAccessData() != variableAccessData
+                            || flush.child1() != nodeIndex)
+                            break;
+                        flush.setOpAndDefaultFlags(Nop);
+                        m_graph.clearAndDerefChild1(flush);
+                        flush.setRefCount(0);
+                        changed = true;
+                        break;
+                    }
+                    
                     if (variableAccessData->isCaptured())
                         break;
                     
@@ -558,35 +583,6 @@
             insertionSet.execute(*block);
         }
         
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-                NodeIndex nodeIndex = block->at(indexInBlock);
-                Node& node = m_graph[nodeIndex];
-                if (!node.shouldGenerate())
-                    continue;
-                if (node.op() != CreateArguments)
-                    continue;
-                // If this is a CreateArguments for an InlineCallFrame* that does
-                // not create arguments, then replace it with a PhantomArguments.
-                // PhantomArguments is a constant that represents JSValue() (the
-                // empty value) in DFG and arguments creation for OSR exit.
-                if (m_createsArguments.contains(node.codeOrigin.inlineCallFrame))
-                    continue;
-                Node phantom(Phantom, node.codeOrigin);
-                phantom.children = node.children;
-                phantom.ref();
-                node.setOpAndDefaultFlags(PhantomArguments);
-                node.children.reset();
-                NodeIndex phantomNodeIndex = m_graph.size();
-                m_graph.append(phantom);
-                insertionSet.append(indexInBlock, phantomNodeIndex);
-            }
-            insertionSet.execute(*block);
-        }
-        
         if (changed)
             m_graph.collectGarbage();
         
@@ -601,43 +597,32 @@
             DefaultHash<VariableAccessData*>::Hash,
             NullableHashTraits<VariableAccessData*> > m_argumentsAliasing;
 
-    void observeBadArgumentsUse(Node& node, Edge edge)
+    void observeBadArgumentsUse(Edge edge)
     {
         if (!edge)
             return;
         
         Node& child = m_graph[edge];
-        switch (child.op()) {
-        case CreateArguments: {
-            if (node.codeOrigin.inlineCallFrame != child.codeOrigin.inlineCallFrame)
-                m_createsArguments.add(child.codeOrigin.inlineCallFrame);
-            break;
+        if (child.op() != GetLocal)
+            return;
+        
+        if (child.local() == m_graph.uncheckedArgumentsRegisterFor(child.codeOrigin)) {
+            m_createsArguments.add(child.codeOrigin.inlineCallFrame);
+            return;
         }
-            
-        case GetLocal: {
-            if (child.local() == m_graph.uncheckedArgumentsRegisterFor(child.codeOrigin)) {
-                m_createsArguments.add(child.codeOrigin.inlineCallFrame);
-                return;
-            }
-            
-            VariableAccessData* variableAccessData = child.variableAccessData();
-            if (variableAccessData->isCaptured())
-                return;
-            
-            ArgumentsAliasingData& data = ""
-            data.escapes = true;
-            break;
-        }
-            
-        default:
-            break;
-        }
+        
+        VariableAccessData* variableAccessData = child.variableAccessData();
+        if (variableAccessData->isCaptured())
+            return;
+        
+        ArgumentsAliasingData& data = ""
+        data.escapes = true;
     }
     
     void observeBadArgumentsUses(Node& node)
     {
         for (unsigned i = m_graph.numChildren(node); i--;)
-            observeBadArgumentsUse(node, m_graph.child(node, i));
+            observeBadArgumentsUse(m_graph.child(node, i));
     }
     
     void observeProperArgumentsUse(Node& node, Edge edge)
@@ -664,13 +649,9 @@
         }
                         
         VariableAccessData* variableAccessData = child.variableAccessData();
-        if (variableAccessData->isCaptured()) {
-            if (child.local() == m_graph.uncheckedArgumentsRegisterFor(child.codeOrigin)
-                && node.codeOrigin.inlineCallFrame != child.codeOrigin.inlineCallFrame)
-                m_createsArguments.add(child.codeOrigin.inlineCallFrame);
+        if (variableAccessData->isCaptured())
             return;
-        }
-        
+                        
         ArgumentsAliasingData& data = ""
         data.mergeCallContext(node.codeOrigin.inlineCallFrame);
     }

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2012-05-23 06:07:53 UTC (rev 118126)
@@ -199,33 +199,6 @@
         return NoNode;
     }
     
-    NodeIndex globalVarStoreElimination(unsigned varNumber, JSGlobalObject* globalObject)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            NodeIndex index = m_currentBlock->at(i);
-            Node& node = m_graph[index];
-            if (!node.shouldGenerate())
-                continue;
-            switch (node.op()) {
-            case PutGlobalVar:
-                if (node.varNumber() == varNumber && codeBlock()->globalObjectFor(node.codeOrigin) == globalObject)
-                    return index;
-                break;
-                
-            case GetGlobalVar:
-                if (node.varNumber() == varNumber && codeBlock()->globalObjectFor(node.codeOrigin) == globalObject)
-                    return NoNode;
-                break;
-                
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(index) || node.canExit())
-                return NoNode;
-        }
-        return NoNode;
-    }
-    
     NodeIndex getByValLoadElimination(NodeIndex child1, NodeIndex child2)
     {
         for (unsigned i = m_indexInBlock; i--;) {
@@ -330,56 +303,6 @@
         return false;
     }
     
-    NodeIndex putStructureStoreElimination(NodeIndex child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            NodeIndex index = m_currentBlock->at(i);
-            if (index == child1)
-                break;
-            Node& node = m_graph[index];
-            if (!node.shouldGenerate())
-                break;
-            switch (node.op()) {
-            case CheckStructure:
-                return NoNode;
-                
-            case PhantomPutStructure:
-                if (node.child1() == child1) // No need to retrace our steps.
-                    return NoNode;
-                break;
-                
-            case PutStructure:
-                if (node.child1() == child1)
-                    return index;
-                break;
-                
-            // PutStructure needs to execute if we GC. Hence this needs to
-            // be careful with respect to nodes that GC.
-            case CreateArguments:
-            case TearOffArguments:
-            case NewFunctionNoCheck:
-            case NewFunction:
-            case NewFunctionExpression:
-            case CreateActivation:
-            case TearOffActivation:
-            case StrCat:
-            case ToPrimitive:
-            case NewRegexp:
-            case NewArrayBuffer:
-            case NewArray:
-            case NewObject:
-            case CreateThis:
-                return NoNode;
-                
-            default:
-                break;
-            }
-            if (m_graph.clobbersWorld(index) || node.canExit())
-                return NoNode;
-        }
-        return NoNode;
-    }
-    
     NodeIndex getByOffsetLoadElimination(unsigned identifierNumber, NodeIndex child1)
     {
         for (unsigned i = m_indexInBlock; i--;) {
@@ -426,52 +349,6 @@
         return NoNode;
     }
     
-    NodeIndex putByOffsetStoreElimination(unsigned identifierNumber, NodeIndex child1)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            NodeIndex index = m_currentBlock->at(i);
-            if (index == child1)
-                break;
-
-            Node& node = m_graph[index];
-            if (!node.shouldGenerate())
-                continue;
-            switch (node.op()) {
-            case GetByOffset:
-                if (m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber == identifierNumber)
-                    return NoNode;
-                break;
-                
-            case PutByOffset:
-                if (m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber == identifierNumber) {
-                    if (node.child1() == child1) // Must be same property storage.
-                        return index;
-                    return NoNode;
-                }
-                break;
-                
-            case PutByVal:
-            case PutByValAlias:
-            case GetByVal:
-                if (m_graph.byValIsPure(node)) {
-                    // If PutByVal speculates that it's accessing an array with an
-                    // integer index, then it's impossible for it to cause a structure
-                    // change.
-                    break;
-                }
-                return NoNode;
-                
-            default:
-                if (m_graph.clobbersWorld(index))
-                    return NoNode;
-                break;
-            }
-            if (node.canExit())
-                return NoNode;
-        }
-        return NoNode;
-    }
-    
     NodeIndex getPropertyStorageLoadElimination(NodeIndex child1)
     {
         for (unsigned i = m_indexInBlock; i--;) {
@@ -602,53 +479,6 @@
         return NoNode;
     }
     
-    // This returns the Flush node that is keeping a SetLocal alive.
-    NodeIndex setLocalStoreElimination(VirtualRegister local)
-    {
-        for (unsigned i = m_indexInBlock; i--;) {
-            NodeIndex index = m_currentBlock->at(i);
-            Node& node = m_graph[index];
-            if (!node.shouldGenerate())
-                continue;
-            switch (node.op()) {
-            case GetLocal:
-            case SetLocal:
-                if (node.local() == local)
-                    return NoNode;
-                break;
-                
-            case GetLocalUnlinked:
-                if (node.unlinkedLocal() == local)
-                    return NoNode;
-                break;
-                
-            case Flush: {
-                if (node.local() != local)
-                    break;
-                if (!i)
-                    break;
-                NodeIndex prevIndex = m_currentBlock->at(i - 1);
-                if (prevIndex != node.child1().index())
-                    break;
-                ASSERT(m_graph[prevIndex].local() == local);
-                ASSERT(m_graph[prevIndex].variableAccessData() == node.variableAccessData());
-                ASSERT(m_graph[prevIndex].shouldGenerate());
-                if (m_graph[prevIndex].refCount() > 1)
-                    break;
-                return index;
-            }
-                
-            default:
-                if (m_graph.clobbersWorld(index))
-                    return NoNode;
-                break;
-            }
-            if (node.canExit())
-                return NoNode;
-        }
-        return NoNode;
-    }
-    
     void performSubstitution(Edge& child, bool addRef = true)
     {
         // Check if this operand is actually unused.
@@ -670,16 +500,14 @@
             m_graph[child].ref();
     }
     
-    enum PredictionHandlingMode { RequireSamePrediction, AllowPredictionMismatch };
-    bool setReplacement(NodeIndex replacement, PredictionHandlingMode predictionHandlingMode = RequireSamePrediction)
+    bool setReplacement(NodeIndex replacement)
     {
         if (replacement == NoNode)
             return false;
         
         // Be safe. Don't try to perform replacements if the predictions don't
         // agree.
-        if (predictionHandlingMode == RequireSamePrediction
-            && m_graph[m_compileIndex].prediction() != m_graph[replacement].prediction())
+        if (m_graph[m_compileIndex].prediction() != m_graph[replacement].prediction())
             return false;
         
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
@@ -708,17 +536,6 @@
         node.setOpAndDefaultFlags(Phantom);
     }
     
-    void eliminate(NodeIndex nodeIndex, NodeType phantomType = Phantom)
-    {
-        if (nodeIndex == NoNode)
-            return;
-        Node& node = m_graph[nodeIndex];
-        if (node.refCount() != 1)
-            return;
-        ASSERT(node.mustGenerate());
-        node.setOpAndDefaultFlags(phantomType);
-    }
-    
     void performNodeCSE(Node& node)
     {
         bool shouldGenerate = node.shouldGenerate();
@@ -804,12 +621,6 @@
             NodeIndex phiIndex = node.child1().index();
             if (!setReplacement(possibleReplacement))
                 break;
-            // If the GetLocal we replaced used to refer to a SetLocal, then it now
-            // should refer to the child of the SetLocal instead.
-            if (m_graph[phiIndex].op() == SetLocal) {
-                ASSERT(node.child1().index() == phiIndex);
-                m_graph.changeEdge(node.children.child1(), m_graph[phiIndex].child1());
-            }
             NodeIndex oldTailIndex = m_currentBlock->variablesAtTail.operand(
                 variableAccessData->local());
             if (oldTailIndex == m_compileIndex) {
@@ -833,32 +644,10 @@
             break;
         }
             
-        case SetLocal: {
-            VariableAccessData* variableAccessData = node.variableAccessData();
-            if (!variableAccessData->isCaptured())
-                break;
-            VirtualRegister local = variableAccessData->local();
-            NodeIndex replacementIndex = setLocalStoreElimination(local);
-            if (replacementIndex == NoNode)
-                break;
-            Node& replacement = m_graph[replacementIndex];
-            ASSERT(replacement.op() == Flush);
-            ASSERT(replacement.refCount() == 1);
-            ASSERT(replacement.shouldGenerate());
-            ASSERT(replacement.mustGenerate());
-            replacement.setOpAndDefaultFlags(Phantom);
-            NodeIndex setLocalIndex = replacement.child1().index();
-            ASSERT(m_graph[setLocalIndex].op() == SetLocal);
-            m_graph.clearAndDerefChild1(replacement);
-            replacement.children.child1() = m_graph[setLocalIndex].child1();
-            m_graph.ref(replacement.child1());
-            break;
-        }
-            
         case JSConstant:
             // This is strange, but necessary. Some phases will convert nodes to constants,
             // which may result in duplicated constants. We use CSE to clean this up.
-            setReplacement(constantCSE(node), AllowPredictionMismatch);
+            setReplacement(constantCSE(node));
             break;
             
         case GetArrayLength:
@@ -891,10 +680,6 @@
             setReplacement(globalVarLoadElimination(node.varNumber(), codeBlock()->globalObjectFor(node.codeOrigin)));
             break;
             
-        case PutGlobalVar:
-            eliminate(globalVarStoreElimination(node.varNumber(), codeBlock()->globalObjectFor(node.codeOrigin)));
-            break;
-            
         case GetByVal:
             if (m_graph.byValIsPure(node))
                 setReplacement(getByValLoadElimination(node.child1().index(), node.child2().index()));
@@ -911,10 +696,6 @@
             if (checkStructureLoadElimination(node.structureSet(), node.child1().index()))
                 eliminate();
             break;
-            
-        case PutStructure:
-            eliminate(putStructureStoreElimination(node.child1().index()), PhantomPutStructure);
-            break;
 
         case CheckFunction:
             if (checkFunctionElimination(node.function(), node.child1().index()))
@@ -936,10 +717,6 @@
             setReplacement(getByOffsetLoadElimination(m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber, node.child1().index()));
             break;
             
-        case PutByOffset:
-            eliminate(putByOffsetStoreElimination(m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber, node.child1().index()));
-            break;
-            
         default:
             // do nothing.
             break;

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGNode.h (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGNode.h	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGNode.h	2012-05-23 06:07:53 UTC (rev 118126)
@@ -201,21 +201,9 @@
         return op() == WeakJSConstant;
     }
     
-    bool isPhantomArguments()
-    {
-        return op() == PhantomArguments;
-    }
-    
     bool hasConstant()
     {
-        switch (op()) {
-        case JSConstant:
-        case WeakJSConstant:
-        case PhantomArguments:
-            return true;
-        default:
-            return false;
-        }
+        return isConstant() || isWeakConstant();
     }
 
     unsigned constantNumber()
@@ -251,17 +239,9 @@
     
     JSValue valueOfJSConstant(CodeBlock* codeBlock)
     {
-        switch (op()) {
-        case WeakJSConstant:
+        if (op() == WeakJSConstant)
             return JSValue(weakConstant());
-        case JSConstant:
-            return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
-        case PhantomArguments:
-            return JSValue();
-        default:
-            ASSERT_NOT_REACHED();
-            return JSValue(); // Have to return something in release mode.
-        }
+        return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
     }
 
     bool isInt32Constant(CodeBlock* codeBlock)
@@ -609,7 +589,7 @@
 
     bool hasStructureTransitionData()
     {
-        return op() == PutStructure || op() == PhantomPutStructure;
+        return op() == PutStructure;
     }
     
     StructureTransitionData& structureTransitionData()

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGNodeType.h (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGNodeType.h	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGNodeType.h	2012-05-23 06:07:53 UTC (rev 118126)
@@ -37,11 +37,11 @@
 // This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
 #define FOR_EACH_DFG_OP(macro) \
     /* A constant in the CodeBlock's constant pool. */\
-    macro(JSConstant, NodeResultJS | NodeDoesNotExit) \
+    macro(JSConstant, NodeResultJS) \
     \
     /* A constant not in the CodeBlock's constant pool. Uses get patched to jumps that exit the */\
     /* code block. */\
-    macro(WeakJSConstant, NodeResultJS | NodeDoesNotExit) \
+    macro(WeakJSConstant, NodeResultJS) \
     \
     /* Nodes for handling functions (both as call and as construct). */\
     macro(ConvertThis, NodeResultJS) \
@@ -53,10 +53,10 @@
     /* VariableAccessData, and thus will share predictions. */\
     macro(GetLocal, NodeResultJS) \
     macro(SetLocal, 0) \
-    macro(Phantom, NodeMustGenerate | NodeDoesNotExit) \
-    macro(Nop, 0 | NodeDoesNotExit) \
-    macro(Phi, 0 | NodeDoesNotExit) \
-    macro(Flush, NodeMustGenerate | NodeDoesNotExit) \
+    macro(Phantom, NodeMustGenerate) \
+    macro(Nop, 0) \
+    macro(Phi, 0) \
+    macro(Flush, NodeMustGenerate) \
     \
     /* Get the value of a local variable, without linking into the VariableAccessData */\
     /* network. This is only valid for variable accesses whose predictions originated */\
@@ -64,12 +64,12 @@
     macro(GetLocalUnlinked, NodeResultJS) \
     \
     /* Marker for an argument being set at the prologue of a function. */\
-    macro(SetArgument, 0 | NodeDoesNotExit) \
+    macro(SetArgument, 0) \
     \
     /* Hint that inlining begins here. No code is generated for this node. It's only */\
     /* used for copying OSR data into inline frame data, to support reification of */\
     /* call frames of inlined functions. */\
-    macro(InlineStart, 0 | NodeDoesNotExit) \
+    macro(InlineStart, 0) \
     \
     /* Nodes for bitwise operations. */\
     macro(BitAnd, NodeResultInt32) \
@@ -113,12 +113,11 @@
     macro(PutById, NodeMustGenerate | NodeClobbersWorld) \
     macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
     macro(CheckStructure, NodeMustGenerate) \
-    macro(PutStructure, NodeMustGenerate) \
-    macro(PhantomPutStructure, NodeMustGenerate | NodeDoesNotExit) \
+    macro(PutStructure, NodeMustGenerate | NodeClobbersWorld) \
     macro(GetPropertyStorage, NodeResultStorage) \
     macro(GetIndexedPropertyStorage, NodeMustGenerate | NodeResultStorage) \
     macro(GetByOffset, NodeResultJS) \
-    macro(PutByOffset, NodeMustGenerate) \
+    macro(PutByOffset, NodeMustGenerate | NodeClobbersWorld) \
     macro(GetArrayLength, NodeResultInt32) \
     macro(GetArgumentsLength, NodeResultInt32) \
     macro(GetStringLength, NodeResultInt32) \
@@ -136,7 +135,7 @@
     macro(GetScopedVar, NodeResultJS | NodeMustGenerate) \
     macro(PutScopedVar, NodeMustGenerate | NodeClobbersWorld) \
     macro(GetGlobalVar, NodeResultJS | NodeMustGenerate) \
-    macro(PutGlobalVar, NodeMustGenerate) \
+    macro(PutGlobalVar, NodeMustGenerate | NodeClobbersWorld) \
     macro(CheckFunction, NodeMustGenerate) \
     \
     /* Optimizations for array mutation. */\
@@ -198,7 +197,6 @@
     /* Nodes used for arguments. Similar to activation support, only it makes even less */\
     /* sense. */\
     macro(CreateArguments, NodeResultJS) \
-    macro(PhantomArguments, NodeResultJS | NodeDoesNotExit) \
     macro(TearOffArguments, NodeMustGenerate) \
     macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \
     macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2012-05-23 06:07:53 UTC (rev 118126)
@@ -618,9 +618,7 @@
         case Int32ToDouble:
         case GetLocalUnlinked:
         case GetMyArgumentsLength:
-        case GetMyArgumentByVal:
-        case PhantomPutStructure:
-        case PhantomArguments: {
+        case GetMyArgumentByVal: {
             // This node should never be visible at this stage of compilation. It is
             // inserted by fixup(), which follows this phase.
             ASSERT_NOT_REACHED();

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2012-05-23 06:07:53 UTC (rev 118126)
@@ -1358,15 +1358,13 @@
         return ValueRecovery::argumentsThatWereNotCreated();
 
     case HaveNode: {
-        Node* nodePtr = &at(valueSource.nodeIndex());
-
-        if (nodePtr->isPhantomArguments())
-            return ValueRecovery::argumentsThatWereNotCreated();
-        
-        if (nodePtr->hasConstant())
+        if (isConstant(valueSource.nodeIndex()))
             return ValueRecovery::constant(valueOfJSConstant(valueSource.nodeIndex()));
         
+        Node* nodePtr = &at(valueSource.nodeIndex());
         if (!nodePtr->shouldGenerate()) {
+            if (nodePtr->op() == CreateArguments)
+                return ValueRecovery::argumentsThatWereNotCreated();
             // It's legitimately dead. As in, nobody will ever use this node, or operand,
             // ever. Set it to Undefined to make the GC happy after the OSR.
             return ValueRecovery::constant(jsUndefined());

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2012-05-23 06:07:53 UTC (rev 118126)
@@ -1853,7 +1853,6 @@
 
     switch (op) {
     case JSConstant:
-    case PhantomArguments:
         initConstantInfo(m_compileIndex);
         break;
 
@@ -3488,15 +3487,6 @@
         break;
     }
         
-    case PhantomPutStructure: {
-        m_jit.addWeakReferenceTransition(
-            node.codeOrigin.codeOriginOwner(),
-            node.structureTransitionData().previousStructure,
-            node.structureTransitionData().newStructure);
-        noResult(m_compileIndex);
-        break;
-    }
-
     case PutStructure: {
         SpeculateCellOperand base(this, node.child1());
         GPRReg baseGPR = base.gpr();

Modified: branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (118125 => 118126)


--- branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2012-05-23 05:40:20 UTC (rev 118125)
+++ branches/dfgopt/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2012-05-23 06:07:53 UTC (rev 118126)
@@ -1924,7 +1924,6 @@
 
     switch (op) {
     case JSConstant:
-    case PhantomArguments:
         initConstantInfo(m_compileIndex);
         break;
 
@@ -3495,15 +3494,6 @@
         break;
     }
         
-    case PhantomPutStructure: {
-        m_jit.addWeakReferenceTransition(
-            node.codeOrigin.codeOriginOwner(),
-            node.structureTransitionData().previousStructure,
-            node.structureTransitionData().newStructure);
-        noResult(m_compileIndex);
-        break;
-    }
-        
     case PutStructure: {
         SpeculateCellOperand base(this, node.child1());
         GPRReg baseGPR = base.gpr();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to