]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - dfg/DFGAbstractInterpreter.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGAbstractInterpreter.h
index 97582ac319726c8177836c3becb957065e75b408..b3ebd68f18bec32a7667940c227736ab3ad0714d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
 #include "DFGBranchDirection.h"
 #include "DFGGraph.h"
 #include "DFGNode.h"
+#include "DFGPhiChildren.h"
 
 namespace JSC { namespace DFG {
 
@@ -80,22 +81,15 @@ public:
     //
     // This is guaranteed to be equivalent to doing:
     //
-    // if (state.startExecuting(index)) {
-    //     state.executeEdges(index);
-    //     result = state.executeEffects(index);
-    // } else
-    //     result = true;
+    // state.startExecuting()
+    // state.executeEdges(index);
+    // result = state.executeEffects(index);
     bool execute(unsigned indexInBlock);
     bool execute(Node*);
     
-    // Indicate the start of execution of the node. It resets any state in the node,
-    // that is progressively built up by executeEdges() and executeEffects(). In
-    // particular, this resets canExit(), so if you want to "know" between calls of
-    // startExecuting() and executeEdges()/Effects() whether the last run of the
-    // analysis concluded that the node can exit, you should probably set that
-    // information aside prior to calling startExecuting().
-    bool startExecuting(Node*);
-    bool startExecuting(unsigned indexInBlock);
+    // Indicate the start of execution of a node. It resets any state in the node
+    // that is progressively built up by executeEdges() and executeEffects().
+    void startExecuting();
     
     // Abstractly execute the edges of the given node. This runs filterEdgeByUse()
     // on all edges of the node. You can skip this step, if you have already used
@@ -103,10 +97,14 @@ public:
     void executeEdges(Node*);
     void executeEdges(unsigned indexInBlock);
     
-    ALWAYS_INLINE void filterEdgeByUse(Node* node, Edge& edge)
+    ALWAYS_INLINE void filterEdgeByUse(Edge& edge)
     {
         ASSERT(mayHaveTypeCheck(edge.useKind()) || !needsTypeCheck(edge));
-        filterByType(node, edge, typeFilterFor(edge.useKind()));
+        filterByType(edge, typeFilterFor(edge.useKind()));
+    }
+    ALWAYS_INLINE void filterEdgeByUse(Node*, Edge& edge)
+    {
+        filterEdgeByUse(edge);
     }
     
     // Abstractly execute the effects of the given node. This changes the abstract
@@ -114,6 +112,7 @@ public:
     bool executeEffects(unsigned indexInBlock);
     bool executeEffects(unsigned clobberLimit, Node*);
     
+    void dump(PrintStream& out) const;
     void dump(PrintStream& out);
     
     template<typename T>
@@ -135,7 +134,7 @@ public:
     }
     
     template<typename T>
-    FiltrationResult filterByValue(T node, JSValue value)
+    FiltrationResult filterByValue(T node, FrozenValue value)
     {
         return filterByValue(forNode(node), value);
     }
@@ -143,12 +142,20 @@ public:
     FiltrationResult filter(AbstractValue&, const StructureSet&);
     FiltrationResult filterArrayModes(AbstractValue&, ArrayModes);
     FiltrationResult filter(AbstractValue&, SpeculatedType);
-    FiltrationResult filterByValue(AbstractValue&, JSValue);
+    FiltrationResult filterByValue(AbstractValue&, FrozenValue);
+    
+    PhiChildren* phiChildren() { return m_phiChildren.get(); }
     
 private:
     void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
-    void clobberCapturedVars(const CodeOrigin&);
+    
+    template<typename Functor>
+    void forAllValues(unsigned indexInBlock, Functor&);
+    
     void clobberStructures(unsigned indexInBlock);
+    void observeTransition(unsigned indexInBlock, Structure* from, Structure* to);
+    void observeTransitions(unsigned indexInBlock, const TransitionVector&);
+    void setDidClobber();
     
     enum BooleanResult {
         UnknownBooleanResult,
@@ -157,26 +164,25 @@ private:
     };
     BooleanResult booleanResult(Node*, AbstractValue&);
     
-    void setBuiltInConstant(Node* node, JSValue value)
+    void setBuiltInConstant(Node* node, FrozenValue value)
     {
         AbstractValue& abstractValue = forNode(node);
-        abstractValue.set(m_graph, value);
-        abstractValue.fixTypeForRepresentation(node);
+        abstractValue.set(m_graph, value, m_state.structureClobberState());
+        abstractValue.fixTypeForRepresentation(m_graph, node);
     }
     
-    void setConstant(Node* node, JSValue value)
+    void setConstant(Node* node, FrozenValue value)
     {
         setBuiltInConstant(node, value);
         m_state.setFoundConstants(true);
     }
     
-    ALWAYS_INLINE void filterByType(Node* node, Edge& edge, SpeculatedType type)
+    ALWAYS_INLINE void filterByType(Edge& edge, SpeculatedType type)
     {
         AbstractValue& value = forNode(edge);
-        if (!value.isType(type)) {
-            node->setCanExit(true);
+        if (!value.isType(type))
             edge.setProofStatus(NeedsCheck);
-        else
+        else
             edge.setProofStatus(IsProved);
         
         filter(value, type);
@@ -188,6 +194,7 @@ private:
     CodeBlock* m_codeBlock;
     Graph& m_graph;
     AbstractStateType& m_state;
+    std::unique_ptr<PhiChildren> m_phiChildren;
 };
 
 } } // namespace JSC::DFG