new test fast/js/dfg-arguments-mixed-alias.html fails on JSVALUE32_64
https://bugs.webkit.org/show_bug.cgi?id=87378

Reviewed by Gavin Barraclough.
        
- Captured variable tracking forgot did not consistently handle arguments, leading to OSR
  badness.
        
- Nodes capable of exiting were tracked in a non-monotonic way, leading to compiler errors.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::CSEPhase):
(CSEPhase):
(JSC::DFG::performCSE):
* dfg/DFGCSEPhase.h:
(DFG):
* dfg/DFGCommon.h:
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::resetExitStates):
(DFG):
* dfg/DFGGraph.h:
(Graph):
* dfg/DFGPhase.h:
(DFG):
(JSC::DFG::runPhase):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@118468 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index a432d59..2bb0031 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,35 @@
+2012-05-24  Filip Pizlo  <fpizlo@apple.com>
+
+        new test fast/js/dfg-arguments-mixed-alias.html fails on JSVALUE32_64
+        https://bugs.webkit.org/show_bug.cgi?id=87378
+
+        Reviewed by Gavin Barraclough.
+        
+        - Captured variable tracking forgot did not consistently handle arguments, leading to OSR
+          badness.
+        
+        - Nodes capable of exiting were tracked in a non-monotonic way, leading to compiler errors.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::CSEPhase):
+        (CSEPhase):
+        (JSC::DFG::performCSE):
+        * dfg/DFGCSEPhase.h:
+        (DFG):
+        * dfg/DFGCommon.h:
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compile):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::resetExitStates):
+        (DFG):
+        * dfg/DFGGraph.h:
+        (Graph):
+        * dfg/DFGPhase.h:
+        (DFG):
+        (JSC::DFG::runPhase):
+
 2012-05-24  Geoffrey Garen  <ggaren@apple.com>
 
         Made WeakSet per-block instead of per-heap
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 15a6f72..27e198c 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -2836,6 +2836,10 @@
                 inlineCallFrame.capturedVars.set(i);
         }
         
+        if (codeBlock->usesArguments() || codeBlock->needsActivation()) {
+            for (int i = argumentCountIncludingThis; i--;)
+                inlineCallFrame.capturedVars.set(argumentToOperand(i) + inlineCallFrame.stackOffset);
+        }
         for (int i = codeBlock->m_numCapturedVars; i--;)
             inlineCallFrame.capturedVars.set(i + inlineCallFrame.stackOffset);
         
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 0a9ce34..842bcc2 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -35,8 +35,9 @@
 
 class CSEPhase : public Phase {
 public:
-    CSEPhase(Graph& graph)
+    CSEPhase(Graph& graph, OptimizationFixpointState fixpointState)
         : Phase(graph, "common subexpression elimination")
+        , m_fixpointState(fixpointState)
     {
         // Replacements are used to implement local common subexpression elimination.
         m_replacements.resize(m_graph.size());
@@ -750,11 +751,12 @@
     unsigned m_indexInBlock;
     Vector<NodeIndex, 16> m_replacements;
     FixedArray<unsigned, LastNodeType> m_lastSeen;
+    OptimizationFixpointState m_fixpointState;
 };
 
-bool performCSE(Graph& graph)
+bool performCSE(Graph& graph, OptimizationFixpointState fixpointState)
 {
-    return runPhase<CSEPhase>(graph);
+    return runPhase<CSEPhase>(graph, fixpointState);
 }
 
 } } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.h b/Source/JavaScriptCore/dfg/DFGCSEPhase.h
index 1a7c733..7e33c22 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.h
@@ -30,6 +30,8 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "DFGCommon.h"
+
 namespace JSC { namespace DFG {
 
 class Graph;
@@ -39,7 +41,7 @@
 // a wide range of subexpression similarities. It's known to produce big wins
 // on a few benchmarks, and is relatively cheap to run.
 
-bool performCSE(Graph&);
+bool performCSE(Graph&, OptimizationFixpointState);
 
 } } // namespace JSC::DFG
 
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index 4428d45..b2e3bb4 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -130,6 +130,8 @@
 
 enum NoResultTag { NoResult };
 
+enum OptimizationFixpointState { FixpointConverged, FixpointNotConverged };
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.cpp b/Source/JavaScriptCore/dfg/DFGDriver.cpp
index cf54578..6ebe338 100644
--- a/Source/JavaScriptCore/dfg/DFGDriver.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDriver.cpp
@@ -82,10 +82,12 @@
         changed |= performConstantFolding(dfg);
         changed |= performArgumentsSimplification(dfg);
         changed |= performCFGSimplification(dfg);
-        performCSE(dfg);
         if (!changed)
             break;
+        performCSE(dfg, FixpointNotConverged);
+        dfg.resetExitStates();
     }
+    performCSE(dfg, FixpointConverged);
 #if DFG_ENABLE(DEBUG_VERBOSE)
     dataLog("DFG optimization fixpoint converged in %u iterations.\n", cnt);
 #endif
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index 7f20cb4..4562e30 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -491,6 +491,12 @@
     determineReachability();
 }
 
+void Graph::resetExitStates()
+{
+    for (unsigned i = size(); i--;)
+        at(i).setCanExit(true);
+}
+
 } } // namespace JSC::DFG
 
 #endif
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index 9fe7664..52654d2 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -461,6 +461,8 @@
     void determineReachability();
     void resetReachability();
     
+    void resetExitStates();
+    
     unsigned numChildren(Node& node)
     {
         if (node.flags() & NodeHasVarArgs)
diff --git a/Source/JavaScriptCore/dfg/DFGPhase.h b/Source/JavaScriptCore/dfg/DFGPhase.h
index 6dcf9dc..6d13bcd 100644
--- a/Source/JavaScriptCore/dfg/DFGPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGPhase.h
@@ -79,6 +79,13 @@
     return phase.run();
 }
 
+template<typename PhaseType, typename ArgumentType1>
+bool runPhase(Graph& graph, ArgumentType1 arg1)
+{
+    PhaseType phase(graph, arg1);
+    return phase.run();
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)