[JSC] Handle new_async_func / new_async_func_exp in DFG / FTL
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGObjectAllocationSinkingPhase.cpp
index 6fc307a..a1b8393 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGBlockMapInlines.h"
+#include "DFGClobbersExitState.h"
 #include "DFGCombinedLiveness.h"
 #include "DFGGraph.h"
 #include "DFGInsertionSet.h"
@@ -138,7 +139,7 @@ public:
     // once it is escaped if it still has pointers to it in order to
     // replace any use of those pointers by the corresponding
     // materialization
-    enum class Kind { Escaped, Object, Activation, Function, NewArrowFunction };
+    enum class Kind { Escaped, Object, Activation, Function, GeneratorFunction, AsyncFunction };
 
     explicit Allocation(Node* identifier = nullptr, Kind kind = Kind::Escaped)
         : m_identifier(identifier)
@@ -232,12 +233,7 @@ public:
 
     bool isFunctionAllocation() const
     {
-        return m_kind == Kind::Function || m_kind == Kind::NewArrowFunction;
-    }
-    
-    bool isArrowFunctionAllocation() const
-    {
-        return m_kind == Kind::NewArrowFunction;
+        return m_kind == Kind::Function || m_kind == Kind::GeneratorFunction || m_kind == Kind::AsyncFunction;
     }
 
     bool operator==(const Allocation& other) const
@@ -272,9 +268,13 @@ public:
         case Kind::Function:
             out.print("Function");
             break;
-                
-        case Kind::NewArrowFunction:
-            out.print("NewArrowFunction");
+
+        case Kind::GeneratorFunction:
+            out.print("GeneratorFunction");
+            break;
+
+        case Kind::AsyncFunction:
+            out.print("AsyncFunction");
             break;
 
         case Kind::Activation:
@@ -417,7 +417,7 @@ public:
 
     HashMap<Node*, Allocation> takeEscapees()
     {
-        return WTF::move(m_escapees);
+        return WTFMove(m_escapees);
     }
 
     void escape(Node* node)
@@ -643,14 +643,14 @@ private:
         if (allocation.isEscapedAllocation())
             return;
 
-        Allocation unescaped = WTF::move(allocation);
+        Allocation unescaped = WTFMove(allocation);
         allocation = Allocation(unescaped.identifier(), Allocation::Kind::Escaped);
 
         for (const auto& entry : unescaped.fields())
             escapeAllocation(entry.value);
 
         if (m_wantEscapees)
-            m_escapees.add(unescaped.identifier(), WTF::move(unescaped));
+            m_escapees.add(unescaped.identifier(), WTFMove(unescaped));
     }
 
     void prune()
@@ -726,6 +726,7 @@ private:
     {
         m_graph.computeRefCounts();
         m_graph.initializeNodeOwners();
+        m_graph.ensureDominators();
         performLivenessAnalysis(m_graph);
         performOSRAvailabilityAnalysis(m_graph);
         m_combinedLiveness = CombinedLiveness(m_graph);
@@ -757,7 +758,7 @@ private:
         promoteLocalHeap();
 
         if (Options::validateGraphAtEachPhase())
-            validate(m_graph, DumpGraph, graphBeforeSinking);
+            DFG::validate(m_graph, DumpGraph, graphBeforeSinking);
         return true;
     }
 
@@ -834,39 +835,28 @@ private:
                 StructurePLoc, LazyNode(m_graph.freeze(node->structure())));
             break;
 
-        case MaterializeNewObject: {
-            target = &m_heap.newAllocation(node, Allocation::Kind::Object);
-            target->setStructures(node->structureSet());
-            writes.add(
-                StructurePLoc, LazyNode(m_graph.varArgChild(node, 0).node()));
-            for (unsigned i = 0; i < node->objectMaterializationData().m_properties.size(); ++i) {
-                writes.add(
-                    PromotedLocationDescriptor(
-                        NamedPropertyPLoc,
-                        node->objectMaterializationData().m_properties[i].m_identifierNumber),
-                    LazyNode(m_graph.varArgChild(node, i + 1).node()));
-            }
-            break;
-        }
-
         case NewFunction:
