| Index: src/compiler/js-inlining.cc | 
| diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc | 
| index 147cfc9134a896d7b34b9e7e5f00c1c5707cc0f3..7a18c714c9d40e35eaf9b7432b5ba317839627a9 100644 | 
| --- a/src/compiler/js-inlining.cc | 
| +++ b/src/compiler/js-inlining.cc | 
| @@ -2,7 +2,6 @@ | 
| // Use of this source code is governed by a BSD-style license that can be | 
| // found in the LICENSE file. | 
|  | 
| -#include "src/compiler/access-builder.h" | 
| #include "src/compiler/ast-graph-builder.h" | 
| #include "src/compiler/common-operator.h" | 
| #include "src/compiler/generic-node-inl.h" | 
| @@ -68,9 +67,14 @@ static void Parse(Handle<JSFunction> function, CompilationInfoWithZone* info) { | 
| // A facade on a JSFunction's graph to facilitate inlining. It assumes the | 
| // that the function graph has only one return statement, and provides | 
| // {UnifyReturn} to convert a function graph to that end. | 
| +// InlineAtCall will create some new nodes using {graph}'s builders (and hence | 
| +// those nodes will live in {graph}'s zone. | 
| class Inlinee { | 
| public: | 
| -  Inlinee(Node* start, Node* end) : start_(start), end_(end) {} | 
| +  explicit Inlinee(JSGraph* graph) : jsgraph_(graph) {} | 
| + | 
| +  Graph* graph() { return jsgraph_->graph(); } | 
| +  JSGraph* jsgraph() { return jsgraph_; } | 
|  | 
| // Returns the last regular control node, that is | 
| // the last control node before the end node. | 
| @@ -88,25 +92,24 @@ class Inlinee { | 
| } | 
| // Return the unique return statement of the graph. | 
| Node* unique_return() { | 
| -    Node* unique_return = NodeProperties::GetControlInput(end_); | 
| +    Node* unique_return = | 
| +        NodeProperties::GetControlInput(jsgraph_->graph()->end()); | 
| DCHECK_EQ(IrOpcode::kReturn, unique_return->opcode()); | 
| return unique_return; | 
| } | 
| // Inline this graph at {call}, use {jsgraph} and its zone to create | 
| // any new nodes. | 
| void InlineAtCall(JSGraph* jsgraph, Node* call); | 
| - | 
| // Ensure that only a single return reaches the end node. | 
| -  static void UnifyReturn(JSGraph* jsgraph); | 
| +  void UnifyReturn(); | 
|  | 
| private: | 
| -  Node* start_; | 
| -  Node* end_; | 
| +  JSGraph* jsgraph_; | 
| }; | 
|  | 
|  | 
| -void Inlinee::UnifyReturn(JSGraph* jsgraph) { | 
| -  Graph* graph = jsgraph->graph(); | 
| +void Inlinee::UnifyReturn() { | 
| +  Graph* graph = jsgraph_->graph(); | 
|  | 
| Node* final_merge = NodeProperties::GetControlInput(graph->end(), 0); | 
| if (final_merge->opcode() == IrOpcode::kReturn) { | 
| @@ -117,11 +120,11 @@ void Inlinee::UnifyReturn(JSGraph* jsgraph) { | 
|  | 
| int predecessors = | 
| OperatorProperties::GetControlInputCount(final_merge->op()); | 
| -  Operator* op_phi = jsgraph->common()->Phi(kMachAnyTagged, predecessors); | 
| -  Operator* op_ephi = jsgraph->common()->EffectPhi(predecessors); | 
| +  Operator* op_phi = jsgraph_->common()->Phi(kMachAnyTagged, predecessors); | 
| +  Operator* op_ephi = jsgraph_->common()->EffectPhi(predecessors); | 
|  | 
| -  NodeVector values(jsgraph->zone()); | 
| -  NodeVector effects(jsgraph->zone()); | 
| +  NodeVector values(jsgraph_->zone()); | 
| +  NodeVector effects(jsgraph_->zone()); | 
| // Iterate over all control flow predecessors, | 
| // which must be return statements. | 
| InputIter iter = final_merge->inputs().begin(); | 
| @@ -147,104 +150,37 @@ void Inlinee::UnifyReturn(JSGraph* jsgraph) { | 
| Node* ephi = graph->NewNode(op_ephi, static_cast<int>(effects.size()), | 
| &effects.front()); | 
| Node* new_return = | 
| -      graph->NewNode(jsgraph->common()->Return(), phi, ephi, final_merge); | 
| +      graph->NewNode(jsgraph_->common()->Return(), phi, ephi, final_merge); | 
| graph->end()->ReplaceInput(0, new_return); | 
| } | 
|  | 
|  | 
| -class CopyVisitor : public NullNodeVisitor { | 
| - public: | 
| -  CopyVisitor(Graph* source_graph, Graph* target_graph, Zone* temp_zone) | 
| -      : copies_(source_graph->NodeCount(), NULL, temp_zone), | 
| -        sentinels_(source_graph->NodeCount(), NULL, temp_zone), | 
| -        source_graph_(source_graph), | 
| -        target_graph_(target_graph), | 
| -        temp_zone_(temp_zone), | 
| -        sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, 0, 0, | 
| -                     "sentinel") {} | 
| - | 
| -  GenericGraphVisit::Control Post(Node* original) { | 
| -    NodeVector inputs(temp_zone_); | 
| -    for (InputIter it = original->inputs().begin(); | 
| -         it != original->inputs().end(); ++it) { | 
| -      inputs.push_back(GetCopy(*it)); | 
| -    } | 
| - | 
| -    // Reuse the operator in the copy. This assumes that op lives in a zone | 
| -    // that lives longer than graph()'s zone. | 
| -    Node* copy = target_graph_->NewNode( | 
| -        original->op(), static_cast<int>(inputs.size()), &inputs.front()); | 
| -    copies_[original->id()] = copy; | 
| -    return GenericGraphVisit::CONTINUE; | 
| -  } | 
| - | 
| -  Node* GetCopy(Node* original) { | 
| -    Node* copy = copies_[original->id()]; | 
| -    if (copy == NULL) { | 
| -      copy = GetSentinel(original); | 
| -    } | 
| -    return copy; | 
| -  } | 
| - | 
| -  void CopyGraph() { | 
| -    source_graph_->VisitNodeInputsFromEnd(this); | 
| -    ReplaceSentinels(); | 
| -  } | 
| - | 
| -  const NodeVector& copies() { return copies_; } | 
| - | 
| - private: | 
| -  void ReplaceSentinels() { | 
| -    for (int id = 0; id < source_graph_->NodeCount(); ++id) { | 
| -      Node* sentinel = sentinels_[id]; | 
| -      if (sentinel == NULL) continue; | 
| -      Node* copy = copies_[id]; | 
| -      DCHECK_NE(NULL, copy); | 
| -      sentinel->ReplaceUses(copy); | 
| -    } | 
| -  } | 
| - | 
| -  Node* GetSentinel(Node* original) { | 
| -    Node* sentinel = sentinels_[original->id()]; | 
| -    if (sentinel == NULL) { | 
| -      sentinel = target_graph_->NewNode(&sentinel_op_); | 
| -    } | 
| -    return sentinel; | 
| -  } | 
| - | 
| -  NodeVector copies_; | 
| -  NodeVector sentinels_; | 
| -  Graph* source_graph_; | 
| -  Graph* target_graph_; | 
| -  Zone* temp_zone_; | 
| -  SimpleOperator sentinel_op_; | 
| -}; | 
| - | 
| - | 
| void Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { | 
| +  MachineOperatorBuilder machine(jsgraph->zone()); | 
| + | 
| // The scheduler is smart enough to place our code; we just ensure {control} | 
| // becomes the control input of the start of the inlinee. | 
| Node* control = NodeProperties::GetControlInput(call); | 
|  | 
| // The inlinee uses the context from the JSFunction object. This will | 
| // also be the effect dependency for the inlinee as it produces an effect. | 
| -  SimplifiedOperatorBuilder simplified(jsgraph->zone()); | 
| +  // TODO(sigurds) Use simplified load once it is ready. | 
| Node* context = jsgraph->graph()->NewNode( | 
| -      simplified.LoadField(AccessBuilder::ForJSFunctionContext()), | 
| -      NodeProperties::GetValueInput(call, 0), | 
| +      machine.Load(kMachAnyTagged), NodeProperties::GetValueInput(call, 0), | 
| +      jsgraph->Int32Constant(JSFunction::kContextOffset - kHeapObjectTag), | 
| NodeProperties::GetEffectInput(call)); | 
|  | 
| // {inlinee_inputs} counts JSFunction, Receiver, arguments, context, | 
| // but not effect, control. | 
| -  int inlinee_inputs = start_->op()->OutputCount(); | 
| +  int inlinee_inputs = graph()->start()->op()->OutputCount(); | 
| // Context is last argument. | 
| int inlinee_context_index = inlinee_inputs - 1; | 
| // {inliner_inputs} counts JSFunction, Receiver, arguments, but not | 
| // context, effect, control. | 
| int inliner_inputs = OperatorProperties::GetValueInputCount(call->op()); | 
| // Iterate over all uses of the start node. | 
| -  UseIter iter = start_->uses().begin(); | 
| -  while (iter != start_->uses().end()) { | 
| +  UseIter iter = graph()->start()->uses().begin(); | 
| +  while (iter != graph()->start()->uses().end()) { | 
| Node* use = *iter; | 
| switch (use->opcode()) { | 
| case IrOpcode::kParameter: { | 
| @@ -298,10 +234,10 @@ void Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { | 
| } | 
|  | 
|  | 
| -void JSInliner::TryInlineCall(Node* call) { | 
| -  DCHECK_EQ(IrOpcode::kJSCallFunction, call->opcode()); | 
| +void JSInliner::TryInlineCall(Node* node) { | 
| +  DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); | 
|  | 
| -  HeapObjectMatcher<JSFunction> match(call->InputAt(0)); | 
| +  HeapObjectMatcher<JSFunction> match(node->InputAt(0)); | 
| if (!match.HasValue()) { | 
| return; | 
| } | 
| @@ -339,20 +275,21 @@ void JSInliner::TryInlineCall(Node* call) { | 
| info_->shared_info()->DebugName()->ToCString().get()); | 
| } | 
|  | 
| -  Graph graph(info.zone()); | 
| -  Typer typer(info.zone()); | 
| -  JSGraph jsgraph(&graph, jsgraph_->common(), jsgraph_->javascript(), &typer, | 
| -                  jsgraph_->machine()); | 
| +  Graph graph(info_->zone()); | 
| +  graph.SetNextNodeId(jsgraph_->graph()->NextNodeID()); | 
| + | 
| +  Typer typer(info_->zone()); | 
| +  CommonOperatorBuilder common(info_->zone()); | 
| +  JSGraph jsgraph(&graph, &common, &typer); | 
|  | 
| AstGraphBuilder graph_builder(&info, &jsgraph); | 
| graph_builder.CreateGraph(); | 
| -  Inlinee::UnifyReturn(&jsgraph); | 
|  | 
| -  CopyVisitor visitor(&graph, jsgraph_->graph(), info.zone()); | 
| -  visitor.CopyGraph(); | 
| +  Inlinee inlinee(&jsgraph); | 
| +  inlinee.UnifyReturn(); | 
| +  inlinee.InlineAtCall(jsgraph_, node); | 
|  | 
| -  Inlinee inlinee(visitor.GetCopy(graph.start()), visitor.GetCopy(graph.end())); | 
| -  inlinee.InlineAtCall(jsgraph_, call); | 
| +  jsgraph_->graph()->SetNextNodeId(inlinee.graph()->NextNodeID()); | 
| } | 
| } | 
| } | 
|  |