Object allocation sinking phase should explicitly create bottom values for CreateActivation sink candidates and CreateActivation should have SymbolTable as a child node
https://bugs.webkit.org/show_bug.cgi?id=145192

Reviewed by Filip Pizlo.

When we sink CreateActivation and generate MaterializeCreateActivation
in the object allocation sinking phase, we now explictly add PutHints for
all variables on the activation setting those variables to their default value
(undefined for Function activations and soon to be JS Empty Value for block scope activations).
This allows us to remove code that fills FTL fast activation allocations with Undefined.

This patch also adds the constant SymbolTable as an OpInfo of CreateActivation and MaterializeCreateActivation
nodes. This is in preparation for ES6 block scoping which will introduce a new
op code that gets lowered to CreateActivation.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasCellOperand):
(JSC::DFG::Node::cellOperand):
* dfg/DFGObjectAllocationSinkingPhase.cpp:
(JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
(JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
(JSC::DFG::ObjectAllocationSinkingPhase::createMaterialize):
(JSC::DFG::ObjectAllocationSinkingPhase::populateMaterialize):
* dfg/DFGPromotedHeapLocation.cpp:
(WTF::printInternal):
* dfg/DFGPromotedHeapLocation.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCreateActivation):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
(JSC::FTL::LowerDFGToLLVM::compileMaterializeCreateActivation):
* ftl/FTLOperations.cpp:
(JSC::FTL::operationMaterializeObjectInOSR):
* tests/stress/activation-sink-default-value.js: Added.
(bar):
* tests/stress/activation-sink-osrexit-default-value.js: Added.
(foo.set result):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@184747 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp b/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
index 8a79fc5..584e160 100644
--- a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
@@ -586,6 +586,27 @@
                             nodeIndex + 1,
                             PromotedHeapLocation(ActivationScopePLoc, node).createHint(
                                 m_graph, node->origin, node->child1().node()));
+                        Node* symbolTableNode = m_insertionSet.insertConstant(
+                            nodeIndex + 1, node->origin, node->cellOperand());
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(ActivationSymbolTablePLoc, node).createHint(
+                                m_graph, node->origin, symbolTableNode));
+
+                        {
+                            SymbolTable* symbolTable = node->castOperand<SymbolTable*>();
+                            Node* undefined = m_insertionSet.insertConstant(
+                                nodeIndex + 1, node->origin, jsUndefined());
+                            ConcurrentJITLocker locker(symbolTable->m_lock);
+                            for (auto iter = symbolTable->begin(locker), end = symbolTable->end(locker); iter != end; ++iter) {
+                                m_insertionSet.insert(
+                                    nodeIndex + 1,
+                                    PromotedHeapLocation(
+                                        ClosureVarPLoc, node, iter->value.scopeOffset().offset()).createHint(
+                                        m_graph, node->origin, undefined));
+                            }
+                        }
+
                         node->convertToPhantomCreateActivation();
                     }
                     break;
@@ -597,6 +618,12 @@
                             nodeIndex + 1,
                             PromotedHeapLocation(ActivationScopePLoc, node).createHint(
                                 m_graph, node->origin, m_graph.varArgChild(node, 0).node()));
+                        Node* symbolTableNode = m_insertionSet.insertConstant(
+                            nodeIndex + 1, node->origin, node->cellOperand());
+                        m_insertionSet.insert(
+                            nodeIndex + 1,
+                            PromotedHeapLocation(ActivationSymbolTablePLoc, node).createHint(
+                                m_graph, node->origin, symbolTableNode));
                         ObjectMaterializationData& data = node->objectMaterializationData();
                         for (unsigned i = 0; i < data.m_properties.size(); ++i) {
                             unsigned identifierNumber = data.m_properties[i].m_identifierNumber;
@@ -829,7 +856,7 @@
             break;
 
         case CreateActivation:
-            if (!m_graph.symbolTableFor(node->origin.semantic)->singletonScope()->isStillValid())
+            if (!node->castOperand<SymbolTable*>()->singletonScope()->isStillValid())
                 sinkCandidate();
             escape(node->child1().node());
             break;
@@ -932,13 +959,13 @@
         case CreateActivation:
         case MaterializeCreateActivation: {
             ObjectMaterializationData* data = m_graph.m_objectMaterializationData.add();
-
+            FrozenValue* symbolTable = escapee->cellOperand();
             result = m_graph.addNode(
                 escapee->prediction(), Node::VarArg, MaterializeCreateActivation,
                 NodeOrigin(
                     escapee->origin.semantic,
                     where->origin.forExit),
-                OpInfo(data), OpInfo(), 0, 0);
+                OpInfo(data), OpInfo(symbolTable), 0, 0);
             break;
         }
 
@@ -1009,6 +1036,7 @@
             Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
 
             PromotedHeapLocation scope(ActivationScopePLoc, escapee);
+            PromotedHeapLocation symbolTable(ActivationSymbolTablePLoc, escapee);
             ASSERT(locations.contains(scope));
 
             m_graph.m_varArgChildren.append(Edge(resolve(block, scope), KnownCellUse));
@@ -1020,6 +1048,11 @@
                     break;
                 }
 
+                case ActivationSymbolTablePLoc: {
+                    ASSERT(locations[i] == symbolTable);
+                    break;
+                }
+
                 case ClosureVarPLoc: {
                     Node* value = resolve(block, locations[i]);
                     if (value->op() == BottomValue)