-        case NewArrowFunction: {
-            bool isArrowFunction = node->op() == NewArrowFunction;
-            if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid()) {
+        case NewGeneratorFunction:
+        case NewAsyncFunction: {
+            if (isStillValid(node->castOperand<FunctionExecutable*>()->singletonFunction())) {
                 m_heap.escape(node->child1().node());
                 break;
             }
-            
-            target = &m_heap.newAllocation(node, isArrowFunction ? Allocation::Kind::NewArrowFunction : Allocation::Kind::Function);
+
+            if (node->op() == NewGeneratorFunction)
+                target = &m_heap.newAllocation(node, Allocation::Kind::GeneratorFunction);
+            else if (node->op() == NewAsyncFunction)
+                target = &m_heap.newAllocation(node, Allocation::Kind::AsyncFunction);
+            else
+                target = &m_heap.newAllocation(node, Allocation::Kind::Function);
+
             writes.add(FunctionExecutablePLoc, LazyNode(node->cellOperand()));
             writes.add(FunctionActivationPLoc, LazyNode(node->child1().node()));
-            if (isArrowFunction)
-                writes.add(ArrowFunctionBoundThisPLoc, LazyNode(node->child2().node()));
             break;
         }
 
         case CreateActivation: {
-            if (node->castOperand<SymbolTable*>()->singletonScope()->isStillValid()) {
+            if (isStillValid(node->castOperand<SymbolTable*>()->singletonScope())) {
                 m_heap.escape(node->child1().node());
                 break;
             }
@@ -886,23 +876,6 @@ private:
             break;
         }
 
-        case MaterializeCreateActivation: {
-            // We have sunk this once already - there is no way the
-            // watchpoint is still valid.
-            ASSERT(!node->castOperand<SymbolTable*>()->singletonScope()->isStillValid());
-            target = &m_heap.newAllocation(node, Allocation::Kind::Activation);
-            writes.add(ActivationSymbolTablePLoc, LazyNode(m_graph.varArgChild(node, 0).node()));
-            writes.add(ActivationScopePLoc, LazyNode(m_graph.varArgChild(node, 1).node()));
-            for (unsigned i = 0; i < node->objectMaterializationData().m_properties.size(); ++i) {
-                writes.add(
-                    PromotedLocationDescriptor(
-                        ClosureVarPLoc,
-                        node->objectMaterializationData().m_properties[i].m_identifierNumber),
-                    LazyNode(m_graph.varArgChild(node, i + 2).node()));
-            }
-            break;
-        }
-
         case PutStructure:
             target = m_heap.onlyLocalAllocation(node->child1().node());
             if (target && target->isObjectAllocation()) {
@@ -1048,14 +1021,6 @@ private:
                 m_heap.escape(node->child1().node());
             break;
 
-        case LoadArrowFunctionThis:
-            target = m_heap.onlyLocalAllocation(node->child1().node());
-            if (target && target->isArrowFunctionAllocation())
-                exactRead = ArrowFunctionBoundThisPLoc;
-            else
-                m_heap.escape(node->child1().node());
-            break;
-        
         case GetScope:
             target = m_heap.onlyLocalAllocation(node->child1().node());
             if (target && target->isFunctionAllocation())
@@ -1254,7 +1219,7 @@ private:
                     if (mustEscape)
                         escapingOnEdge.add(entry.key, entry.value);
                 }
-                placeMaterializations(WTF::move(escapingOnEdge), block->terminal());
+                placeMaterializations(WTFMove(escapingOnEdge), block->terminal());
             }
         }
 
@@ -1285,7 +1250,7 @@ private:
 
             for (const auto& field : entry.value.fields()) {
                 ASSERT(m_sinkCandidates.contains(entry.key) || !escapees.contains(field.value));
-                if (escapees.contains(field.value) && !field.key.neededForMaterialization())
+                if (escapees.contains(field.value))
                     hints.append(PromotedHeapLocation(entry.key, field.key));
             }
         }
@@ -1368,7 +1333,7 @@ private:
             // We need to insert *after* the current position
             if (firstPos != toMaterialize.end())
                 ++firstPos;
-            firstPos = toMaterialize.insert(firstPos, WTF::move(allocation));
+            firstPos = toMaterialize.insert(firstPos, WTFMove(allocation));
         };
 
         // Nodes that no other unmaterialized node points to will be
