Merge V8 5.3.332.45.  DO NOT MERGE

Test: Manual

FPIIM-449

Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc
index 5c01ff3..0664105 100644
--- a/src/compiler/js-inlining.cc
+++ b/src/compiler/js-inlining.cc
@@ -4,18 +4,19 @@
 
 #include "src/compiler/js-inlining.h"
 
-#include "src/ast/ast.h"
 #include "src/ast/ast-numbering.h"
+#include "src/ast/ast.h"
 #include "src/ast/scopes.h"
 #include "src/compiler.h"
-#include "src/compiler/all-nodes.h"
 #include "src/compiler/ast-graph-builder.h"
+#include "src/compiler/ast-loop-assignment-analyzer.h"
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph-reducer.h"
 #include "src/compiler/js-operator.h"
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/operator-properties.h"
+#include "src/compiler/type-hint-analyzer.h"
 #include "src/isolate-inl.h"
 #include "src/parsing/parser.h"
 #include "src/parsing/rewriter.h"
@@ -54,12 +55,8 @@
     return call_->InputAt(formal_arguments() + 1);
   }
 
-  Node* frame_state_before() {
-    return NodeProperties::GetFrameStateInput(call_, 1);
-  }
-
-  Node* frame_state_after() {
-    // Both, {JSCallFunction} and {JSCallConstruct}, have frame state after.
+  Node* frame_state() {
+    // Both, {JSCallFunction} and {JSCallConstruct}, have frame state.
     return NodeProperties::GetFrameStateInput(call_, 0);
   }
 
@@ -75,63 +72,6 @@
 };
 
 
