1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/bytecode-graph-builder.h"
6
7#include "src/compiler/bytecode-branch-analysis.h"
8#include "src/compiler/linkage.h"
9#include "src/compiler/operator-properties.h"
10#include "src/interpreter/bytecodes.h"
11
12namespace v8 {
13namespace internal {
14namespace compiler {
15
16// Helper for generating frame states for before and after a bytecode.
17class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
18 public:
19  FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder,
20                           const interpreter::BytecodeArrayIterator& iterator)
21      : builder_(builder),
22        id_after_(BailoutId::None()),
23        added_to_node_(false),
24        output_poke_offset_(0),
25        output_poke_count_(0) {
26    BailoutId id_before(iterator.current_offset());
27    frame_state_before_ = builder_->environment()->Checkpoint(
28        id_before, OutputFrameStateCombine::Ignore());
29    id_after_ = BailoutId(id_before.ToInt() + iterator.current_bytecode_size());
30  }
31
32  ~FrameStateBeforeAndAfter() {
33    DCHECK(added_to_node_);
34    DCHECK(builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
35                                                           output_poke_count_));
36  }
37
38 private:
39  friend class Environment;
40
41  void AddToNode(Node* node, OutputFrameStateCombine combine) {
42    DCHECK(!added_to_node_);
43    int count = OperatorProperties::GetFrameStateInputCount(node->op());
44    DCHECK_LE(count, 2);
45    if (count >= 1) {
46      // Add the frame state for after the operation.
47      DCHECK_EQ(IrOpcode::kDead,
48                NodeProperties::GetFrameStateInput(node, 0)->opcode());
49      Node* frame_state_after =
50          builder_->environment()->Checkpoint(id_after_, combine);
51      NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
52    }
53
54    if (count >= 2) {
55      // Add the frame state for before the operation.
56      DCHECK_EQ(IrOpcode::kDead,
57                NodeProperties::GetFrameStateInput(node, 1)->opcode());
58      NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
59    }
60
61    if (!combine.IsOutputIgnored()) {
62      output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
63      output_poke_count_ = node->op()->ValueOutputCount();
64    }
65    added_to_node_ = true;
66  }
67
68  BytecodeGraphBuilder* builder_;
69  Node* frame_state_before_;
70  BailoutId id_after_;
71
72  bool added_to_node_;
73  int output_poke_offset_;
74  int output_poke_count_;
75};
76
77
78// Issues:
79// - Scopes - intimately tied to AST. Need to eval what is needed.
80// - Need to resolve closure parameter treatment.
81BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
82                                               int register_count,
83                                               int parameter_count,
84                                               Node* control_dependency,
85                                               Node* context)
86    : builder_(builder),
87      register_count_(register_count),
88      parameter_count_(parameter_count),
89      context_(context),
90      control_dependency_(control_dependency),
91      effect_dependency_(control_dependency),
92      values_(builder->local_zone()),
93      parameters_state_values_(nullptr),
94      registers_state_values_(nullptr),
95      accumulator_state_values_(nullptr) {
96  // The layout of values_ is:
97  //
98  // [receiver] [parameters] [registers] [accumulator]
99  //
100  // parameter[0] is the receiver (this), parameters 1..N are the
101  // parameters supplied to the method (arg0..argN-1). The accumulator
102  // is stored separately.
103
104  // Parameters including the receiver
105  for (int i = 0; i < parameter_count; i++) {
106    const char* debug_name = (i == 0) ? "%this" : nullptr;
107    const Operator* op = common()->Parameter(i, debug_name);
108    Node* parameter = builder->graph()->NewNode(op, graph()->start());
109    values()->push_back(parameter);
110  }
111
112  // Registers
113  register_base_ = static_cast<int>(values()->size());
114  Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
115  values()->insert(values()->end(), register_count, undefined_constant);
116
117  // Accumulator
118  accumulator_base_ = static_cast<int>(values()->size());
119  values()->push_back(undefined_constant);
120}
121
122
123BytecodeGraphBuilder::Environment::Environment(
124    const BytecodeGraphBuilder::Environment* other)
125    : builder_(other->builder_),
126      register_count_(other->register_count_),
127      parameter_count_(other->parameter_count_),
128      context_(other->context_),
129      control_dependency_(other->control_dependency_),
130      effect_dependency_(other->effect_dependency_),
131      values_(other->zone()),
132      parameters_state_values_(nullptr),
133      registers_state_values_(nullptr),
134      accumulator_state_values_(nullptr),
135      register_base_(other->register_base_),
136      accumulator_base_(other->accumulator_base_) {
137  values_ = other->values_;
138}
139
140
141int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
142    interpreter::Register the_register) const {
143  if (the_register.is_parameter()) {
144    return the_register.ToParameterIndex(parameter_count());
145  } else {
146    return the_register.index() + register_base();
147  }
148}
149
150
151Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
152  return values()->at(accumulator_base_);
153}
154
155
156Node* BytecodeGraphBuilder::Environment::LookupRegister(
157    interpreter::Register the_register) const {
158  if (the_register.is_function_context()) {
159    return builder()->GetFunctionContext();
160  } else if (the_register.is_function_closure()) {
161    return builder()->GetFunctionClosure();
162  } else if (the_register.is_new_target()) {
163    return builder()->GetNewTarget();
164  } else {
165    int values_index = RegisterToValuesIndex(the_register);
166    return values()->at(values_index);
167  }
168}
169
170
171void BytecodeGraphBuilder::Environment::ExchangeRegisters(
172    interpreter::Register reg0, interpreter::Register reg1) {
173  int reg0_index = RegisterToValuesIndex(reg0);
174  int reg1_index = RegisterToValuesIndex(reg1);
175  Node* saved_reg0_value = values()->at(reg0_index);
176  values()->at(reg0_index) = values()->at(reg1_index);
177  values()->at(reg1_index) = saved_reg0_value;
178}
179
180
181void BytecodeGraphBuilder::Environment::BindAccumulator(
182    Node* node, FrameStateBeforeAndAfter* states) {
183  if (states) {
184    states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
185  }
186  values()->at(accumulator_base_) = node;
187}
188
189
190void BytecodeGraphBuilder::Environment::BindRegister(
191    interpreter::Register the_register, Node* node,
192    FrameStateBeforeAndAfter* states) {
193  int values_index = RegisterToValuesIndex(the_register);
194  if (states) {
195    states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
196                                                            values_index));
197  }
198  values()->at(values_index) = node;
199}
200
201
202void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
203    interpreter::Register first_reg, Node* node,
204    FrameStateBeforeAndAfter* states) {
205  int values_index = RegisterToValuesIndex(first_reg);
206  if (states) {
207    states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
208                                                            values_index));
209  }
210  for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
211    values()->at(values_index + i) =
212        builder()->NewNode(common()->Projection(i), node);
213  }
214}
215
216
217void BytecodeGraphBuilder::Environment::RecordAfterState(
218    Node* node, FrameStateBeforeAndAfter* states) {
219  states->AddToNode(node, OutputFrameStateCombine::Ignore());
220}
221
222
223bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
224  return GetControlDependency()->opcode() == IrOpcode::kDead;
225}
226
227
228void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
229  UpdateControlDependency(builder()->jsgraph()->Dead());
230}
231
232
233BytecodeGraphBuilder::Environment*
234BytecodeGraphBuilder::Environment::CopyForLoop() {
235  PrepareForLoop();
236  return new (zone()) Environment(this);
237}
238
239
240BytecodeGraphBuilder::Environment*
241BytecodeGraphBuilder::Environment::CopyForConditional() const {
242  return new (zone()) Environment(this);
243}
244
245
246void BytecodeGraphBuilder::Environment::Merge(
247    BytecodeGraphBuilder::Environment* other) {
248  // Nothing to do if the other environment is dead.
249  if (other->IsMarkedAsUnreachable()) {
250    return;
251  }
252
253  // Create a merge of the control dependencies of both environments and update
254  // the current environment's control dependency accordingly.
255  Node* control = builder()->MergeControl(GetControlDependency(),
256                                          other->GetControlDependency());
257  UpdateControlDependency(control);
258
259  // Create a merge of the effect dependencies of both environments and update
260  // the current environment's effect dependency accordingly.
261  Node* effect = builder()->MergeEffect(GetEffectDependency(),
262                                        other->GetEffectDependency(), control);
263  UpdateEffectDependency(effect);
264
265  // Introduce Phi nodes for values that have differing input at merge points,
266  // potentially extending an existing Phi node if possible.
267  context_ = builder()->MergeValue(context_, other->context_, control);
268  for (size_t i = 0; i < values_.size(); i++) {
269    values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
270  }
271}
272
273
274void BytecodeGraphBuilder::Environment::PrepareForLoop() {
275  // Create a control node for the loop header.
276  Node* control = builder()->NewLoop();
277
278  // Create a Phi for external effects.
279  Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
280  UpdateEffectDependency(effect);
281
282  // Assume everything in the loop is updated.
283  context_ = builder()->NewPhi(1, context_, control);
284  int size = static_cast<int>(values()->size());
285  for (int i = 0; i < size; i++) {
286    values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
287  }
288
289  // Connect to the loop end.
290  Node* terminate = builder()->graph()->NewNode(
291      builder()->common()->Terminate(), effect, control);
292  builder()->exit_controls_.push_back(terminate);
293}
294
295
296bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
297    Node** state_values, int offset, int count) {
298  if (!builder()->info()->is_deoptimization_enabled()) {
299    return false;
300  }
301  if (*state_values == nullptr) {
302    return true;
303  }
304  DCHECK_EQ((*state_values)->InputCount(), count);
305  DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
306  Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
307  for (int i = 0; i < count; i++) {
308    if ((*state_values)->InputAt(i) != env_values[i]) {
309      return true;
310    }
311  }
312  return false;
313}
314
315
316void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
317                                                          int offset,
318                                                          int count) {
319  if (StateValuesRequireUpdate(state_values, offset, count)) {
320    const Operator* op = common()->StateValues(count);
321    (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
322  }
323}
324
325
326Node* BytecodeGraphBuilder::Environment::Checkpoint(
327    BailoutId bailout_id, OutputFrameStateCombine combine) {
328  if (!builder()->info()->is_deoptimization_enabled()) {
329    return builder()->jsgraph()->EmptyFrameState();
330  }
331
332  // TODO(rmcilroy): Consider using StateValuesCache for some state values.
333  UpdateStateValues(&parameters_state_values_, 0, parameter_count());
334  UpdateStateValues(&registers_state_values_, register_base(),
335                    register_count());
336  UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
337
338  const Operator* op = common()->FrameState(
339      bailout_id, combine, builder()->frame_state_function_info());
340  Node* result = graph()->NewNode(
341      op, parameters_state_values_, registers_state_values_,
342      accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
343      builder()->graph()->start());
344
345  return result;
346}
347
348
349bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
350    Node** state_values, int offset, int count, int output_poke_start,
351    int output_poke_end) {
352  DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
353  for (int i = 0; i < count; i++, offset++) {
354    if (offset < output_poke_start || offset >= output_poke_end) {
355      if ((*state_values)->InputAt(i) != values()->at(offset)) {
356        return false;
357      }
358    }
359  }
360  return true;
361}
362
363
364bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
365    int output_poke_offset, int output_poke_count) {
366  // Poke offset is relative to the top of the stack (i.e., the accumulator).
367  int output_poke_start = accumulator_base() - output_poke_offset;
368  int output_poke_end = output_poke_start + output_poke_count;
369  return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
370                                output_poke_start, output_poke_end) &&
371         StateValuesAreUpToDate(&registers_state_values_, register_base(),
372                                register_count(), output_poke_start,
373                                output_poke_end) &&
374         StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
375                                1, output_poke_start, output_poke_end);
376}
377
378
379BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
380                                           CompilationInfo* compilation_info,
381                                           JSGraph* jsgraph)
382    : local_zone_(local_zone),
383      info_(compilation_info),
384      jsgraph_(jsgraph),
385      bytecode_array_(handle(info()->shared_info()->bytecode_array())),
386      frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
387          FrameStateType::kInterpretedFunction,
388          bytecode_array()->parameter_count(),
389          bytecode_array()->register_count(), info()->shared_info(),
390          CALL_MAINTAINS_NATIVE_CONTEXT)),
391      merge_environments_(local_zone),
392      loop_header_environments_(local_zone),
393      input_buffer_size_(0),
394      input_buffer_(nullptr),
395      exit_controls_(local_zone) {}
396
397
398Node* BytecodeGraphBuilder::GetNewTarget() {
399  if (!new_target_.is_set()) {
400    int params = bytecode_array()->parameter_count();
401    int index = Linkage::GetJSCallNewTargetParamIndex(params);
402    const Operator* op = common()->Parameter(index, "%new.target");
403    Node* node = NewNode(op, graph()->start());
404    new_target_.set(node);
405  }
406  return new_target_.get();
407}
408
409
410Node* BytecodeGraphBuilder::GetFunctionContext() {
411  if (!function_context_.is_set()) {
412    int params = bytecode_array()->parameter_count();
413    int index = Linkage::GetJSCallContextParamIndex(params);
414    const Operator* op = common()->Parameter(index, "%context");
415    Node* node = NewNode(op, graph()->start());
416    function_context_.set(node);
417  }
418  return function_context_.get();
419}
420
421
422Node* BytecodeGraphBuilder::GetFunctionClosure() {
423  if (!function_closure_.is_set()) {
424    int index = Linkage::kJSCallClosureParamIndex;
425    const Operator* op = common()->Parameter(index, "%closure");
426    Node* node = NewNode(op, graph()->start());
427    function_closure_.set(node);
428  }
429  return function_closure_.get();
430}
431
432
433Node* BytecodeGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
434  return NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), object,
435                 jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
436}
437
438
439Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object,
440                                                          int offset) {
441  return graph()->NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()),
442                          object,
443                          jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
444                          graph()->start(), graph()->start());
445}
446
447
448Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
449  const Operator* op =
450      javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
451  Node* native_context = NewNode(op, environment()->Context());
452  return NewNode(javascript()->LoadContext(0, index, true), native_context);
453}
454
455
456Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() {
457  if (!feedback_vector_.is_set()) {
458    Node* closure = GetFunctionClosure();
459    Node* shared = BuildLoadImmutableObjectField(
460        closure, JSFunction::kSharedFunctionInfoOffset);
461    Node* vector = BuildLoadImmutableObjectField(
462        shared, SharedFunctionInfo::kFeedbackVectorOffset);
463    feedback_vector_.set(vector);
464  }
465  return feedback_vector_.get();
466}
467
468
469VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
470  Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector();
471  FeedbackVectorSlot slot;
472  if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
473    slot = feedback_vector->ToSlot(slot_id);
474  }
475  return VectorSlotPair(feedback_vector, slot);
476}
477
478
479bool BytecodeGraphBuilder::CreateGraph(bool stack_check) {
480  // Set up the basic structure of the graph. Outputs for {Start} are
481  // the formal parameters (including the receiver) plus context and
482  // closure.
483
484  // Set up the basic structure of the graph. Outputs for {Start} are the formal
485  // parameters (including the receiver) plus new target, number of arguments,
486  // context and closure.
487  int actual_parameter_count = bytecode_array()->parameter_count() + 4;
488  graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
489
490  Environment env(this, bytecode_array()->register_count(),
491                  bytecode_array()->parameter_count(), graph()->start(),
492                  GetFunctionContext());
493  set_environment(&env);
494
495  CreateGraphBody(stack_check);
496
497  // Finish the basic structure of the graph.
498  DCHECK_NE(0u, exit_controls_.size());
499  int const input_count = static_cast<int>(exit_controls_.size());
500  Node** const inputs = &exit_controls_.front();
501  Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
502  graph()->SetEnd(end);
503
504  return true;
505}
506
507
508void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) {
509  // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments
510  // object setup, this function variable if used, tracing hooks.
511
512  if (stack_check) {
513    Node* node = NewNode(javascript()->StackCheck());
514    PrepareEntryFrameState(node);
515  }
516
517  VisitBytecodes();
518}
519
520
521void BytecodeGraphBuilder::VisitBytecodes() {
522  BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
523  analysis.Analyze();
524  set_branch_analysis(&analysis);
525  interpreter::BytecodeArrayIterator iterator(bytecode_array());
526  set_bytecode_iterator(&iterator);
527  while (!iterator.done()) {
528    int current_offset = iterator.current_offset();
529    if (analysis.is_reachable(current_offset)) {
530      MergeEnvironmentsOfForwardBranches(current_offset);
531      BuildLoopHeaderForBackwardBranches(current_offset);
532
533      switch (iterator.current_bytecode()) {
534#define BYTECODE_CASE(name, ...)       \
535  case interpreter::Bytecode::k##name: \
536    Visit##name(iterator);             \
537    break;
538        BYTECODE_LIST(BYTECODE_CASE)
539#undef BYTECODE_CODE
540      }
541    }
542    iterator.Advance();
543  }
544  set_branch_analysis(nullptr);
545  set_bytecode_iterator(nullptr);
546}
547
548
549void BytecodeGraphBuilder::VisitLdaZero(
550    const interpreter::BytecodeArrayIterator& iterator) {
551  Node* node = jsgraph()->ZeroConstant();
552  environment()->BindAccumulator(node);
553}
554
555
556void BytecodeGraphBuilder::VisitLdaSmi8(
557    const interpreter::BytecodeArrayIterator& iterator) {
558  Node* node = jsgraph()->Constant(iterator.GetImmediateOperand(0));
559  environment()->BindAccumulator(node);
560}
561
562
563void BytecodeGraphBuilder::VisitLdaConstantWide(
564    const interpreter::BytecodeArrayIterator& iterator) {
565  Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
566  environment()->BindAccumulator(node);
567}
568
569
570void BytecodeGraphBuilder::VisitLdaConstant(
571    const interpreter::BytecodeArrayIterator& iterator) {
572  Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
573  environment()->BindAccumulator(node);
574}
575
576
577void BytecodeGraphBuilder::VisitLdaUndefined(
578    const interpreter::BytecodeArrayIterator& iterator) {
579  Node* node = jsgraph()->UndefinedConstant();
580  environment()->BindAccumulator(node);
581}
582
583
584void BytecodeGraphBuilder::VisitLdaNull(
585    const interpreter::BytecodeArrayIterator& iterator) {
586  Node* node = jsgraph()->NullConstant();
587  environment()->BindAccumulator(node);
588}
589
590
591void BytecodeGraphBuilder::VisitLdaTheHole(
592    const interpreter::BytecodeArrayIterator& iterator) {
593  Node* node = jsgraph()->TheHoleConstant();
594  environment()->BindAccumulator(node);
595}
596
597
598void BytecodeGraphBuilder::VisitLdaTrue(
599    const interpreter::BytecodeArrayIterator& iterator) {
600  Node* node = jsgraph()->TrueConstant();
601  environment()->BindAccumulator(node);
602}
603
604
605void BytecodeGraphBuilder::VisitLdaFalse(
606    const interpreter::BytecodeArrayIterator& iterator) {
607  Node* node = jsgraph()->FalseConstant();
608  environment()->BindAccumulator(node);
609}
610
611
612void BytecodeGraphBuilder::VisitLdar(
613    const interpreter::BytecodeArrayIterator& iterator) {
614  Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
615  environment()->BindAccumulator(value);
616}
617
618
619void BytecodeGraphBuilder::VisitStar(
620    const interpreter::BytecodeArrayIterator& iterator) {
621  Node* value = environment()->LookupAccumulator();
622  environment()->BindRegister(iterator.GetRegisterOperand(0), value);
623}
624
625
626void BytecodeGraphBuilder::VisitMov(
627    const interpreter::BytecodeArrayIterator& iterator) {
628  Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
629  environment()->BindRegister(iterator.GetRegisterOperand(1), value);
630}
631
632
633void BytecodeGraphBuilder::VisitExchange(
634    const interpreter::BytecodeArrayIterator& iterator) {
635  environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
636                                   iterator.GetRegisterOperand(1));
637}
638
639
640void BytecodeGraphBuilder::VisitExchangeWide(
641    const interpreter::BytecodeArrayIterator& iterator) {
642  environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
643                                   iterator.GetRegisterOperand(1));
644}
645
646
647void BytecodeGraphBuilder::BuildLoadGlobal(
648    const interpreter::BytecodeArrayIterator& iterator,
649    TypeofMode typeof_mode) {
650  FrameStateBeforeAndAfter states(this, iterator);
651  Handle<Name> name =
652      Handle<Name>::cast(iterator.GetConstantForIndexOperand(0));
653  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
654
655  const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
656  Node* node = NewNode(op, BuildLoadFeedbackVector());
657  environment()->BindAccumulator(node, &states);
658}
659
660
661void BytecodeGraphBuilder::VisitLdaGlobalSloppy(
662    const interpreter::BytecodeArrayIterator& iterator) {
663  DCHECK(is_sloppy(language_mode()));
664  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
665}
666
667
668void BytecodeGraphBuilder::VisitLdaGlobalStrict(
669    const interpreter::BytecodeArrayIterator& iterator) {
670  DCHECK(is_strict(language_mode()));
671  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
672}
673
674
675void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppy(
676    const interpreter::BytecodeArrayIterator& iterator) {
677  DCHECK(is_sloppy(language_mode()));
678  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
679}
680
681
682void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrict(
683    const interpreter::BytecodeArrayIterator& iterator) {
684  DCHECK(is_strict(language_mode()));
685  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
686}
687
688
689void BytecodeGraphBuilder::VisitLdaGlobalSloppyWide(
690    const interpreter::BytecodeArrayIterator& iterator) {
691  DCHECK(is_sloppy(language_mode()));
692  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
693}
694
695
696void BytecodeGraphBuilder::VisitLdaGlobalStrictWide(
697    const interpreter::BytecodeArrayIterator& iterator) {
698  DCHECK(is_strict(language_mode()));
699  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
700}
701
702
703void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppyWide(
704    const interpreter::BytecodeArrayIterator& iterator) {
705  DCHECK(is_sloppy(language_mode()));
706  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
707}
708
709
710void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide(
711    const interpreter::BytecodeArrayIterator& iterator) {
712  DCHECK(is_strict(language_mode()));
713  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
714}
715
716
717void BytecodeGraphBuilder::BuildStoreGlobal(
718    const interpreter::BytecodeArrayIterator& iterator) {
719  FrameStateBeforeAndAfter states(this, iterator);
720  Handle<Name> name =
721      Handle<Name>::cast(iterator.GetConstantForIndexOperand(0));
722  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
723  Node* value = environment()->LookupAccumulator();
724
725  const Operator* op =
726      javascript()->StoreGlobal(language_mode(), name, feedback);
727  Node* node = NewNode(op, value, BuildLoadFeedbackVector());
728  environment()->RecordAfterState(node, &states);
729}
730
731
732void BytecodeGraphBuilder::VisitStaGlobalSloppy(
733    const interpreter::BytecodeArrayIterator& iterator) {
734  DCHECK(is_sloppy(language_mode()));
735  BuildStoreGlobal(iterator);
736}
737
738
739void BytecodeGraphBuilder::VisitStaGlobalStrict(
740    const interpreter::BytecodeArrayIterator& iterator) {
741  DCHECK(is_strict(language_mode()));
742  BuildStoreGlobal(iterator);
743}
744
745void BytecodeGraphBuilder::VisitStaGlobalSloppyWide(
746    const interpreter::BytecodeArrayIterator& iterator) {
747  DCHECK(is_sloppy(language_mode()));
748  BuildStoreGlobal(iterator);
749}
750
751
752void BytecodeGraphBuilder::VisitStaGlobalStrictWide(
753    const interpreter::BytecodeArrayIterator& iterator) {
754  DCHECK(is_strict(language_mode()));
755  BuildStoreGlobal(iterator);
756}
757
758
759void BytecodeGraphBuilder::VisitLdaContextSlot(
760    const interpreter::BytecodeArrayIterator& iterator) {
761  // TODO(mythria): LoadContextSlots are unrolled by the required depth when
762  // generating bytecode. Hence the value of depth is always 0. Update this
763  // code, when the implementation changes.
764  // TODO(mythria): immutable flag is also set to false. This information is not
765  // available in bytecode array. update this code when the implementation
766  // changes.
767  const Operator* op =
768      javascript()->LoadContext(0, iterator.GetIndexOperand(1), false);
769  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
770  Node* node = NewNode(op, context);
771  environment()->BindAccumulator(node);
772}
773
774
775void BytecodeGraphBuilder::VisitLdaContextSlotWide(
776    const interpreter::BytecodeArrayIterator& iterator) {
777  VisitLdaContextSlot(iterator);
778}
779
780
781void BytecodeGraphBuilder::VisitStaContextSlot(
782    const interpreter::BytecodeArrayIterator& iterator) {
783  // TODO(mythria): LoadContextSlots are unrolled by the required depth when
784  // generating bytecode. Hence the value of depth is always 0. Update this
785  // code, when the implementation changes.
786  const Operator* op =
787      javascript()->StoreContext(0, iterator.GetIndexOperand(1));
788  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
789  Node* value = environment()->LookupAccumulator();
790  NewNode(op, context, value);
791}
792
793
794void BytecodeGraphBuilder::VisitStaContextSlotWide(
795    const interpreter::BytecodeArrayIterator& iterator) {
796  VisitStaContextSlot(iterator);
797}
798
799
800void BytecodeGraphBuilder::BuildLdaLookupSlot(
801    TypeofMode typeof_mode,
802    const interpreter::BytecodeArrayIterator& iterator) {
803  FrameStateBeforeAndAfter states(this, iterator);
804  Handle<String> name =
805      Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
806  const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
807  Node* value =
808      NewNode(op, BuildLoadFeedbackVector(), environment()->Context());
809  environment()->BindAccumulator(value, &states);
810}
811
812
813void BytecodeGraphBuilder::VisitLdaLookupSlot(
814    const interpreter::BytecodeArrayIterator& iterator) {
815  BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF, iterator);
816}
817
818
819void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof(
820    const interpreter::BytecodeArrayIterator& iterator) {
821  BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF, iterator);
822}
823
824
825void BytecodeGraphBuilder::BuildStaLookupSlot(
826    LanguageMode language_mode,
827    const interpreter::BytecodeArrayIterator& iterator) {
828  FrameStateBeforeAndAfter states(this, iterator);
829  Node* value = environment()->LookupAccumulator();
830  Node* name = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
831  Node* language = jsgraph()->Constant(language_mode);
832  const Operator* op = javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
833  Node* store = NewNode(op, value, environment()->Context(), name, language);
834  environment()->BindAccumulator(store, &states);
835}
836
837
838void BytecodeGraphBuilder::VisitLdaLookupSlotWide(
839    const interpreter::BytecodeArrayIterator& iterator) {
840  VisitLdaLookupSlot(iterator);
841}
842
843
844void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeofWide(
845    const interpreter::BytecodeArrayIterator& iterator) {
846  VisitLdaLookupSlotInsideTypeof(iterator);
847}
848
849
850void BytecodeGraphBuilder::VisitStaLookupSlotSloppy(
851    const interpreter::BytecodeArrayIterator& iterator) {
852  BuildStaLookupSlot(LanguageMode::SLOPPY, iterator);
853}
854
855
856void BytecodeGraphBuilder::VisitStaLookupSlotStrict(
857    const interpreter::BytecodeArrayIterator& iterator) {
858  BuildStaLookupSlot(LanguageMode::STRICT, iterator);
859}
860
861
862void BytecodeGraphBuilder::VisitStaLookupSlotSloppyWide(
863    const interpreter::BytecodeArrayIterator& iterator) {
864  VisitStaLookupSlotSloppy(iterator);
865}
866
867
868void BytecodeGraphBuilder::VisitStaLookupSlotStrictWide(
869    const interpreter::BytecodeArrayIterator& iterator) {
870  VisitStaLookupSlotStrict(iterator);
871}
872
873
874void BytecodeGraphBuilder::BuildNamedLoad(
875    const interpreter::BytecodeArrayIterator& iterator) {
876  FrameStateBeforeAndAfter states(this, iterator);
877  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
878  Handle<Name> name =
879      Handle<Name>::cast(iterator.GetConstantForIndexOperand(1));
880  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
881
882  const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback);
883  Node* node = NewNode(op, object, BuildLoadFeedbackVector());
884  environment()->BindAccumulator(node, &states);
885}
886
887
888void BytecodeGraphBuilder::VisitLoadICSloppy(
889    const interpreter::BytecodeArrayIterator& iterator) {
890  DCHECK(is_sloppy(language_mode()));
891  BuildNamedLoad(iterator);
892}
893
894
895void BytecodeGraphBuilder::VisitLoadICStrict(
896    const interpreter::BytecodeArrayIterator& iterator) {
897  DCHECK(is_strict(language_mode()));
898  BuildNamedLoad(iterator);
899}
900
901
902void BytecodeGraphBuilder::VisitLoadICSloppyWide(
903    const interpreter::BytecodeArrayIterator& iterator) {
904  DCHECK(is_sloppy(language_mode()));
905  BuildNamedLoad(iterator);
906}
907
908
909void BytecodeGraphBuilder::VisitLoadICStrictWide(
910    const interpreter::BytecodeArrayIterator& iterator) {
911  DCHECK(is_strict(language_mode()));
912  BuildNamedLoad(iterator);
913}
914
915
916void BytecodeGraphBuilder::BuildKeyedLoad(
917    const interpreter::BytecodeArrayIterator& iterator) {
918  FrameStateBeforeAndAfter states(this, iterator);
919  Node* key = environment()->LookupAccumulator();
920  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
921  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
922
923  const Operator* op = javascript()->LoadProperty(language_mode(), feedback);
924  Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
925  environment()->BindAccumulator(node, &states);
926}
927
928
929void BytecodeGraphBuilder::VisitKeyedLoadICSloppy(
930    const interpreter::BytecodeArrayIterator& iterator) {
931  DCHECK(is_sloppy(language_mode()));
932  BuildKeyedLoad(iterator);
933}
934
935
936void BytecodeGraphBuilder::VisitKeyedLoadICStrict(
937    const interpreter::BytecodeArrayIterator& iterator) {
938  DCHECK(is_strict(language_mode()));
939  BuildKeyedLoad(iterator);
940}
941
942
943void BytecodeGraphBuilder::VisitKeyedLoadICSloppyWide(
944    const interpreter::BytecodeArrayIterator& iterator) {
945  DCHECK(is_sloppy(language_mode()));
946  BuildKeyedLoad(iterator);
947}
948
949
950void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide(
951    const interpreter::BytecodeArrayIterator& iterator) {
952  DCHECK(is_strict(language_mode()));
953  BuildKeyedLoad(iterator);
954}
955
956
957void BytecodeGraphBuilder::BuildNamedStore(
958    const interpreter::BytecodeArrayIterator& iterator) {
959  FrameStateBeforeAndAfter states(this, iterator);
960  Node* value = environment()->LookupAccumulator();
961  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
962  Handle<Name> name =
963      Handle<Name>::cast(iterator.GetConstantForIndexOperand(1));
964  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
965
966  const Operator* op =
967      javascript()->StoreNamed(language_mode(), name, feedback);
968  Node* node = NewNode(op, object, value, BuildLoadFeedbackVector());
969  environment()->RecordAfterState(node, &states);
970}
971
972
973void BytecodeGraphBuilder::VisitStoreICSloppy(
974    const interpreter::BytecodeArrayIterator& iterator) {
975  DCHECK(is_sloppy(language_mode()));
976  BuildNamedStore(iterator);
977}
978
979
980void BytecodeGraphBuilder::VisitStoreICStrict(
981    const interpreter::BytecodeArrayIterator& iterator) {
982  DCHECK(is_strict(language_mode()));
983  BuildNamedStore(iterator);
984}
985
986
987void BytecodeGraphBuilder::VisitStoreICSloppyWide(
988    const interpreter::BytecodeArrayIterator& iterator) {
989  DCHECK(is_sloppy(language_mode()));
990  BuildNamedStore(iterator);
991}
992
993
994void BytecodeGraphBuilder::VisitStoreICStrictWide(
995    const interpreter::BytecodeArrayIterator& iterator) {
996  DCHECK(is_strict(language_mode()));
997  BuildNamedStore(iterator);
998}
999
1000
1001void BytecodeGraphBuilder::BuildKeyedStore(
1002    const interpreter::BytecodeArrayIterator& iterator) {
1003  FrameStateBeforeAndAfter states(this, iterator);
1004  Node* value = environment()->LookupAccumulator();
1005  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1006  Node* key = environment()->LookupRegister(iterator.GetRegisterOperand(1));
1007  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
1008
1009  const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
1010  Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector());
1011  environment()->RecordAfterState(node, &states);
1012}
1013
1014
1015void BytecodeGraphBuilder::VisitKeyedStoreICSloppy(
1016    const interpreter::BytecodeArrayIterator& iterator) {
1017  DCHECK(is_sloppy(language_mode()));
1018  BuildKeyedStore(iterator);
1019}
1020
1021
1022void BytecodeGraphBuilder::VisitKeyedStoreICStrict(
1023    const interpreter::BytecodeArrayIterator& iterator) {
1024  DCHECK(is_strict(language_mode()));
1025  BuildKeyedStore(iterator);
1026}
1027
1028
1029void BytecodeGraphBuilder::VisitKeyedStoreICSloppyWide(
1030    const interpreter::BytecodeArrayIterator& iterator) {
1031  DCHECK(is_sloppy(language_mode()));
1032  BuildKeyedStore(iterator);
1033}
1034
1035
1036void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide(
1037    const interpreter::BytecodeArrayIterator& iterator) {
1038  DCHECK(is_strict(language_mode()));
1039  BuildKeyedStore(iterator);
1040}
1041
1042
1043void BytecodeGraphBuilder::VisitPushContext(
1044    const interpreter::BytecodeArrayIterator& iterator) {
1045  Node* context = environment()->LookupAccumulator();
1046  environment()->BindRegister(iterator.GetRegisterOperand(0), context);
1047  environment()->SetContext(context);
1048}
1049
1050
1051void BytecodeGraphBuilder::VisitPopContext(
1052    const interpreter::BytecodeArrayIterator& iterator) {
1053  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1054  environment()->SetContext(context);
1055}
1056
1057
1058void BytecodeGraphBuilder::VisitCreateClosure(
1059    const interpreter::BytecodeArrayIterator& iterator) {
1060  Handle<SharedFunctionInfo> shared_info =
1061      Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0));
1062  PretenureFlag tenured =
1063      iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED;
1064  const Operator* op = javascript()->CreateClosure(shared_info, tenured);
1065  Node* closure = NewNode(op);
1066  environment()->BindAccumulator(closure);
1067}
1068
1069
1070void BytecodeGraphBuilder::VisitCreateClosureWide(
1071    const interpreter::BytecodeArrayIterator& iterator) {
1072  VisitCreateClosure(iterator);
1073}
1074
1075
1076void BytecodeGraphBuilder::BuildCreateArguments(
1077    CreateArgumentsParameters::Type type,
1078    const interpreter::BytecodeArrayIterator& iterator) {
1079  FrameStateBeforeAndAfter states(this, iterator);
1080  const Operator* op = javascript()->CreateArguments(type, 0);
1081  Node* object = NewNode(op, GetFunctionClosure());
1082  environment()->BindAccumulator(object, &states);
1083}
1084
1085
1086void BytecodeGraphBuilder::VisitCreateMappedArguments(
1087    const interpreter::BytecodeArrayIterator& iterator) {
1088  BuildCreateArguments(CreateArgumentsParameters::kMappedArguments, iterator);
1089}
1090
1091
1092void BytecodeGraphBuilder::VisitCreateUnmappedArguments(
1093    const interpreter::BytecodeArrayIterator& iterator) {
1094  BuildCreateArguments(CreateArgumentsParameters::kUnmappedArguments, iterator);
1095}
1096
1097
1098void BytecodeGraphBuilder::BuildCreateLiteral(
1099    const Operator* op, const interpreter::BytecodeArrayIterator& iterator) {
1100  FrameStateBeforeAndAfter states(this, iterator);
1101  Node* literal = NewNode(op, GetFunctionClosure());
1102  environment()->BindAccumulator(literal, &states);
1103}
1104
1105
1106void BytecodeGraphBuilder::BuildCreateRegExpLiteral(
1107    const interpreter::BytecodeArrayIterator& iterator) {
1108  Handle<String> constant_pattern =
1109      Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
1110  int literal_index = iterator.GetIndexOperand(1);
1111  int literal_flags = iterator.GetImmediateOperand(2);
1112  const Operator* op = javascript()->CreateLiteralRegExp(
1113      constant_pattern, literal_flags, literal_index);
1114  BuildCreateLiteral(op, iterator);
1115}
1116
1117
1118void BytecodeGraphBuilder::VisitCreateRegExpLiteral(
1119    const interpreter::BytecodeArrayIterator& iterator) {
1120  BuildCreateRegExpLiteral(iterator);
1121}
1122
1123
1124void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide(
1125    const interpreter::BytecodeArrayIterator& iterator) {
1126  BuildCreateRegExpLiteral(iterator);
1127}
1128
1129
1130void BytecodeGraphBuilder::BuildCreateArrayLiteral(
1131    const interpreter::BytecodeArrayIterator& iterator) {
1132  Handle<FixedArray> constant_elements =
1133      Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
1134  int literal_index = iterator.GetIndexOperand(1);
1135  int literal_flags = iterator.GetImmediateOperand(2);
1136  const Operator* op = javascript()->CreateLiteralArray(
1137      constant_elements, literal_flags, literal_index);
1138  BuildCreateLiteral(op, iterator);
1139}
1140
1141
1142void BytecodeGraphBuilder::VisitCreateArrayLiteral(
1143    const interpreter::BytecodeArrayIterator& iterator) {
1144  BuildCreateArrayLiteral(iterator);
1145}
1146
1147
1148void BytecodeGraphBuilder::VisitCreateArrayLiteralWide(
1149    const interpreter::BytecodeArrayIterator& iterator) {
1150  BuildCreateArrayLiteral(iterator);
1151}
1152
1153
1154void BytecodeGraphBuilder::BuildCreateObjectLiteral(
1155    const interpreter::BytecodeArrayIterator& iterator) {
1156  Handle<FixedArray> constant_properties =
1157      Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
1158  int literal_index = iterator.GetIndexOperand(1);
1159  int literal_flags = iterator.GetImmediateOperand(2);
1160  const Operator* op = javascript()->CreateLiteralObject(
1161      constant_properties, literal_flags, literal_index);
1162  BuildCreateLiteral(op, iterator);
1163}
1164
1165
1166void BytecodeGraphBuilder::VisitCreateObjectLiteral(
1167    const interpreter::BytecodeArrayIterator& iterator) {
1168  BuildCreateObjectLiteral(iterator);
1169}
1170
1171
1172void BytecodeGraphBuilder::VisitCreateObjectLiteralWide(
1173    const interpreter::BytecodeArrayIterator& iterator) {
1174  BuildCreateObjectLiteral(iterator);
1175}
1176
1177
1178Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
1179                                                 Node* callee,
1180                                                 interpreter::Register receiver,
1181                                                 size_t arity) {
1182  Node** all = info()->zone()->NewArray<Node*>(static_cast<int>(arity));
1183  all[0] = callee;
1184  all[1] = environment()->LookupRegister(receiver);
1185  int receiver_index = receiver.index();
1186  for (int i = 2; i < static_cast<int>(arity); ++i) {
1187    all[i] = environment()->LookupRegister(
1188        interpreter::Register(receiver_index + i - 1));
1189  }
1190  Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
1191  return value;
1192}
1193
1194
1195void BytecodeGraphBuilder::BuildCall(
1196    const interpreter::BytecodeArrayIterator& iterator) {
1197  FrameStateBeforeAndAfter states(this, iterator);
1198  // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
1199  // register has been loaded with null / undefined explicitly or we are sure it
1200  // is not null / undefined.
1201  ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
1202  Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1203  interpreter::Register receiver = iterator.GetRegisterOperand(1);
1204  size_t arg_count = iterator.GetCountOperand(2);
1205  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3));
1206
1207  const Operator* call = javascript()->CallFunction(
1208      arg_count + 2, language_mode(), feedback, receiver_hint);
1209  Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
1210  environment()->BindAccumulator(value, &states);
1211}
1212
1213
1214void BytecodeGraphBuilder::VisitCall(
1215    const interpreter::BytecodeArrayIterator& iterator) {
1216  BuildCall(iterator);
1217}
1218
1219
1220void BytecodeGraphBuilder::VisitCallWide(
1221    const interpreter::BytecodeArrayIterator& iterator) {
1222  BuildCall(iterator);
1223}
1224
1225
1226void BytecodeGraphBuilder::VisitCallJSRuntime(
1227    const interpreter::BytecodeArrayIterator& iterator) {
1228  FrameStateBeforeAndAfter states(this, iterator);
1229  Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0));
1230  interpreter::Register receiver = iterator.GetRegisterOperand(1);
1231  size_t arg_count = iterator.GetCountOperand(2);
1232
1233  // Create node to perform the JS runtime call.
1234  const Operator* call =
1235      javascript()->CallFunction(arg_count + 2, language_mode());
1236  Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
1237  environment()->BindAccumulator(value, &states);
1238}
1239
1240
1241Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
1242    const Operator* call_runtime_op, interpreter::Register first_arg,
1243    size_t arity) {
1244  Node** all = info()->zone()->NewArray<Node*>(arity);
1245  int first_arg_index = first_arg.index();
1246  for (int i = 0; i < static_cast<int>(arity); ++i) {
1247    all[i] = environment()->LookupRegister(
1248        interpreter::Register(first_arg_index + i));
1249  }
1250  Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
1251  return value;
1252}
1253
1254
1255void BytecodeGraphBuilder::VisitCallRuntime(
1256    const interpreter::BytecodeArrayIterator& iterator) {
1257  FrameStateBeforeAndAfter states(this, iterator);
1258  Runtime::FunctionId functionId =
1259      static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
1260  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
1261  size_t arg_count = iterator.GetCountOperand(2);
1262
1263  // Create node to perform the runtime call.
1264  const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1265  Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1266  environment()->BindAccumulator(value, &states);
1267}
1268
1269
1270void BytecodeGraphBuilder::VisitCallRuntimeForPair(
1271    const interpreter::BytecodeArrayIterator& iterator) {
1272  FrameStateBeforeAndAfter states(this, iterator);
1273  Runtime::FunctionId functionId =
1274      static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
1275  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
1276  size_t arg_count = iterator.GetCountOperand(2);
1277  interpreter::Register first_return = iterator.GetRegisterOperand(3);
1278
1279  // Create node to perform the runtime call.
1280  const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1281  Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1282  environment()->BindRegistersToProjections(first_return, return_pair, &states);
1283}
1284
1285
1286Node* BytecodeGraphBuilder::ProcessCallNewArguments(
1287    const Operator* call_new_op, interpreter::Register callee,
1288    interpreter::Register first_arg, size_t arity) {
1289  Node** all = info()->zone()->NewArray<Node*>(arity);
1290  all[0] = environment()->LookupRegister(callee);
1291  int first_arg_index = first_arg.index();
1292  for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
1293    all[i] = environment()->LookupRegister(
1294        interpreter::Register(first_arg_index + i - 1));
1295  }
1296  // Original constructor is the same as the callee.
1297  all[arity - 1] = environment()->LookupRegister(callee);
1298  Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
1299  return value;
1300}
1301
1302
1303void BytecodeGraphBuilder::VisitNew(
1304    const interpreter::BytecodeArrayIterator& iterator) {
1305  FrameStateBeforeAndAfter states(this, iterator);
1306  interpreter::Register callee = iterator.GetRegisterOperand(0);
1307  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
1308  size_t arg_count = iterator.GetCountOperand(2);
1309
1310  // TODO(turbofan): Pass the feedback here.
1311  const Operator* call = javascript()->CallConstruct(
1312      static_cast<int>(arg_count) + 2, VectorSlotPair());
1313  Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2);
1314  environment()->BindAccumulator(value, &states);
1315}
1316
1317
1318void BytecodeGraphBuilder::VisitThrow(
1319    const interpreter::BytecodeArrayIterator& iterator) {
1320  FrameStateBeforeAndAfter states(this, iterator);
1321  Node* value = environment()->LookupAccumulator();
1322  // TODO(mythria): Change to Runtime::kThrow when we have deoptimization
1323  // information support in the interpreter.
1324  NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), value);
1325  Node* control = NewNode(common()->Throw(), value);
1326  environment()->RecordAfterState(control, &states);
1327  UpdateControlDependencyToLeaveFunction(control);
1328}
1329
1330
1331void BytecodeGraphBuilder::BuildBinaryOp(
1332    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
1333  FrameStateBeforeAndAfter states(this, iterator);
1334  Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1335  Node* right = environment()->LookupAccumulator();
1336  Node* node = NewNode(js_op, left, right);
1337  environment()->BindAccumulator(node, &states);
1338}
1339
1340
1341void BytecodeGraphBuilder::VisitAdd(
1342    const interpreter::BytecodeArrayIterator& iterator) {
1343  BinaryOperationHints hints = BinaryOperationHints::Any();
1344  BuildBinaryOp(javascript()->Add(language_mode(), hints), iterator);
1345}
1346
1347
1348void BytecodeGraphBuilder::VisitSub(
1349    const interpreter::BytecodeArrayIterator& iterator) {
1350  BinaryOperationHints hints = BinaryOperationHints::Any();
1351  BuildBinaryOp(javascript()->Subtract(language_mode(), hints), iterator);
1352}
1353
1354
1355void BytecodeGraphBuilder::VisitMul(
1356    const interpreter::BytecodeArrayIterator& iterator) {
1357  BinaryOperationHints hints = BinaryOperationHints::Any();
1358  BuildBinaryOp(javascript()->Multiply(language_mode(), hints), iterator);
1359}
1360
1361
1362void BytecodeGraphBuilder::VisitDiv(
1363    const interpreter::BytecodeArrayIterator& iterator) {
1364  BinaryOperationHints hints = BinaryOperationHints::Any();
1365  BuildBinaryOp(javascript()->Divide(language_mode(), hints), iterator);
1366}
1367
1368
1369void BytecodeGraphBuilder::VisitMod(
1370    const interpreter::BytecodeArrayIterator& iterator) {
1371  BinaryOperationHints hints = BinaryOperationHints::Any();
1372  BuildBinaryOp(javascript()->Modulus(language_mode(), hints), iterator);
1373}
1374
1375
1376void BytecodeGraphBuilder::VisitBitwiseOr(
1377    const interpreter::BytecodeArrayIterator& iterator) {
1378  BinaryOperationHints hints = BinaryOperationHints::Any();
1379  BuildBinaryOp(javascript()->BitwiseOr(language_mode(), hints), iterator);
1380}
1381
1382
1383void BytecodeGraphBuilder::VisitBitwiseXor(
1384    const interpreter::BytecodeArrayIterator& iterator) {
1385  BinaryOperationHints hints = BinaryOperationHints::Any();
1386  BuildBinaryOp(javascript()->BitwiseXor(language_mode(), hints), iterator);
1387}
1388
1389
1390void BytecodeGraphBuilder::VisitBitwiseAnd(
1391    const interpreter::BytecodeArrayIterator& iterator) {
1392  BinaryOperationHints hints = BinaryOperationHints::Any();
1393  BuildBinaryOp(javascript()->BitwiseAnd(language_mode(), hints), iterator);
1394}
1395
1396
1397void BytecodeGraphBuilder::VisitShiftLeft(
1398    const interpreter::BytecodeArrayIterator& iterator) {
1399  BinaryOperationHints hints = BinaryOperationHints::Any();
1400  BuildBinaryOp(javascript()->ShiftLeft(language_mode(), hints), iterator);
1401}
1402
1403
1404void BytecodeGraphBuilder::VisitShiftRight(
1405    const interpreter::BytecodeArrayIterator& iterator) {
1406  BinaryOperationHints hints = BinaryOperationHints::Any();
1407  BuildBinaryOp(javascript()->ShiftRight(language_mode(), hints), iterator);
1408}
1409
1410
1411void BytecodeGraphBuilder::VisitShiftRightLogical(
1412    const interpreter::BytecodeArrayIterator& iterator) {
1413  BinaryOperationHints hints = BinaryOperationHints::Any();
1414  BuildBinaryOp(javascript()->ShiftRightLogical(language_mode(), hints),
1415                iterator);
1416}
1417
1418
1419void BytecodeGraphBuilder::VisitInc(
1420    const interpreter::BytecodeArrayIterator& iterator) {
1421  FrameStateBeforeAndAfter states(this, iterator);
1422  const Operator* js_op =
1423      javascript()->Add(language_mode(), BinaryOperationHints::Any());
1424  Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1425                       jsgraph()->OneConstant());
1426  environment()->BindAccumulator(node, &states);
1427}
1428
1429
1430void BytecodeGraphBuilder::VisitDec(
1431    const interpreter::BytecodeArrayIterator& iterator) {
1432  FrameStateBeforeAndAfter states(this, iterator);
1433  const Operator* js_op =
1434      javascript()->Subtract(language_mode(), BinaryOperationHints::Any());
1435  Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1436                       jsgraph()->OneConstant());
1437  environment()->BindAccumulator(node, &states);
1438}
1439
1440
1441void BytecodeGraphBuilder::VisitLogicalNot(
1442    const interpreter::BytecodeArrayIterator& iterator) {
1443  Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
1444                        environment()->LookupAccumulator());
1445  Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
1446                       jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1447  environment()->BindAccumulator(node);
1448}
1449
1450
1451void BytecodeGraphBuilder::VisitTypeOf(
1452    const interpreter::BytecodeArrayIterator& iterator) {
1453  Node* node =
1454      NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
1455  environment()->BindAccumulator(node);
1456}
1457
1458
1459void BytecodeGraphBuilder::BuildDelete(
1460    const interpreter::BytecodeArrayIterator& iterator) {
1461  FrameStateBeforeAndAfter states(this, iterator);
1462  Node* key = environment()->LookupAccumulator();
1463  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1464  Node* node =
1465      NewNode(javascript()->DeleteProperty(language_mode()), object, key);
1466  environment()->BindAccumulator(node, &states);
1467}
1468
1469
1470void BytecodeGraphBuilder::VisitDeletePropertyStrict(
1471    const interpreter::BytecodeArrayIterator& iterator) {
1472  DCHECK(is_strict(language_mode()));
1473  BuildDelete(iterator);
1474}
1475
1476
1477void BytecodeGraphBuilder::VisitDeletePropertySloppy(
1478    const interpreter::BytecodeArrayIterator& iterator) {
1479  DCHECK(is_sloppy(language_mode()));
1480  BuildDelete(iterator);
1481}
1482
1483
1484void BytecodeGraphBuilder::VisitDeleteLookupSlot(
1485    const interpreter::BytecodeArrayIterator& iterator) {
1486  FrameStateBeforeAndAfter states(this, iterator);
1487  Node* name = environment()->LookupAccumulator();
1488  const Operator* op = javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
1489  Node* result = NewNode(op, environment()->Context(), name);
1490  environment()->BindAccumulator(result, &states);
1491}
1492
1493
1494void BytecodeGraphBuilder::BuildCompareOp(
1495    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
1496  FrameStateBeforeAndAfter states(this, iterator);
1497  Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1498  Node* right = environment()->LookupAccumulator();
1499  Node* node = NewNode(js_op, left, right);
1500  environment()->BindAccumulator(node, &states);
1501}
1502
1503
1504void BytecodeGraphBuilder::VisitTestEqual(
1505    const interpreter::BytecodeArrayIterator& iterator) {
1506  BuildCompareOp(javascript()->Equal(), iterator);
1507}
1508
1509
1510void BytecodeGraphBuilder::VisitTestNotEqual(
1511    const interpreter::BytecodeArrayIterator& iterator) {
1512  BuildCompareOp(javascript()->NotEqual(), iterator);
1513}
1514
1515
1516void BytecodeGraphBuilder::VisitTestEqualStrict(
1517    const interpreter::BytecodeArrayIterator& iterator) {
1518  BuildCompareOp(javascript()->StrictEqual(), iterator);
1519}
1520
1521
1522void BytecodeGraphBuilder::VisitTestNotEqualStrict(
1523    const interpreter::BytecodeArrayIterator& iterator) {
1524  BuildCompareOp(javascript()->StrictNotEqual(), iterator);
1525}
1526
1527
1528void BytecodeGraphBuilder::VisitTestLessThan(
1529    const interpreter::BytecodeArrayIterator& iterator) {
1530  BuildCompareOp(javascript()->LessThan(language_mode()), iterator);
1531}
1532
1533
1534void BytecodeGraphBuilder::VisitTestGreaterThan(
1535    const interpreter::BytecodeArrayIterator& iterator) {
1536  BuildCompareOp(javascript()->GreaterThan(language_mode()), iterator);
1537}
1538
1539
1540void BytecodeGraphBuilder::VisitTestLessThanOrEqual(
1541    const interpreter::BytecodeArrayIterator& iterator) {
1542  BuildCompareOp(javascript()->LessThanOrEqual(language_mode()), iterator);
1543}
1544
1545
1546void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual(
1547    const interpreter::BytecodeArrayIterator& iterator) {
1548  BuildCompareOp(javascript()->GreaterThanOrEqual(language_mode()), iterator);
1549}
1550
1551
1552void BytecodeGraphBuilder::VisitTestIn(
1553    const interpreter::BytecodeArrayIterator& iterator) {
1554  BuildCompareOp(javascript()->HasProperty(), iterator);
1555}
1556
1557
1558void BytecodeGraphBuilder::VisitTestInstanceOf(
1559    const interpreter::BytecodeArrayIterator& iterator) {
1560  BuildCompareOp(javascript()->InstanceOf(), iterator);
1561}
1562
1563
1564void BytecodeGraphBuilder::BuildCastOperator(
1565    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
1566  FrameStateBeforeAndAfter states(this, iterator);
1567  Node* node = NewNode(js_op, environment()->LookupAccumulator());
1568  environment()->BindAccumulator(node, &states);
1569}
1570
1571
1572void BytecodeGraphBuilder::VisitToName(
1573    const interpreter::BytecodeArrayIterator& iterator) {
1574  BuildCastOperator(javascript()->ToName(), iterator);
1575}
1576
1577
1578void BytecodeGraphBuilder::VisitToObject(
1579    const interpreter::BytecodeArrayIterator& iterator) {
1580  BuildCastOperator(javascript()->ToObject(), iterator);
1581}
1582
1583
1584void BytecodeGraphBuilder::VisitToNumber(
1585    const interpreter::BytecodeArrayIterator& iterator) {
1586  BuildCastOperator(javascript()->ToNumber(), iterator);
1587}
1588
1589
1590void BytecodeGraphBuilder::VisitJump(
1591    const interpreter::BytecodeArrayIterator& iterator) {
1592  BuildJump();
1593}
1594
1595
1596void BytecodeGraphBuilder::VisitJumpConstant(
1597    const interpreter::BytecodeArrayIterator& iterator) {
1598  BuildJump();
1599}
1600
1601
1602void BytecodeGraphBuilder::VisitJumpConstantWide(
1603    const interpreter::BytecodeArrayIterator& iterator) {
1604  BuildJump();
1605}
1606
1607
1608void BytecodeGraphBuilder::VisitJumpIfTrue(
1609    const interpreter::BytecodeArrayIterator& iterator) {
1610  BuildJumpIfEqual(jsgraph()->TrueConstant());
1611}
1612
1613
1614void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
1615    const interpreter::BytecodeArrayIterator& iterator) {
1616  BuildJumpIfEqual(jsgraph()->TrueConstant());
1617}
1618
1619
1620void BytecodeGraphBuilder::VisitJumpIfTrueConstantWide(
1621    const interpreter::BytecodeArrayIterator& iterator) {
1622  BuildJumpIfEqual(jsgraph()->TrueConstant());
1623}
1624
1625
1626void BytecodeGraphBuilder::VisitJumpIfFalse(
1627    const interpreter::BytecodeArrayIterator& iterator) {
1628  BuildJumpIfEqual(jsgraph()->FalseConstant());
1629}
1630
1631
1632void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
1633    const interpreter::BytecodeArrayIterator& iterator) {
1634  BuildJumpIfEqual(jsgraph()->FalseConstant());
1635}
1636
1637
1638void BytecodeGraphBuilder::VisitJumpIfFalseConstantWide(
1639    const interpreter::BytecodeArrayIterator& iterator) {
1640  BuildJumpIfEqual(jsgraph()->FalseConstant());
1641}
1642
1643
1644void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
1645    const interpreter::BytecodeArrayIterator& iterator) {
1646  BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1647}
1648
1649
1650void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
1651    const interpreter::BytecodeArrayIterator& iterator) {
1652  BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1653}
1654
1655
1656void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstantWide(
1657    const interpreter::BytecodeArrayIterator& iterator) {
1658  BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1659}
1660
1661
1662void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
1663    const interpreter::BytecodeArrayIterator& iterator) {
1664  BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1665}
1666
1667
1668void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
1669    const interpreter::BytecodeArrayIterator& iterator) {
1670  BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1671}
1672
1673
1674void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstantWide(
1675    const interpreter::BytecodeArrayIterator& iterator) {
1676  BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1677}
1678
1679
1680void BytecodeGraphBuilder::VisitJumpIfNull(
1681    const interpreter::BytecodeArrayIterator& iterator) {
1682  BuildJumpIfEqual(jsgraph()->NullConstant());
1683}
1684
1685
1686void BytecodeGraphBuilder::VisitJumpIfNullConstant(
1687    const interpreter::BytecodeArrayIterator& iterator) {
1688  BuildJumpIfEqual(jsgraph()->NullConstant());
1689}
1690
1691
1692void BytecodeGraphBuilder::VisitJumpIfNullConstantWide(
1693    const interpreter::BytecodeArrayIterator& iterator) {
1694  BuildJumpIfEqual(jsgraph()->NullConstant());
1695}
1696
1697
1698void BytecodeGraphBuilder::VisitJumpIfUndefined(
1699    const interpreter::BytecodeArrayIterator& iterator) {
1700  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1701}
1702
1703
1704void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
1705    const interpreter::BytecodeArrayIterator& iterator) {
1706  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1707}
1708
1709
1710void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide(
1711    const interpreter::BytecodeArrayIterator& iterator) {
1712  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1713}
1714
1715
1716void BytecodeGraphBuilder::VisitReturn(
1717    const interpreter::BytecodeArrayIterator& iterator) {
1718  Node* control =
1719      NewNode(common()->Return(), environment()->LookupAccumulator());
1720  UpdateControlDependencyToLeaveFunction(control);
1721  set_environment(nullptr);
1722}
1723
1724
1725void BytecodeGraphBuilder::VisitForInPrepare(
1726    const interpreter::BytecodeArrayIterator& iterator) {
1727  Node* prepare = nullptr;
1728  {
1729    FrameStateBeforeAndAfter states(this, iterator);
1730    Node* receiver = environment()->LookupAccumulator();
1731    prepare = NewNode(javascript()->ForInPrepare(), receiver);
1732    environment()->RecordAfterState(prepare, &states);
1733  }
1734  // Project cache_type, cache_array, cache_length into register
1735  // operands 1, 2, 3.
1736  for (int i = 0; i < 3; i++) {
1737    environment()->BindRegister(iterator.GetRegisterOperand(i),
1738                                NewNode(common()->Projection(i), prepare));
1739  }
1740}
1741
1742
1743void BytecodeGraphBuilder::VisitForInDone(
1744    const interpreter::BytecodeArrayIterator& iterator) {
1745  FrameStateBeforeAndAfter states(this, iterator);
1746  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1747  Node* cache_length =
1748      environment()->LookupRegister(iterator.GetRegisterOperand(1));
1749  Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
1750  environment()->BindAccumulator(exit_cond, &states);
1751}
1752
1753
1754void BytecodeGraphBuilder::VisitForInNext(
1755    const interpreter::BytecodeArrayIterator& iterator) {
1756  FrameStateBeforeAndAfter states(this, iterator);
1757  Node* receiver =
1758      environment()->LookupRegister(iterator.GetRegisterOperand(0));
1759  Node* cache_type =
1760      environment()->LookupRegister(iterator.GetRegisterOperand(1));
1761  Node* cache_array =
1762      environment()->LookupRegister(iterator.GetRegisterOperand(2));
1763  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(3));
1764  Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
1765                        cache_type, index);
1766  environment()->BindAccumulator(value, &states);
1767}
1768
1769
1770void BytecodeGraphBuilder::VisitForInStep(
1771    const interpreter::BytecodeArrayIterator& iterator) {
1772  FrameStateBeforeAndAfter states(this, iterator);
1773  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1774  index = NewNode(javascript()->ForInStep(), index);
1775  environment()->BindAccumulator(index, &states);
1776}
1777
1778
1779void BytecodeGraphBuilder::MergeEnvironmentsOfBackwardBranches(
1780    int source_offset, int target_offset) {
1781  DCHECK_GE(source_offset, target_offset);
1782  const ZoneVector<int>* branch_sites =
1783      branch_analysis()->BackwardBranchesTargetting(target_offset);
1784  if (branch_sites->back() == source_offset) {
1785    // The set of back branches is complete, merge them.
1786    DCHECK_GE(branch_sites->at(0), target_offset);
1787    Environment* merged = merge_environments_[branch_sites->at(0)];
1788    for (size_t i = 1; i < branch_sites->size(); i++) {
1789      DCHECK_GE(branch_sites->at(i), target_offset);
1790      merged->Merge(merge_environments_[branch_sites->at(i)]);
1791    }
1792    // And now merge with loop header environment created when loop
1793    // header was visited.
1794    loop_header_environments_[target_offset]->Merge(merged);
1795  }
1796}
1797
1798
1799void BytecodeGraphBuilder::MergeEnvironmentsOfForwardBranches(
1800    int source_offset) {
1801  if (branch_analysis()->forward_branches_target(source_offset)) {
1802    // Merge environments of branches that reach this bytecode.
1803    auto branch_sites =
1804        branch_analysis()->ForwardBranchesTargetting(source_offset);
1805    DCHECK_LT(branch_sites->at(0), source_offset);
1806    Environment* merged = merge_environments_[branch_sites->at(0)];
1807    for (size_t i = 1; i < branch_sites->size(); i++) {
1808      DCHECK_LT(branch_sites->at(i), source_offset);
1809      merged->Merge(merge_environments_[branch_sites->at(i)]);
1810    }
1811    if (environment()) {
1812      merged->Merge(environment());
1813    }
1814    set_environment(merged);
1815  }
1816}
1817
1818
1819void BytecodeGraphBuilder::BuildLoopHeaderForBackwardBranches(
1820    int source_offset) {
1821  if (branch_analysis()->backward_branches_target(source_offset)) {
1822    // Add loop header and store a copy so we can connect merged back
1823    // edge inputs to the loop header.
1824    loop_header_environments_[source_offset] = environment()->CopyForLoop();
1825  }
1826}
1827
1828
1829void BytecodeGraphBuilder::BuildJump(int source_offset, int target_offset) {
1830  DCHECK_NULL(merge_environments_[source_offset]);
1831  merge_environments_[source_offset] = environment();
1832  if (source_offset >= target_offset) {
1833    MergeEnvironmentsOfBackwardBranches(source_offset, target_offset);
1834  }
1835  set_environment(nullptr);
1836}
1837
1838
1839void BytecodeGraphBuilder::BuildJump() {
1840  int source_offset = bytecode_iterator()->current_offset();
1841  int target_offset = bytecode_iterator()->GetJumpTargetOffset();
1842  BuildJump(source_offset, target_offset);
1843}
1844
1845
1846void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1847  int source_offset = bytecode_iterator()->current_offset();
1848  NewBranch(condition);
1849  Environment* if_false_environment = environment()->CopyForConditional();
1850  NewIfTrue();
1851  BuildJump(source_offset, bytecode_iterator()->GetJumpTargetOffset());
1852  set_environment(if_false_environment);
1853  NewIfFalse();
1854}
1855
1856
1857void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
1858  Node* accumulator = environment()->LookupAccumulator();
1859  Node* condition =
1860      NewNode(javascript()->StrictEqual(), accumulator, comperand);
1861  BuildConditionalJump(condition);
1862}
1863
1864
1865void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
1866  Node* accumulator = environment()->LookupAccumulator();
1867  Node* to_boolean =
1868      NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1869  Node* condition = NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1870  BuildConditionalJump(condition);
1871}
1872
1873
1874Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1875  if (size > input_buffer_size_) {
1876    size = size + kInputBufferSizeIncrement + input_buffer_size_;
1877    input_buffer_ = local_zone()->NewArray<Node*>(size);
1878    input_buffer_size_ = size;
1879  }
1880  return input_buffer_;
1881}
1882
1883
1884void BytecodeGraphBuilder::PrepareEntryFrameState(Node* node) {
1885  DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
1886  DCHECK_EQ(IrOpcode::kDead,
1887            NodeProperties::GetFrameStateInput(node, 0)->opcode());
1888  NodeProperties::ReplaceFrameStateInput(
1889      node, 0, environment()->Checkpoint(BailoutId(0),
1890                                         OutputFrameStateCombine::Ignore()));
1891}
1892
1893
1894Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
1895                                     Node** value_inputs, bool incomplete) {
1896  DCHECK_EQ(op->ValueInputCount(), value_input_count);
1897
1898  bool has_context = OperatorProperties::HasContextInput(op);
1899  int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
1900  bool has_control = op->ControlInputCount() == 1;
1901  bool has_effect = op->EffectInputCount() == 1;
1902
1903  DCHECK_LT(op->ControlInputCount(), 2);
1904  DCHECK_LT(op->EffectInputCount(), 2);
1905
1906  Node* result = nullptr;
1907  if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
1908    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
1909  } else {
1910    int input_count_with_deps = value_input_count;
1911    if (has_context) ++input_count_with_deps;
1912    input_count_with_deps += frame_state_count;
1913    if (has_control) ++input_count_with_deps;
1914    if (has_effect) ++input_count_with_deps;
1915    Node** buffer = EnsureInputBufferSize(input_count_with_deps);
1916    memcpy(buffer, value_inputs, kPointerSize * value_input_count);
1917    Node** current_input = buffer + value_input_count;
1918    if (has_context) {
1919      *current_input++ = environment()->Context();
1920    }
1921    for (int i = 0; i < frame_state_count; i++) {
1922      // The frame state will be inserted later. Here we misuse
1923      // the {Dead} node as a sentinel to be later overwritten
1924      // with the real frame state.
1925      *current_input++ = jsgraph()->Dead();
1926    }
1927    if (has_effect) {
1928      *current_input++ = environment()->GetEffectDependency();
1929    }
1930    if (has_control) {
1931      *current_input++ = environment()->GetControlDependency();
1932    }
1933    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
1934    if (!environment()->IsMarkedAsUnreachable()) {
1935      // Update the current control dependency for control-producing nodes.
1936      if (NodeProperties::IsControl(result)) {
1937        environment()->UpdateControlDependency(result);
1938      }
1939      // Update the current effect dependency for effect-producing nodes.
1940      if (result->op()->EffectOutputCount() > 0) {
1941        environment()->UpdateEffectDependency(result);
1942      }
1943      // Add implicit success continuation for throwing nodes.
1944      if (!result->op()->HasProperty(Operator::kNoThrow)) {
1945        const Operator* if_success = common()->IfSuccess();
1946        Node* on_success = graph()->NewNode(if_success, result);
1947        environment_->UpdateControlDependency(on_success);
1948      }
1949    }
1950  }
1951
1952  return result;
1953}
1954
1955
1956Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1957  const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1958  Node** buffer = EnsureInputBufferSize(count + 1);
1959  MemsetPointer(buffer, input, count);
1960  buffer[count] = control;
1961  return graph()->NewNode(phi_op, count + 1, buffer, true);
1962}
1963
1964
1965Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1966                                         Node* control) {
1967  const Operator* phi_op = common()->EffectPhi(count);
1968  Node** buffer = EnsureInputBufferSize(count + 1);
1969  MemsetPointer(buffer, input, count);
1970  buffer[count] = control;
1971  return graph()->NewNode(phi_op, count + 1, buffer, true);
1972}
1973
1974
1975Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1976  int inputs = control->op()->ControlInputCount() + 1;
1977  if (control->opcode() == IrOpcode::kLoop) {
1978    // Control node for loop exists, add input.
1979    const Operator* op = common()->Loop(inputs);
1980    control->AppendInput(graph_zone(), other);
1981    NodeProperties::ChangeOp(control, op);
1982  } else if (control->opcode() == IrOpcode::kMerge) {
1983    // Control node for merge exists, add input.
1984    const Operator* op = common()->Merge(inputs);
1985    control->AppendInput(graph_zone(), other);
1986    NodeProperties::ChangeOp(control, op);
1987  } else {
1988    // Control node is a singleton, introduce a merge.
1989    const Operator* op = common()->Merge(inputs);
1990    Node* merge_inputs[] = {control, other};
1991    control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1992  }
1993  return control;
1994}
1995
1996
1997Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1998                                        Node* control) {
1999  int inputs = control->op()->ControlInputCount();
2000  if (value->opcode() == IrOpcode::kEffectPhi &&
2001      NodeProperties::GetControlInput(value) == control) {
2002    // Phi already exists, add input.
2003    value->InsertInput(graph_zone(), inputs - 1, other);
2004    NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
2005  } else if (value != other) {
2006    // Phi does not exist yet, introduce one.
2007    value = NewEffectPhi(inputs, value, control);
2008    value->ReplaceInput(inputs - 1, other);
2009  }
2010  return value;
2011}
2012
2013
2014Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
2015                                       Node* control) {
2016  int inputs = control->op()->ControlInputCount();
2017  if (value->opcode() == IrOpcode::kPhi &&
2018      NodeProperties::GetControlInput(value) == control) {
2019    // Phi already exists, add input.
2020    value->InsertInput(graph_zone(), inputs - 1, other);
2021    NodeProperties::ChangeOp(
2022        value, common()->Phi(MachineRepresentation::kTagged, inputs));
2023  } else if (value != other) {
2024    // Phi does not exist yet, introduce one.
2025    value = NewPhi(inputs, value, control);
2026    value->ReplaceInput(inputs - 1, other);
2027  }
2028  return value;
2029}
2030
2031
2032void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
2033  if (environment()->IsMarkedAsUnreachable()) return;
2034  environment()->MarkAsUnreachable();
2035  exit_controls_.push_back(exit);
2036}
2037
2038}  // namespace compiler
2039}  // namespace internal
2040}  // namespace v8
2041