@@ -1377,7 +1342,7 @@ private:
         auto lastPos = toMaterialize.end();
         auto materializeLast = [&] (Allocation&& allocation) {
             materialize(allocation.identifier());
-            lastPos = toMaterialize.insert(lastPos, WTF::move(allocation));
+            lastPos = toMaterialize.insert(lastPos, WTFMove(allocation));
         };
 
         // These are the promoted locations that contains some of the
@@ -1398,12 +1363,12 @@ private:
                     continue;
 
                 if (dependencies.find(entry.key)->value.isEmpty()) {
-                    materializeFirst(WTF::move(entry.value));
+                    materializeFirst(WTFMove(entry.value));
                     continue;
                 }
 
                 if (reverseDependencies.find(entry.key)->value.isEmpty()) {
-                    materializeLast(WTF::move(entry.value));
+                    materializeLast(WTFMove(entry.value));
                     continue;
                 }
             }
@@ -1414,7 +1379,7 @@ private:
             // first.
             if (materialized.isEmpty()) {
                 uint64_t maxEvaluation = 0;
-                Allocation* bestAllocation;
+                Allocation* bestAllocation = nullptr;
                 for (auto& entry : escapees) {
                     if (!forMaterialization.find(entry.key)->value.isEmpty())
                         continue;
@@ -1428,7 +1393,7 @@ private:
                 }
                 RELEASE_ASSERT(maxEvaluation > 0);
 
-                materializeFirst(WTF::move(*bestAllocation));
+                materializeFirst(WTFMove(*bestAllocation));
             }
             RELEASE_ASSERT(!materialized.isEmpty());
 
@@ -1487,11 +1452,14 @@ private:
                 OpInfo(set), OpInfo(data), 0, 0);
         }
 
-        case Allocation::Kind::NewArrowFunction:
+        case Allocation::Kind::AsyncFunction:
+        case Allocation::Kind::GeneratorFunction:
         case Allocation::Kind::Function: {
             FrozenValue* executable = allocation.identifier()->cellOperand();
             
-            NodeType nodeType = allocation.kind() == Allocation::Kind::NewArrowFunction ? NewArrowFunction : NewFunction;
+            NodeType nodeType =
+                allocation.kind() == Allocation::Kind::GeneratorFunction ? NewGeneratorFunction :
+                allocation.kind() == Allocation::Kind::AsyncFunction ? NewAsyncFunction : NewFunction;
             
             return m_graph.addNode(
                 allocation.identifier()->prediction(), nodeType,
@@ -1579,7 +1547,7 @@ private:
         // with useless constants everywhere
         HashMap<FrozenValue*, Node*> lazyMapping;
         if (!m_bottom)
-            m_bottom = m_insertionSet.insertConstant(0, NodeOrigin(), jsNumber(1927));
+            m_bottom = m_insertionSet.insertConstant(0, m_graph.block(0)->at(0)->origin, jsNumber(1927));
         for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
             m_heap = m_heapAtHead[block];
 
@@ -1652,7 +1620,7 @@ private:
                 if (m_heapAtHead[block].follow(location))
                     return nullptr;
 
-                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
+                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, block->at(0)->origin.withInvalidExit());
                 phiNode->mergeFlags(NodeResultJS);
                 return phiNode;
             });
@@ -1669,7 +1637,7 @@ private:
                 if (!m_heapAtHead[block].getAllocation(identifier).isEscapedAllocation())
                     return nullptr;
 
-                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, NodeOrigin());
+                Node* phiNode = m_graph.addNode(SpecHeapTop, Phi, block->at(0)->origin.withInvalidExit());
                 phiNode->mergeFlags(NodeResultJS);
                 return phiNode;
             });
@@ -1700,7 +1668,9 @@ private:
 
                 if (m_sinkCandidates.contains(location.base())) {
                     m_insertionSet.insert(
-                        0, location.createHint(m_graph, NodeOrigin(), phiDef->value()));
+                        0,
+                        location.createHint(
+                            m_graph, block->at(0)->origin.withInvalidExit(), phiDef->value()));
                 }
             }
 
@@ -1710,7 +1680,10 @@ private:
 
                 Node* identifier = indexToNode[variable->index()];
                 m_escapeeToMaterialization.add(identifier, phiDef->value());