-class CopyVisitor {
- public:
-  CopyVisitor(Graph* source_graph, Graph* target_graph, Zone* temp_zone)
-      : sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "Sentinel", 0, 0,
-                     0, 0, 0, 0),
-        sentinel_(target_graph->NewNode(&sentinel_op_)),
-        copies_(source_graph->NodeCount(), sentinel_, temp_zone),
-        source_graph_(source_graph),
-        target_graph_(target_graph),
-        temp_zone_(temp_zone) {}
-
-  Node* GetCopy(Node* orig) { return copies_[orig->id()]; }
-
-  void CopyGraph() {
-    NodeVector inputs(temp_zone_);
-    // TODO(bmeurer): AllNodes should be turned into something like
-    // Graph::CollectNodesReachableFromEnd() and the gray set stuff should be
-    // removed since it's only needed by the visualizer.
-    AllNodes all(temp_zone_, source_graph_);
-    // Copy all nodes reachable from end.
-    for (Node* orig : all.live) {
-      Node* copy = GetCopy(orig);
-      if (copy != sentinel_) {
-        // Mapping already exists.
-        continue;
-      }
-      // Copy the node.
-      inputs.clear();
-      for (Node* input : orig->inputs()) inputs.push_back(copies_[input->id()]);
-      copy = target_graph_->NewNode(orig->op(), orig->InputCount(),
-                                    inputs.empty() ? nullptr : &inputs[0]);
-      copies_[orig->id()] = copy;
-    }
-    // For missing inputs.
-    for (Node* orig : all.live) {
-      Node* copy = copies_[orig->id()];
-      for (int i = 0; i < copy->InputCount(); ++i) {
-        Node* input = copy->InputAt(i);
-        if (input == sentinel_) {
-          copy->ReplaceInput(i, GetCopy(orig->InputAt(i)));
-        }
-      }
-    }
-  }
-
-  const NodeVector& copies() const { return copies_; }
-
- private:
-  Operator const sentinel_op_;
-  Node* const sentinel_;
-  NodeVector copies_;
-  Graph* const source_graph_;
-  Graph* const target_graph_;
-  Zone* const temp_zone_;
-};
-
-
 Reduction JSInliner::InlineCall(Node* call, Node* new_target, Node* context,
                                 Node* frame_state, Node* start, Node* end) {
   // The scheduler is smart enough to place our code; we just ensure {control}
@@ -390,7 +330,7 @@
   // TODO(turbofan): TranslatedState::GetAdaptedArguments() currently relies on
   // not inlining recursive functions. We might want to relax that at some
   // point.
-  for (Node* frame_state = call.frame_state_after();
+  for (Node* frame_state = call.frame_state();
        frame_state->opcode() == IrOpcode::kFrameState;
        frame_state = frame_state->InputAt(kFrameStateOuterStateInput)) {
     FrameStateInfo const& frame_info = OpParameter<FrameStateInfo>(frame_state);
@@ -416,6 +356,7 @@
   ParseInfo parse_info(&zone, function);
   CompilationInfo info(&parse_info, function);
   if (info_->is_deoptimization_enabled()) info.MarkAsDeoptimizationEnabled();
+  if (info_->is_type_feedback_enabled()) info.MarkAsTypeFeedbackEnabled();
 
   if (!Compiler::ParseAndAnalyze(info.parse_info())) {
     TRACE("Not inlining %s into %s because parsing failed\n",
@@ -433,6 +374,7 @@
           info_->shared_info()->DebugName()->ToCString().get());
     return NoChange();
   }
+
   // Remember that we inlined this function. This needs to be called right
   // after we ensure deoptimization support so that the code flusher
   // does not remove the code with the deoptimization support.
@@ -446,59 +388,75 @@
         shared_info->DebugName()->ToCString().get(),
         info_->shared_info()->DebugName()->ToCString().get());
 
-  // TODO(mstarzinger): We could use the temporary zone for the graph because
-  // nodes are copied. This however leads to Zone-Types being allocated in the
-  // wrong zone and makes the engine explode at high speeds. Explosion bad!
-  Graph graph(jsgraph_->zone());
-  JSGraph jsgraph(info.isolate(), &graph, jsgraph_->common(),
-                  jsgraph_->javascript(), jsgraph_->simplified(),
-                  jsgraph_->machine());
-  AstGraphBuilder graph_builder(local_zone_, &info, &jsgraph);
-  graph_builder.CreateGraph(false);
+  // If function was lazily compiled, it's literals array may not yet be set up.
+  JSFunction::EnsureLiterals(function);
 
-  CopyVisitor visitor(&graph, jsgraph_->graph(), &zone);
-  visitor.CopyGraph();
+  // Create the subgraph for the inlinee.
+  Node* start;
+  Node* end;
+  {
+    // Run the loop assignment analyzer on the inlinee.
+    AstLoopAssignmentAnalyzer loop_assignment_analyzer(&zone, &info);
+    LoopAssignmentAnalysis* loop_assignment =
+        loop_assignment_analyzer.Analyze();
 
-  Node* start = visitor.GetCopy(graph.start());
-  Node* end = visitor.GetCopy(graph.end());
-  Node* frame_state = call.frame_state_after();
-  Node* new_target = jsgraph_->UndefinedConstant();
+    // Run the type hint analyzer on the inlinee.
+    TypeHintAnalyzer type_hint_analyzer(&zone);
+    TypeHintAnalysis* type_hint_analysis =
+        type_hint_analyzer.Analyze(handle(shared_info->code(), info.isolate()));
 
-  // Insert nodes around the call that model the behavior required for a
-  // constructor dispatch (allocate implicit receiver and check return value).
-  // This models the behavior usually accomplished by our {JSConstructStub}.
-  // Note that the context has to be the callers context (input to call node).
-  Node* receiver = jsgraph_->UndefinedConstant();  // Implicit receiver.
-  if (node->opcode() == IrOpcode::kJSCallConstruct &&
-      NeedsImplicitReceiver(shared_info)) {
-    Node* effect = NodeProperties::GetEffectInput(node);
-    Node* context = NodeProperties::GetContextInput(node);
-    Node* create = jsgraph_->graph()->NewNode(
-        jsgraph_->javascript()->Create(), call.target(), call.new_target(),
-        context, call.frame_state_before(), effect);
-    NodeProperties::ReplaceEffectInput(node, create);
-    // Insert a check of the return value to determine whether the return value
-    // or the implicit receiver should be selected as a result of the call.
-    Node* check = jsgraph_->graph()->NewNode(
-        jsgraph_->javascript()->CallRuntime(Runtime::kInlineIsJSReceiver, 1),
-        node, context, node, start);
-    Node* select = jsgraph_->graph()->NewNode(
-        jsgraph_->common()->Select(MachineRepresentation::kTagged), check, node,
-        create);
-    NodeProperties::ReplaceUses(node, select, check, node, node);
-    NodeProperties::ReplaceValueInput(select, node, 1);
-    NodeProperties::ReplaceValueInput(check, node, 0);
-    NodeProperties::ReplaceEffectInput(check, node);
-    receiver = create;  // The implicit receiver.
+    // Run the AstGraphBuilder to create the subgraph.
+    Graph::SubgraphScope scope(graph());
+    AstGraphBuilder graph_builder(&zone, &info, jsgraph(), loop_assignment,
+                                  type_hint_analysis);
+    graph_builder.CreateGraph(false);
+
+    // Extract the inlinee start/end nodes.
+    start = graph()->start();
+    end = graph()->end();
   }
 
-  // Swizzle the inputs of the {JSCallConstruct} node to look like inputs to a
-  // normal {JSCallFunction} node so that the rest of the inlining machinery
-  // behaves as if we were dealing with a regular function invocation.
+  Node* frame_state = call.frame_state();
+  Node* new_target = jsgraph_->UndefinedConstant();
+
+  // Inline {JSCallConstruct} requires some additional magic.
   if (node->opcode() == IrOpcode::kJSCallConstruct) {
+    // Insert nodes around the call that model the behavior required for a
+    // constructor dispatch (allocate implicit receiver and check return value).
+    // This models the behavior usually accomplished by our {JSConstructStub}.
+    // Note that the context has to be the callers context (input to call node).
+    Node* receiver = jsgraph_->UndefinedConstant();  // Implicit receiver.
+    if (NeedsImplicitReceiver(shared_info)) {
+      Node* frame_state_before = NodeProperties::FindFrameStateBefore(node);
+      Node* effect = NodeProperties::GetEffectInput(node);
+      Node* context = NodeProperties::GetContextInput(node);
+      Node* create = jsgraph_->graph()->NewNode(
+          jsgraph_->javascript()->Create(), call.target(), call.new_target(),
+          context, frame_state_before, effect);
+      NodeProperties::ReplaceEffectInput(node, create);
+      // Insert a check of the return value to determine whether the return
+      // value
+      // or the implicit receiver should be selected as a result of the call.
+      Node* check = jsgraph_->graph()->NewNode(
+          jsgraph_->javascript()->CallRuntime(Runtime::kInlineIsJSReceiver, 1),
+          node, context, node, start);
+      Node* select = jsgraph_->graph()->NewNode(
+          jsgraph_->common()->Select(MachineRepresentation::kTagged), check,
+          node, create);
+      NodeProperties::ReplaceUses(node, select, check, node, node);
+      NodeProperties::ReplaceValueInput(select, node, 1);
+      NodeProperties::ReplaceValueInput(check, node, 0);
+      NodeProperties::ReplaceEffectInput(check, node);
+      receiver = create;  // The implicit receiver.
+    }
+
+    // Swizzle the inputs of the {JSCallConstruct} node to look like inputs to a
+    // normal {JSCallFunction} node so that the rest of the inlining machinery
+    // behaves as if we were dealing with a regular function invocation.
     new_target = call.new_target();  // Retrieve new target value input.
     node->RemoveInput(call.formal_arguments() + 1);  // Drop new target.
     node->InsertInput(jsgraph_->graph()->zone(), 1, receiver);
+
     // Insert a construct stub frame into the chain of frame states. This will
     // reconstruct the proper frame when deoptimizing within the constructor.
     frame_state = CreateArtificialFrameState(
@@ -521,10 +479,11 @@
   if (node->opcode() == IrOpcode::kJSCallFunction &&
       is_sloppy(parse_info.language_mode()) && !shared_info->native()) {
     const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
+    Node* frame_state_before = NodeProperties::FindFrameStateBefore(node);
     Node* effect = NodeProperties::GetEffectInput(node);
     Node* convert = jsgraph_->graph()->NewNode(
         jsgraph_->javascript()->ConvertReceiver(p.convert_mode()),
-        call.receiver(), context, call.frame_state_before(), effect, start);
+        call.receiver(), context, frame_state_before, effect, start);
     NodeProperties::ReplaceValueInput(node, convert, 1);
     NodeProperties::ReplaceEffectInput(node, convert);
   }
@@ -558,6 +517,8 @@
   return InlineCall(node, new_target, context, frame_state, start, end);
 }
 
+Graph* JSInliner::graph() const { return jsgraph()->graph(); }
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8