-                insertOSRHintsForUpdate(0, NodeOrigin(), availabilityCalculator.m_availability, identifier, phiDef->value());
+                bool canExit = false;
+                insertOSRHintsForUpdate(
+                    0, block->at(0)->origin, canExit,
+                    availabilityCalculator.m_availability, identifier, phiDef->value());
             }
 
             if (verbose) {
@@ -1720,6 +1693,8 @@ private:
 
             for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                 Node* node = block->at(nodeIndex);
+                bool canExit = true;
+                bool nextCanExit = node->origin.exitOK;
                 for (PromotedHeapLocation location : m_locationsForAllocation.get(node)) {
                     if (location.kind() != NamedPropertyPLoc)
                         continue;
@@ -1727,13 +1702,17 @@ private:
                     m_localMapping.set(location, m_bottom);
 
                     if (m_sinkCandidates.contains(node)) {
+                        if (verbose)
+                            dataLog("For sink candidate ", node, " found location ", location, "\n");
                         m_insertionSet.insert(
                             nodeIndex + 1,
-                            location.createHint(m_graph, node->origin, m_bottom));
+                            location.createHint(
+                                m_graph, node->origin.takeValidExit(nextCanExit), m_bottom));
                     }
                 }
 
                 for (Node* materialization : m_materializationSiteToMaterializations.get(node)) {
+                    materialization->origin.exitOK &= canExit;
                     Node* escapee = m_materializationToEscapee.get(materialization);
                     populateMaterialization(block, materialization, escapee);
                     m_escapeeToMaterialization.set(escapee, materialization);
@@ -1743,7 +1722,7 @@ private:
                 }
 
                 for (PromotedHeapLocation location : m_materializationSiteToRecoveries.get(node))
-                    m_insertionSet.insert(nodeIndex, createRecovery(block, location, node));
+                    m_insertionSet.insert(nodeIndex, createRecovery(block, location, node, canExit));
 
                 // We need to put the OSR hints after the recoveries,
                 // because we only want the hints once the object is
@@ -1751,15 +1730,24 @@ private:
                 for (Node* materialization : m_materializationSiteToMaterializations.get(node)) {
                     Node* escapee = m_materializationToEscapee.get(materialization);
                     insertOSRHintsForUpdate(
-                        nodeIndex, node->origin,
+                        nodeIndex, node->origin, canExit,
                         availabilityCalculator.m_availability, escapee, materialization);
                 }
 
+                if (node->origin.exitOK && !canExit) {
+                    // We indicate that the exit state is fine now. It is OK because we updated the
+                    // state above. We need to indicate this manually because the validation doesn't
+                    // have enough information to infer that the exit state is fine.
+                    m_insertionSet.insertNode(nodeIndex, SpecNone, ExitOK, node->origin);
+                }
+
                 if (m_sinkCandidates.contains(node))
                     m_escapeeToMaterialization.set(node, node);
 
                 availabilityCalculator.executeNode(node);
 
+                bool desiredNextExitOK = node->origin.exitOK && !clobbersExitState(m_graph, node);
+
                 bool doLower = false;
                 handleNode(
                     node,
@@ -1782,27 +1770,42 @@ private:
 
                         doLower = true;
 
-                        m_insertionSet.insert(nodeIndex + 1,
-                            location.createHint(m_graph, node->origin, nodeValue));
+                        if (verbose)
+                            dataLog("Creating hint with value ", nodeValue, " before ", node, "\n");
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            location.createHint(
+                                m_graph, node->origin.takeValidExit(nextCanExit), nodeValue));
                     },
                     [&] (PromotedHeapLocation location) -> Node* {
                         return resolve(block, location);
                     });
 
+                if (!nextCanExit && desiredNextExitOK) {
+                    // We indicate that the exit state is fine now. We need to do this because we
+                    // emitted hints that appear to invalidate the exit state.
+                    m_insertionSet.insertNode(nodeIndex + 1, SpecNone, ExitOK, node->origin);
+                }
+
                 if (m_sinkCandidates.contains(node) || doLower) {
                     switch (node->op()) {
                     case NewObject:
-                    case MaterializeNewObject:
                         node->convertToPhantomNewObject();
                         break;
 
-                    case NewArrowFunction:
                     case NewFunction:
                         node->convertToPhantomNewFunction();
                         break;
 
+                    case NewGeneratorFunction:
+                        node->convertToPhantomNewGeneratorFunction();
+                        break;
+
+                    case NewAsyncFunction:
+                        node->convertToPhantomNewAsyncFunction();
+                        break;
+
                     case CreateActivation:
-                    case MaterializeCreateActivation:
                         node->convertToPhantomCreateActivation();
                         break;
 
@@ -1867,7 +1870,8 @@ private:
         ASSERT(def->value());
 
         Node* result = def->value();
-
+        if (result->replacement())
+            result = result->replacement();
         ASSERT(!result->replacement());
 
         m_localMapping.add(location, result);
@@ -1905,8 +1909,15 @@ private:
         return def->value();
     }
 
-    void insertOSRHintsForUpdate(unsigned nodeIndex, NodeOrigin origin, AvailabilityMap& availability, Node* escapee, Node* materialization)
+    void insertOSRHintsForUpdate(unsigned nodeIndex, NodeOrigin origin, bool& canExit, AvailabilityMap& availability, Node* escapee, Node* materialization)
     {
+        if (verbose) {
+            dataLog("Inserting OSR hints at ", origin, ":\n");
+            dataLog("    Escapee: ", escapee, "\n");
+            dataLog("    Materialization: ", materialization, "\n");
+            dataLog("    Availability: ", availability, "\n");
+        }
+        
         // We need to follow() the value in the heap.
         // Consider the following graph:
         //
@@ -1939,7 +1950,8 @@ private:
                 continue;
 
             m_insertionSet.insert(
-                nodeIndex, entry.key.createHint(m_graph, origin, materialization));
+                nodeIndex,
+                entry.key.createHint(m_graph, origin.takeValidExit(canExit), materialization));
         }
 
         for (unsigned i = availability.m_locals.size(); i--;) {
@@ -1950,7 +1962,7 @@ private:
 
             int operand = availability.m_locals.operandForIndex(i);
             m_insertionSet.insertNode(
-                nodeIndex, SpecNone, MovHint, origin, OpInfo(operand),
+                nodeIndex, SpecNone, MovHint, origin.takeValidExit(canExit), OpInfo(operand),
                 materialization->defaultEdge());
         }
     }
@@ -1978,7 +1990,7 @@ private:
 
                 case NamedPropertyPLoc: {
                     ASSERT(location.base() == allocation.identifier());
-                    data.m_properties.append(PhantomPropertyValue(location.info()));
+                    data.m_properties.append(location.descriptor());
                     Node* value = resolve(block, location);
                     if (m_sinkCandidates.contains(value))
                         m_graph.m_varArgChildren.append(m_bottom);
@@ -2028,7 +2040,7 @@ private:
 
                 case ClosureVarPLoc: {
                     ASSERT(location.base() == allocation.identifier());
-                    data.m_properties.append(PhantomPropertyValue(location.info()));
+                    data.m_properties.append(location.descriptor());
                     Node* value = resolve(block, location);
                     if (m_sinkCandidates.contains(value))
                         m_graph.m_varArgChildren.append(m_bottom);
@@ -2049,10 +2061,10 @@ private:
         }
         
         case NewFunction:
-        case NewArrowFunction: {
-            bool isArrowFunction = node->op() == NewArrowFunction;
+        case NewGeneratorFunction:
+        case NewAsyncFunction: {
             Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
-            ASSERT(locations.size() == (isArrowFunction ? 3 : 2));
+            ASSERT(locations.size() == 2);
                 
             PromotedHeapLocation executable(FunctionExecutablePLoc, allocation.identifier());
             ASSERT_UNUSED(executable, locations.contains(executable));
@@ -2061,13 +2073,6 @@ private:
             ASSERT(locations.contains(activation));
 
             node->child1() = Edge(resolve(block, activation), KnownCellUse);
-            
-            if (isArrowFunction) {
-                PromotedHeapLocation boundThis(ArrowFunctionBoundThisPLoc, allocation.identifier());
-                ASSERT(locations.contains(boundThis));
-                node->child2() = Edge(resolve(block, boundThis), CellUse);
-            }
-            
             break;
         }
 
@@ -2076,7 +2081,7 @@ private:
         }
     }
 
-    Node* createRecovery(BasicBlock* block, PromotedHeapLocation location, Node* where)
+    Node* createRecovery(BasicBlock* block, PromotedHeapLocation location, Node* where, bool& canExit)
     {
         if (verbose)
             dataLog("Recovering ", location, " at ", where, "\n");
@@ -2084,12 +2089,14 @@ private:
         Node* base = getMaterialization(block, location.base());
         Node* value = resolve(block, location);
 
+        NodeOrigin origin = where->origin.withSemantic(base->origin.semantic);
+
         if (verbose)
             dataLog("Base is ", base, " and value is ", value, "\n");
 
         if (base->isPhantomAllocation()) {
             return PromotedHeapLocation(base, location.descriptor()).createHint(
-                m_graph, where->origin.withSemantic(base->origin.semantic), value);
+                m_graph, origin.takeValidExit(canExit), value);
         }
 
         switch (location.kind()) {
@@ -2121,9 +2128,8 @@ private:
                 data->identifierNumber = identifierNumber;
 
                 return m_graph.addNode(
-                    SpecNone,
                     PutByOffset,
-                    where->origin,
+                    origin.takeValidExit(canExit),
                     OpInfo(data),
                     Edge(storage, KnownCellUse),
                     Edge(base, KnownCellUse),
@@ -2139,20 +2145,25 @@ private:
                 for (Structure* structure : structures) {
                     PropertyOffset offset = structure->getConcurrently(uid);
                     if (offset != currentOffset) {
+                        // Because our analysis treats MultiPutByOffset like an escape, we only have to
+                        // deal with storing results that would have been previously stored by PutByOffset
+                        // nodes. Those nodes were guarded by the appropriate type checks. This means that
+                        // at this point, we can simply trust that the incoming value has the right type
+                        // for whatever structure we are using.
                         data->variants.append(
-                            PutByIdVariant::replace(currentSet, currentOffset));
+                            PutByIdVariant::replace(currentSet, currentOffset, InferredType::Top));
                         currentOffset = offset;
                         currentSet.clear();
                     }
                     currentSet.add(structure);
                 }
-                data->variants.append(PutByIdVariant::replace(currentSet, currentOffset));
+                data->variants.append(
+                    PutByIdVariant::replace(currentSet, currentOffset, InferredType::Top));
             }
 
             return m_graph.addNode(
-                SpecNone,
                 MultiPutByOffset,
-                where->origin.withSemantic(base->origin.semantic),
+                origin.takeValidExit(canExit),
                 OpInfo(data),
                 Edge(base, KnownCellUse),
                 value->defaultEdge());
@@ -2161,9 +2172,8 @@ private:
 
         case ClosureVarPLoc: {
             return m_graph.addNode(
-                SpecNone,
                 PutClosureVar,
-                where->origin.withSemantic(base->origin.semantic),
+                origin.takeValidExit(canExit),
                 OpInfo(location.info()),
                 Edge(base, KnownCellUse),
                 value->defaultEdge());
@@ -2176,6 +2186,15 @@ private:
         }
     }
 
+    // This is a great way of asking value->isStillValid() without having to worry about getting
+    // different answers. It turns out that this analysis works OK regardless of what this
+    // returns but breaks badly if this changes its mind for any particular InferredValue. This
+    // method protects us from that.
+    bool isStillValid(InferredValue* value)
+    {
+        return m_validInferredValues.add(value, value->isStillValid()).iterator->value;
+    }
+
     SSACalculator m_pointerSSA;
     SSACalculator m_allocationSSA;
     HashSet<Node*> m_sinkCandidates;
@@ -2186,6 +2205,8 @@ private:
     InsertionSet m_insertionSet;
     CombinedLiveness m_combinedLiveness;
 
+    HashMap<InferredValue*, bool> m_validInferredValues;
+
     HashMap<Node*, Node*> m_materializationToEscapee;
     HashMap<Node*, Vector<Node*>> m_materializationSiteToMaterializations;
     HashMap<Node*, Vector<PromotedHeapLocation>> m_materializationSiteToRecoveries;
@@ -2203,7 +2224,6 @@ private:
 
 bool performObjectAllocationSinking(Graph& graph)
 {
-    SamplingRegion samplingRegion("DFG Object Allocation Sinking Phase");
     return runPhase<ObjectAllocationSinkingPhase>(graph);
 }