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 
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15 
16 // Helper for generating frame states for before and after a bytecode.
17 class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
18  public:
FrameStateBeforeAndAfter(BytecodeGraphBuilder * builder,const interpreter::BytecodeArrayIterator & iterator)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 
~FrameStateBeforeAndAfter()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 
AddToNode(Node * node,OutputFrameStateCombine combine)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.
Environment(BytecodeGraphBuilder * builder,int register_count,int parameter_count,Node * control_dependency,Node * context)81 BytecodeGraphBuilder::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 
Environment(const BytecodeGraphBuilder::Environment * other)123 BytecodeGraphBuilder::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 
RegisterToValuesIndex(interpreter::Register the_register) const141 int 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 
LookupAccumulator() const151 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
152   return values()->at(accumulator_base_);
153 }
154 
155 
LookupRegister(interpreter::Register the_register) const156 Node* 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 
ExchangeRegisters(interpreter::Register reg0,interpreter::Register reg1)171 void 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 
BindAccumulator(Node * node,FrameStateBeforeAndAfter * states)181 void 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 
BindRegister(interpreter::Register the_register,Node * node,FrameStateBeforeAndAfter * states)190 void 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 
BindRegistersToProjections(interpreter::Register first_reg,Node * node,FrameStateBeforeAndAfter * states)202 void 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 
RecordAfterState(Node * node,FrameStateBeforeAndAfter * states)217 void BytecodeGraphBuilder::Environment::RecordAfterState(
218     Node* node, FrameStateBeforeAndAfter* states) {
219   states->AddToNode(node, OutputFrameStateCombine::Ignore());
220 }
221 
222 
IsMarkedAsUnreachable() const223 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
224   return GetControlDependency()->opcode() == IrOpcode::kDead;
225 }
226 
227 
MarkAsUnreachable()228 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
229   UpdateControlDependency(builder()->jsgraph()->Dead());
230 }
231 
232 
233 BytecodeGraphBuilder::Environment*
CopyForLoop()234 BytecodeGraphBuilder::Environment::CopyForLoop() {
235   PrepareForLoop();
236   return new (zone()) Environment(this);
237 }
238 
239 
240 BytecodeGraphBuilder::Environment*
CopyForConditional() const241 BytecodeGraphBuilder::Environment::CopyForConditional() const {
242   return new (zone()) Environment(this);
243 }
244 
245 
Merge(BytecodeGraphBuilder::Environment * other)246 void 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 
PrepareForLoop()274 void 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 
StateValuesRequireUpdate(Node ** state_values,int offset,int count)296 bool 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 
UpdateStateValues(Node ** state_values,int offset,int count)316 void 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 
Checkpoint(BailoutId bailout_id,OutputFrameStateCombine combine)326 Node* 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 
StateValuesAreUpToDate(Node ** state_values,int offset,int count,int output_poke_start,int output_poke_end)349 bool 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 
StateValuesAreUpToDate(int output_poke_offset,int output_poke_count)364 bool 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 
BytecodeGraphBuilder(Zone * local_zone,CompilationInfo * compilation_info,JSGraph * jsgraph)379 BytecodeGraphBuilder::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 
GetNewTarget()398 Node* 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 
GetFunctionContext()410 Node* 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 
GetFunctionClosure()422 Node* 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 
BuildLoadObjectField(Node * object,int offset)433 Node* BytecodeGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
434   return NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), object,
435                  jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
436 }
437 
438 
BuildLoadImmutableObjectField(Node * object,int offset)439 Node* 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 
BuildLoadNativeContextField(int index)448 Node* 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 
BuildLoadFeedbackVector()456 Node* 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 
CreateVectorSlotPair(int slot_id)469 VectorSlotPair 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 
CreateGraph(bool stack_check)479 bool 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 
CreateGraphBody(bool stack_check)508 void 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 
VisitBytecodes()521 void 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 
VisitLdaZero(const interpreter::BytecodeArrayIterator & iterator)549 void BytecodeGraphBuilder::VisitLdaZero(
550     const interpreter::BytecodeArrayIterator& iterator) {
551   Node* node = jsgraph()->ZeroConstant();
552   environment()->BindAccumulator(node);
553 }
554 
555 
VisitLdaSmi8(const interpreter::BytecodeArrayIterator & iterator)556 void BytecodeGraphBuilder::VisitLdaSmi8(
557     const interpreter::BytecodeArrayIterator& iterator) {
558   Node* node = jsgraph()->Constant(iterator.GetImmediateOperand(0));
559   environment()->BindAccumulator(node);
560 }
561 
562 
VisitLdaConstantWide(const interpreter::BytecodeArrayIterator & iterator)563 void BytecodeGraphBuilder::VisitLdaConstantWide(
564     const interpreter::BytecodeArrayIterator& iterator) {
565   Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
566   environment()->BindAccumulator(node);
567 }
568 
569 
VisitLdaConstant(const interpreter::BytecodeArrayIterator & iterator)570 void BytecodeGraphBuilder::VisitLdaConstant(
571     const interpreter::BytecodeArrayIterator& iterator) {
572   Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
573   environment()->BindAccumulator(node);
574 }
575 
576 
VisitLdaUndefined(const interpreter::BytecodeArrayIterator & iterator)577 void BytecodeGraphBuilder::VisitLdaUndefined(
578     const interpreter::BytecodeArrayIterator& iterator) {
579   Node* node = jsgraph()->UndefinedConstant();
580   environment()->BindAccumulator(node);
581 }
582 
583 
VisitLdaNull(const interpreter::BytecodeArrayIterator & iterator)584 void BytecodeGraphBuilder::VisitLdaNull(
585     const interpreter::BytecodeArrayIterator& iterator) {
586   Node* node = jsgraph()->NullConstant();
587   environment()->BindAccumulator(node);
588 }
589 
590 
VisitLdaTheHole(const interpreter::BytecodeArrayIterator & iterator)591 void BytecodeGraphBuilder::VisitLdaTheHole(
592     const interpreter::BytecodeArrayIterator& iterator) {
593   Node* node = jsgraph()->TheHoleConstant();
594   environment()->BindAccumulator(node);
595 }
596 
597 
VisitLdaTrue(const interpreter::BytecodeArrayIterator & iterator)598 void BytecodeGraphBuilder::VisitLdaTrue(
599     const interpreter::BytecodeArrayIterator& iterator) {
600   Node* node = jsgraph()->TrueConstant();
601   environment()->BindAccumulator(node);
602 }
603 
604 
VisitLdaFalse(const interpreter::BytecodeArrayIterator & iterator)605 void BytecodeGraphBuilder::VisitLdaFalse(
606     const interpreter::BytecodeArrayIterator& iterator) {
607   Node* node = jsgraph()->FalseConstant();
608   environment()->BindAccumulator(node);
609 }
610 
611 
VisitLdar(const interpreter::BytecodeArrayIterator & iterator)612 void BytecodeGraphBuilder::VisitLdar(
613     const interpreter::BytecodeArrayIterator& iterator) {
614   Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
615   environment()->BindAccumulator(value);
616 }
617 
618 
VisitStar(const interpreter::BytecodeArrayIterator & iterator)619 void BytecodeGraphBuilder::VisitStar(
620     const interpreter::BytecodeArrayIterator& iterator) {
621   Node* value = environment()->LookupAccumulator();
622   environment()->BindRegister(iterator.GetRegisterOperand(0), value);
623 }
624 
625 
VisitMov(const interpreter::BytecodeArrayIterator & iterator)626 void 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 
VisitExchange(const interpreter::BytecodeArrayIterator & iterator)633 void BytecodeGraphBuilder::VisitExchange(
634     const interpreter::BytecodeArrayIterator& iterator) {
635   environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
636                                    iterator.GetRegisterOperand(1));
637 }
638 
639 
VisitExchangeWide(const interpreter::BytecodeArrayIterator & iterator)640 void BytecodeGraphBuilder::VisitExchangeWide(
641     const interpreter::BytecodeArrayIterator& iterator) {
642   environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
643                                    iterator.GetRegisterOperand(1));
644 }
645 
646 
BuildLoadGlobal(const interpreter::BytecodeArrayIterator & iterator,TypeofMode typeof_mode)647 void 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 
VisitLdaGlobalSloppy(const interpreter::BytecodeArrayIterator & iterator)661 void BytecodeGraphBuilder::VisitLdaGlobalSloppy(
662     const interpreter::BytecodeArrayIterator& iterator) {
663   DCHECK(is_sloppy(language_mode()));
664   BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
665 }
666 
667 
VisitLdaGlobalStrict(const interpreter::BytecodeArrayIterator & iterator)668 void BytecodeGraphBuilder::VisitLdaGlobalStrict(
669     const interpreter::BytecodeArrayIterator& iterator) {
670   DCHECK(is_strict(language_mode()));
671   BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
672 }
673 
674 
VisitLdaGlobalInsideTypeofSloppy(const interpreter::BytecodeArrayIterator & iterator)675 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppy(
676     const interpreter::BytecodeArrayIterator& iterator) {
677   DCHECK(is_sloppy(language_mode()));
678   BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
679 }
680 
681 
VisitLdaGlobalInsideTypeofStrict(const interpreter::BytecodeArrayIterator & iterator)682 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrict(
683     const interpreter::BytecodeArrayIterator& iterator) {
684   DCHECK(is_strict(language_mode()));
685   BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
686 }
687 
688 
VisitLdaGlobalSloppyWide(const interpreter::BytecodeArrayIterator & iterator)689 void BytecodeGraphBuilder::VisitLdaGlobalSloppyWide(
690     const interpreter::BytecodeArrayIterator& iterator) {
691   DCHECK(is_sloppy(language_mode()));
692   BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
693 }
694 
695 
VisitLdaGlobalStrictWide(const interpreter::BytecodeArrayIterator & iterator)696 void BytecodeGraphBuilder::VisitLdaGlobalStrictWide(
697     const interpreter::BytecodeArrayIterator& iterator) {
698   DCHECK(is_strict(language_mode()));
699   BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
700 }
701 
702 
VisitLdaGlobalInsideTypeofSloppyWide(const interpreter::BytecodeArrayIterator & iterator)703 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppyWide(
704     const interpreter::BytecodeArrayIterator& iterator) {
705   DCHECK(is_sloppy(language_mode()));
706   BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
707 }
708 
709 
VisitLdaGlobalInsideTypeofStrictWide(const interpreter::BytecodeArrayIterator & iterator)710 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide(
711     const interpreter::BytecodeArrayIterator& iterator) {
712   DCHECK(is_strict(language_mode()));
713   BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
714 }
715 
716 
BuildStoreGlobal(const interpreter::BytecodeArrayIterator & iterator)717 void 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 
VisitStaGlobalSloppy(const interpreter::BytecodeArrayIterator & iterator)732 void BytecodeGraphBuilder::VisitStaGlobalSloppy(
733     const interpreter::BytecodeArrayIterator& iterator) {
734   DCHECK(is_sloppy(language_mode()));
735   BuildStoreGlobal(iterator);
736 }
737 
738 
VisitStaGlobalStrict(const interpreter::BytecodeArrayIterator & iterator)739 void BytecodeGraphBuilder::VisitStaGlobalStrict(
740     const interpreter::BytecodeArrayIterator& iterator) {
741   DCHECK(is_strict(language_mode()));
742   BuildStoreGlobal(iterator);
743 }
744 
VisitStaGlobalSloppyWide(const interpreter::BytecodeArrayIterator & iterator)745 void BytecodeGraphBuilder::VisitStaGlobalSloppyWide(
746     const interpreter::BytecodeArrayIterator& iterator) {
747   DCHECK(is_sloppy(language_mode()));
748   BuildStoreGlobal(iterator);
749 }
750 
751 
VisitStaGlobalStrictWide(const interpreter::BytecodeArrayIterator & iterator)752 void BytecodeGraphBuilder::VisitStaGlobalStrictWide(
753     const interpreter::BytecodeArrayIterator& iterator) {
754   DCHECK(is_strict(language_mode()));
755   BuildStoreGlobal(iterator);
756 }
757 
758 
VisitLdaContextSlot(const interpreter::BytecodeArrayIterator & iterator)759 void 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 
VisitLdaContextSlotWide(const interpreter::BytecodeArrayIterator & iterator)775 void BytecodeGraphBuilder::VisitLdaContextSlotWide(
776     const interpreter::BytecodeArrayIterator& iterator) {
777   VisitLdaContextSlot(iterator);
778 }
779 
780 
VisitStaContextSlot(const interpreter::BytecodeArrayIterator & iterator)781 void 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 
VisitStaContextSlotWide(const interpreter::BytecodeArrayIterator & iterator)794 void BytecodeGraphBuilder::VisitStaContextSlotWide(
795     const interpreter::BytecodeArrayIterator& iterator) {
796   VisitStaContextSlot(iterator);
797 }
798 
799 
BuildLdaLookupSlot(TypeofMode typeof_mode,const interpreter::BytecodeArrayIterator & iterator)800 void 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 
VisitLdaLookupSlot(const interpreter::BytecodeArrayIterator & iterator)813 void BytecodeGraphBuilder::VisitLdaLookupSlot(
814     const interpreter::BytecodeArrayIterator& iterator) {
815   BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF, iterator);
816 }
817 
818 
VisitLdaLookupSlotInsideTypeof(const interpreter::BytecodeArrayIterator & iterator)819 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof(
820     const interpreter::BytecodeArrayIterator& iterator) {
821   BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF, iterator);
822 }
823 
824 
BuildStaLookupSlot(LanguageMode language_mode,const interpreter::BytecodeArrayIterator & iterator)825 void 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 
VisitLdaLookupSlotWide(const interpreter::BytecodeArrayIterator & iterator)838 void BytecodeGraphBuilder::VisitLdaLookupSlotWide(
839     const interpreter::BytecodeArrayIterator& iterator) {
840   VisitLdaLookupSlot(iterator);
841 }
842 
843 
VisitLdaLookupSlotInsideTypeofWide(const interpreter::BytecodeArrayIterator & iterator)844 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeofWide(
845     const interpreter::BytecodeArrayIterator& iterator) {
846   VisitLdaLookupSlotInsideTypeof(iterator);
847 }
848 
849 
VisitStaLookupSlotSloppy(const interpreter::BytecodeArrayIterator & iterator)850 void BytecodeGraphBuilder::VisitStaLookupSlotSloppy(
851     const interpreter::BytecodeArrayIterator& iterator) {
852   BuildStaLookupSlot(LanguageMode::SLOPPY, iterator);
853 }
854 
855 
VisitStaLookupSlotStrict(const interpreter::BytecodeArrayIterator & iterator)856 void BytecodeGraphBuilder::VisitStaLookupSlotStrict(
857     const interpreter::BytecodeArrayIterator& iterator) {
858   BuildStaLookupSlot(LanguageMode::STRICT, iterator);
859 }
860 
861 
VisitStaLookupSlotSloppyWide(const interpreter::BytecodeArrayIterator & iterator)862 void BytecodeGraphBuilder::VisitStaLookupSlotSloppyWide(
863     const interpreter::BytecodeArrayIterator& iterator) {
864   VisitStaLookupSlotSloppy(iterator);
865 }
866 
867 
VisitStaLookupSlotStrictWide(const interpreter::BytecodeArrayIterator & iterator)868 void BytecodeGraphBuilder::VisitStaLookupSlotStrictWide(
869     const interpreter::BytecodeArrayIterator& iterator) {
870   VisitStaLookupSlotStrict(iterator);
871 }
872 
873 
BuildNamedLoad(const interpreter::BytecodeArrayIterator & iterator)874 void 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 
VisitLoadICSloppy(const interpreter::BytecodeArrayIterator & iterator)888 void BytecodeGraphBuilder::VisitLoadICSloppy(
889     const interpreter::BytecodeArrayIterator& iterator) {
890   DCHECK(is_sloppy(language_mode()));
891   BuildNamedLoad(iterator);
892 }
893 
894 
VisitLoadICStrict(const interpreter::BytecodeArrayIterator & iterator)895 void BytecodeGraphBuilder::VisitLoadICStrict(
896     const interpreter::BytecodeArrayIterator& iterator) {
897   DCHECK(is_strict(language_mode()));
898   BuildNamedLoad(iterator);
899 }
900 
901 
VisitLoadICSloppyWide(const interpreter::BytecodeArrayIterator & iterator)902 void BytecodeGraphBuilder::VisitLoadICSloppyWide(
903     const interpreter::BytecodeArrayIterator& iterator) {
904   DCHECK(is_sloppy(language_mode()));
905   BuildNamedLoad(iterator);
906 }
907 
908 
VisitLoadICStrictWide(const interpreter::BytecodeArrayIterator & iterator)909 void BytecodeGraphBuilder::VisitLoadICStrictWide(
910     const interpreter::BytecodeArrayIterator& iterator) {
911   DCHECK(is_strict(language_mode()));
912   BuildNamedLoad(iterator);
913 }
914 
915 
BuildKeyedLoad(const interpreter::BytecodeArrayIterator & iterator)916 void 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 
VisitKeyedLoadICSloppy(const interpreter::BytecodeArrayIterator & iterator)929 void BytecodeGraphBuilder::VisitKeyedLoadICSloppy(
930     const interpreter::BytecodeArrayIterator& iterator) {
931   DCHECK(is_sloppy(language_mode()));
932   BuildKeyedLoad(iterator);
933 }
934 
935 
VisitKeyedLoadICStrict(const interpreter::BytecodeArrayIterator & iterator)936 void BytecodeGraphBuilder::VisitKeyedLoadICStrict(
937     const interpreter::BytecodeArrayIterator& iterator) {
938   DCHECK(is_strict(language_mode()));
939   BuildKeyedLoad(iterator);
940 }
941 
942 
VisitKeyedLoadICSloppyWide(const interpreter::BytecodeArrayIterator & iterator)943 void BytecodeGraphBuilder::VisitKeyedLoadICSloppyWide(
944     const interpreter::BytecodeArrayIterator& iterator) {
945   DCHECK(is_sloppy(language_mode()));
946   BuildKeyedLoad(iterator);
947 }
948 
949 
VisitKeyedLoadICStrictWide(const interpreter::BytecodeArrayIterator & iterator)950 void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide(
951     const interpreter::BytecodeArrayIterator& iterator) {
952   DCHECK(is_strict(language_mode()));
953   BuildKeyedLoad(iterator);
954 }
955 
956 
BuildNamedStore(const interpreter::BytecodeArrayIterator & iterator)957 void 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 
VisitStoreICSloppy(const interpreter::BytecodeArrayIterator & iterator)973 void BytecodeGraphBuilder::VisitStoreICSloppy(
974     const interpreter::BytecodeArrayIterator& iterator) {
975   DCHECK(is_sloppy(language_mode()));
976   BuildNamedStore(iterator);
977 }
978 
979 
VisitStoreICStrict(const interpreter::BytecodeArrayIterator & iterator)980 void BytecodeGraphBuilder::VisitStoreICStrict(
981     const interpreter::BytecodeArrayIterator& iterator) {
982   DCHECK(is_strict(language_mode()));
983   BuildNamedStore(iterator);
984 }
985 
986 
VisitStoreICSloppyWide(const interpreter::BytecodeArrayIterator & iterator)987 void BytecodeGraphBuilder::VisitStoreICSloppyWide(
988     const interpreter::BytecodeArrayIterator& iterator) {
989   DCHECK(is_sloppy(language_mode()));
990   BuildNamedStore(iterator);
991 }
992 
993 
VisitStoreICStrictWide(const interpreter::BytecodeArrayIterator & iterator)994 void BytecodeGraphBuilder::VisitStoreICStrictWide(
995     const interpreter::BytecodeArrayIterator& iterator) {
996   DCHECK(is_strict(language_mode()));
997   BuildNamedStore(iterator);
998 }
999 
1000 
BuildKeyedStore(const interpreter::BytecodeArrayIterator & iterator)1001 void 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 
VisitKeyedStoreICSloppy(const interpreter::BytecodeArrayIterator & iterator)1015 void BytecodeGraphBuilder::VisitKeyedStoreICSloppy(
1016     const interpreter::BytecodeArrayIterator& iterator) {
1017   DCHECK(is_sloppy(language_mode()));
1018   BuildKeyedStore(iterator);
1019 }
1020 
1021 
VisitKeyedStoreICStrict(const interpreter::BytecodeArrayIterator & iterator)1022 void BytecodeGraphBuilder::VisitKeyedStoreICStrict(
1023     const interpreter::BytecodeArrayIterator& iterator) {
1024   DCHECK(is_strict(language_mode()));
1025   BuildKeyedStore(iterator);
1026 }
1027 
1028 
VisitKeyedStoreICSloppyWide(const interpreter::BytecodeArrayIterator & iterator)1029 void BytecodeGraphBuilder::VisitKeyedStoreICSloppyWide(
1030     const interpreter::BytecodeArrayIterator& iterator) {
1031   DCHECK(is_sloppy(language_mode()));
1032   BuildKeyedStore(iterator);
1033 }
1034 
1035 
VisitKeyedStoreICStrictWide(const interpreter::BytecodeArrayIterator & iterator)1036 void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide(
1037     const interpreter::BytecodeArrayIterator& iterator) {
1038   DCHECK(is_strict(language_mode()));
1039   BuildKeyedStore(iterator);
1040 }
1041 
1042 
VisitPushContext(const interpreter::BytecodeArrayIterator & iterator)1043 void 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 
VisitPopContext(const interpreter::BytecodeArrayIterator & iterator)1051 void BytecodeGraphBuilder::VisitPopContext(
1052     const interpreter::BytecodeArrayIterator& iterator) {
1053   Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
1054   environment()->SetContext(context);
1055 }
1056 
1057 
VisitCreateClosure(const interpreter::BytecodeArrayIterator & iterator)1058 void 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 
VisitCreateClosureWide(const interpreter::BytecodeArrayIterator & iterator)1070 void BytecodeGraphBuilder::VisitCreateClosureWide(
1071     const interpreter::BytecodeArrayIterator& iterator) {
1072   VisitCreateClosure(iterator);
1073 }
1074 
1075 
BuildCreateArguments(CreateArgumentsParameters::Type type,const interpreter::BytecodeArrayIterator & iterator)1076 void 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 
VisitCreateMappedArguments(const interpreter::BytecodeArrayIterator & iterator)1086 void BytecodeGraphBuilder::VisitCreateMappedArguments(
1087     const interpreter::BytecodeArrayIterator& iterator) {
1088   BuildCreateArguments(CreateArgumentsParameters::kMappedArguments, iterator);
1089 }
1090 
1091 
VisitCreateUnmappedArguments(const interpreter::BytecodeArrayIterator & iterator)1092 void BytecodeGraphBuilder::VisitCreateUnmappedArguments(
1093     const interpreter::BytecodeArrayIterator& iterator) {
1094   BuildCreateArguments(CreateArgumentsParameters::kUnmappedArguments, iterator);
1095 }
1096 
1097 
BuildCreateLiteral(const Operator * op,const interpreter::BytecodeArrayIterator & iterator)1098 void 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 
BuildCreateRegExpLiteral(const interpreter::BytecodeArrayIterator & iterator)1106 void 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 
VisitCreateRegExpLiteral(const interpreter::BytecodeArrayIterator & iterator)1118 void BytecodeGraphBuilder::VisitCreateRegExpLiteral(
1119     const interpreter::BytecodeArrayIterator& iterator) {
1120   BuildCreateRegExpLiteral(iterator);
1121 }
1122 
1123 
VisitCreateRegExpLiteralWide(const interpreter::BytecodeArrayIterator & iterator)1124 void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide(
1125     const interpreter::BytecodeArrayIterator& iterator) {
1126   BuildCreateRegExpLiteral(iterator);
1127 }
1128 
1129 
BuildCreateArrayLiteral(const interpreter::BytecodeArrayIterator & iterator)1130 void 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 
VisitCreateArrayLiteral(const interpreter::BytecodeArrayIterator & iterator)1142 void BytecodeGraphBuilder::VisitCreateArrayLiteral(
1143     const interpreter::BytecodeArrayIterator& iterator) {
1144   BuildCreateArrayLiteral(iterator);
1145 }
1146 
1147 
VisitCreateArrayLiteralWide(const interpreter::BytecodeArrayIterator & iterator)1148 void BytecodeGraphBuilder::VisitCreateArrayLiteralWide(
1149     const interpreter::BytecodeArrayIterator& iterator) {
1150   BuildCreateArrayLiteral(iterator);
1151 }
1152 
1153 
BuildCreateObjectLiteral(const interpreter::BytecodeArrayIterator & iterator)1154 void 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 
VisitCreateObjectLiteral(const interpreter::BytecodeArrayIterator & iterator)1166 void BytecodeGraphBuilder::VisitCreateObjectLiteral(
1167     const interpreter::BytecodeArrayIterator& iterator) {
1168   BuildCreateObjectLiteral(iterator);
1169 }
1170 
1171 
VisitCreateObjectLiteralWide(const interpreter::BytecodeArrayIterator & iterator)1172 void BytecodeGraphBuilder::VisitCreateObjectLiteralWide(
1173     const interpreter::BytecodeArrayIterator& iterator) {
1174   BuildCreateObjectLiteral(iterator);
1175 }
1176 
1177 
ProcessCallArguments(const Operator * call_op,Node * callee,interpreter::Register receiver,size_t arity)1178 Node* 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 
BuildCall(const interpreter::BytecodeArrayIterator & iterator)1195 void 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 
VisitCall(const interpreter::BytecodeArrayIterator & iterator)1214 void BytecodeGraphBuilder::VisitCall(
1215     const interpreter::BytecodeArrayIterator& iterator) {
1216   BuildCall(iterator);
1217 }
1218 
1219 
VisitCallWide(const interpreter::BytecodeArrayIterator & iterator)1220 void BytecodeGraphBuilder::VisitCallWide(
1221     const interpreter::BytecodeArrayIterator& iterator) {
1222   BuildCall(iterator);
1223 }
1224 
1225 
VisitCallJSRuntime(const interpreter::BytecodeArrayIterator & iterator)1226 void 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 
ProcessCallRuntimeArguments(const Operator * call_runtime_op,interpreter::Register first_arg,size_t arity)1241 Node* 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 
VisitCallRuntime(const interpreter::BytecodeArrayIterator & iterator)1255 void 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 
VisitCallRuntimeForPair(const interpreter::BytecodeArrayIterator & iterator)1270 void 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 
ProcessCallNewArguments(const Operator * call_new_op,interpreter::Register callee,interpreter::Register first_arg,size_t arity)1286 Node* 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 
VisitNew(const interpreter::BytecodeArrayIterator & iterator)1303 void 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 
VisitThrow(const interpreter::BytecodeArrayIterator & iterator)1318 void 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 
BuildBinaryOp(const Operator * js_op,const interpreter::BytecodeArrayIterator & iterator)1331 void 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 
VisitAdd(const interpreter::BytecodeArrayIterator & iterator)1341 void BytecodeGraphBuilder::VisitAdd(
1342     const interpreter::BytecodeArrayIterator& iterator) {
1343   BinaryOperationHints hints = BinaryOperationHints::Any();
1344   BuildBinaryOp(javascript()->Add(language_mode(), hints), iterator);
1345 }
1346 
1347 
VisitSub(const interpreter::BytecodeArrayIterator & iterator)1348 void BytecodeGraphBuilder::VisitSub(
1349     const interpreter::BytecodeArrayIterator& iterator) {
1350   BinaryOperationHints hints = BinaryOperationHints::Any();
1351   BuildBinaryOp(javascript()->Subtract(language_mode(), hints), iterator);
1352 }
1353 
1354 
VisitMul(const interpreter::BytecodeArrayIterator & iterator)1355 void BytecodeGraphBuilder::VisitMul(
1356     const interpreter::BytecodeArrayIterator& iterator) {
1357   BinaryOperationHints hints = BinaryOperationHints::Any();
1358   BuildBinaryOp(javascript()->Multiply(language_mode(), hints), iterator);
1359 }
1360 
1361 
VisitDiv(const interpreter::BytecodeArrayIterator & iterator)1362 void BytecodeGraphBuilder::VisitDiv(
1363     const interpreter::BytecodeArrayIterator& iterator) {
1364   BinaryOperationHints hints = BinaryOperationHints::Any();
1365   BuildBinaryOp(javascript()->Divide(language_mode(), hints), iterator);
1366 }
1367 
1368 
VisitMod(const interpreter::BytecodeArrayIterator & iterator)1369 void BytecodeGraphBuilder::VisitMod(
1370     const interpreter::BytecodeArrayIterator& iterator) {
1371   BinaryOperationHints hints = BinaryOperationHints::Any();
1372   BuildBinaryOp(javascript()->Modulus(language_mode(), hints), iterator);
1373 }
1374 
1375 
VisitBitwiseOr(const interpreter::BytecodeArrayIterator & iterator)1376 void BytecodeGraphBuilder::VisitBitwiseOr(
1377     const interpreter::BytecodeArrayIterator& iterator) {
1378   BinaryOperationHints hints = BinaryOperationHints::Any();
1379   BuildBinaryOp(javascript()->BitwiseOr(language_mode(), hints), iterator);
1380 }
1381 
1382 
VisitBitwiseXor(const interpreter::BytecodeArrayIterator & iterator)1383 void BytecodeGraphBuilder::VisitBitwiseXor(
1384     const interpreter::BytecodeArrayIterator& iterator) {
1385   BinaryOperationHints hints = BinaryOperationHints::Any();
1386   BuildBinaryOp(javascript()->BitwiseXor(language_mode(), hints), iterator);
1387 }
1388 
1389 
VisitBitwiseAnd(const interpreter::BytecodeArrayIterator & iterator)1390 void BytecodeGraphBuilder::VisitBitwiseAnd(
1391     const interpreter::BytecodeArrayIterator& iterator) {
1392   BinaryOperationHints hints = BinaryOperationHints::Any();
1393   BuildBinaryOp(javascript()->BitwiseAnd(language_mode(), hints), iterator);
1394 }
1395 
1396 
VisitShiftLeft(const interpreter::BytecodeArrayIterator & iterator)1397 void BytecodeGraphBuilder::VisitShiftLeft(
1398     const interpreter::BytecodeArrayIterator& iterator) {
1399   BinaryOperationHints hints = BinaryOperationHints::Any();
1400   BuildBinaryOp(javascript()->ShiftLeft(language_mode(), hints), iterator);
1401 }
1402 
1403 
VisitShiftRight(const interpreter::BytecodeArrayIterator & iterator)1404 void BytecodeGraphBuilder::VisitShiftRight(
1405     const interpreter::BytecodeArrayIterator& iterator) {
1406   BinaryOperationHints hints = BinaryOperationHints::Any();
1407   BuildBinaryOp(javascript()->ShiftRight(language_mode(), hints), iterator);
1408 }
1409 
1410 
VisitShiftRightLogical(const interpreter::BytecodeArrayIterator & iterator)1411 void BytecodeGraphBuilder::VisitShiftRightLogical(
1412     const interpreter::BytecodeArrayIterator& iterator) {
1413   BinaryOperationHints hints = BinaryOperationHints::Any();
1414   BuildBinaryOp(javascript()->ShiftRightLogical(language_mode(), hints),
1415                 iterator);
1416 }
1417 
1418 
VisitInc(const interpreter::BytecodeArrayIterator & iterator)1419 void 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 
VisitDec(const interpreter::BytecodeArrayIterator & iterator)1430 void 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 
VisitLogicalNot(const interpreter::BytecodeArrayIterator & iterator)1441 void 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 
VisitTypeOf(const interpreter::BytecodeArrayIterator & iterator)1451 void BytecodeGraphBuilder::VisitTypeOf(
1452     const interpreter::BytecodeArrayIterator& iterator) {
1453   Node* node =
1454       NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
1455   environment()->BindAccumulator(node);
1456 }
1457 
1458 
BuildDelete(const interpreter::BytecodeArrayIterator & iterator)1459 void 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 
VisitDeletePropertyStrict(const interpreter::BytecodeArrayIterator & iterator)1470 void BytecodeGraphBuilder::VisitDeletePropertyStrict(
1471     const interpreter::BytecodeArrayIterator& iterator) {
1472   DCHECK(is_strict(language_mode()));
1473   BuildDelete(iterator);
1474 }
1475 
1476 
VisitDeletePropertySloppy(const interpreter::BytecodeArrayIterator & iterator)1477 void BytecodeGraphBuilder::VisitDeletePropertySloppy(
1478     const interpreter::BytecodeArrayIterator& iterator) {
1479   DCHECK(is_sloppy(language_mode()));
1480   BuildDelete(iterator);
1481 }
1482 
1483 
VisitDeleteLookupSlot(const interpreter::BytecodeArrayIterator & iterator)1484 void 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 
BuildCompareOp(const Operator * js_op,const interpreter::BytecodeArrayIterator & iterator)1494 void 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 
VisitTestEqual(const interpreter::BytecodeArrayIterator & iterator)1504 void BytecodeGraphBuilder::VisitTestEqual(
1505     const interpreter::BytecodeArrayIterator& iterator) {
1506   BuildCompareOp(javascript()->Equal(), iterator);
1507 }
1508 
1509 
VisitTestNotEqual(const interpreter::BytecodeArrayIterator & iterator)1510 void BytecodeGraphBuilder::VisitTestNotEqual(
1511     const interpreter::BytecodeArrayIterator& iterator) {
1512   BuildCompareOp(javascript()->NotEqual(), iterator);
1513 }
1514 
1515 
VisitTestEqualStrict(const interpreter::BytecodeArrayIterator & iterator)1516 void BytecodeGraphBuilder::VisitTestEqualStrict(
1517     const interpreter::BytecodeArrayIterator& iterator) {
1518   BuildCompareOp(javascript()->StrictEqual(), iterator);
1519 }
1520 
1521 
VisitTestNotEqualStrict(const interpreter::BytecodeArrayIterator & iterator)1522 void BytecodeGraphBuilder::VisitTestNotEqualStrict(
1523     const interpreter::BytecodeArrayIterator& iterator) {
1524   BuildCompareOp(javascript()->StrictNotEqual(), iterator);
1525 }
1526 
1527 
VisitTestLessThan(const interpreter::BytecodeArrayIterator & iterator)1528 void BytecodeGraphBuilder::VisitTestLessThan(
1529     const interpreter::BytecodeArrayIterator& iterator) {
1530   BuildCompareOp(javascript()->LessThan(language_mode()), iterator);
1531 }
1532 
1533 
VisitTestGreaterThan(const interpreter::BytecodeArrayIterator & iterator)1534 void BytecodeGraphBuilder::VisitTestGreaterThan(
1535     const interpreter::BytecodeArrayIterator& iterator) {
1536   BuildCompareOp(javascript()->GreaterThan(language_mode()), iterator);
1537 }
1538 
1539 
VisitTestLessThanOrEqual(const interpreter::BytecodeArrayIterator & iterator)1540 void BytecodeGraphBuilder::VisitTestLessThanOrEqual(
1541     const interpreter::BytecodeArrayIterator& iterator) {
1542   BuildCompareOp(javascript()->LessThanOrEqual(language_mode()), iterator);
1543 }
1544 
1545 
VisitTestGreaterThanOrEqual(const interpreter::BytecodeArrayIterator & iterator)1546 void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual(
1547     const interpreter::BytecodeArrayIterator& iterator) {
1548   BuildCompareOp(javascript()->GreaterThanOrEqual(language_mode()), iterator);
1549 }
1550 
1551 
VisitTestIn(const interpreter::BytecodeArrayIterator & iterator)1552 void BytecodeGraphBuilder::VisitTestIn(
1553     const interpreter::BytecodeArrayIterator& iterator) {
1554   BuildCompareOp(javascript()->HasProperty(), iterator);
1555 }
1556 
1557 
VisitTestInstanceOf(const interpreter::BytecodeArrayIterator & iterator)1558 void BytecodeGraphBuilder::VisitTestInstanceOf(
1559     const interpreter::BytecodeArrayIterator& iterator) {
1560   BuildCompareOp(javascript()->InstanceOf(), iterator);
1561 }
1562 
1563 
BuildCastOperator(const Operator * js_op,const interpreter::BytecodeArrayIterator & iterator)1564 void 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 
VisitToName(const interpreter::BytecodeArrayIterator & iterator)1572 void BytecodeGraphBuilder::VisitToName(
1573     const interpreter::BytecodeArrayIterator& iterator) {
1574   BuildCastOperator(javascript()->ToName(), iterator);
1575 }
1576 
1577 
VisitToObject(const interpreter::BytecodeArrayIterator & iterator)1578 void BytecodeGraphBuilder::VisitToObject(
1579     const interpreter::BytecodeArrayIterator& iterator) {
1580   BuildCastOperator(javascript()->ToObject(), iterator);
1581 }
1582 
1583 
VisitToNumber(const interpreter::BytecodeArrayIterator & iterator)1584 void BytecodeGraphBuilder::VisitToNumber(
1585     const interpreter::BytecodeArrayIterator& iterator) {
1586   BuildCastOperator(javascript()->ToNumber(), iterator);
1587 }
1588 
1589 
VisitJump(const interpreter::BytecodeArrayIterator & iterator)1590 void BytecodeGraphBuilder::VisitJump(
1591     const interpreter::BytecodeArrayIterator& iterator) {
1592   BuildJump();
1593 }
1594 
1595 
VisitJumpConstant(const interpreter::BytecodeArrayIterator & iterator)1596 void BytecodeGraphBuilder::VisitJumpConstant(
1597     const interpreter::BytecodeArrayIterator& iterator) {
1598   BuildJump();
1599 }
1600 
1601 
VisitJumpConstantWide(const interpreter::BytecodeArrayIterator & iterator)1602 void BytecodeGraphBuilder::VisitJumpConstantWide(
1603     const interpreter::BytecodeArrayIterator& iterator) {
1604   BuildJump();
1605 }
1606 
1607 
VisitJumpIfTrue(const interpreter::BytecodeArrayIterator & iterator)1608 void BytecodeGraphBuilder::VisitJumpIfTrue(
1609     const interpreter::BytecodeArrayIterator& iterator) {
1610   BuildJumpIfEqual(jsgraph()->TrueConstant());
1611 }
1612 
1613 
VisitJumpIfTrueConstant(const interpreter::BytecodeArrayIterator & iterator)1614 void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
1615     const interpreter::BytecodeArrayIterator& iterator) {
1616   BuildJumpIfEqual(jsgraph()->TrueConstant());
1617 }
1618 
1619 
VisitJumpIfTrueConstantWide(const interpreter::BytecodeArrayIterator & iterator)1620 void BytecodeGraphBuilder::VisitJumpIfTrueConstantWide(
1621     const interpreter::BytecodeArrayIterator& iterator) {
1622   BuildJumpIfEqual(jsgraph()->TrueConstant());
1623 }
1624 
1625 
VisitJumpIfFalse(const interpreter::BytecodeArrayIterator & iterator)1626 void BytecodeGraphBuilder::VisitJumpIfFalse(
1627     const interpreter::BytecodeArrayIterator& iterator) {
1628   BuildJumpIfEqual(jsgraph()->FalseConstant());
1629 }
1630 
1631 
VisitJumpIfFalseConstant(const interpreter::BytecodeArrayIterator & iterator)1632 void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
1633     const interpreter::BytecodeArrayIterator& iterator) {
1634   BuildJumpIfEqual(jsgraph()->FalseConstant());
1635 }
1636 
1637 
VisitJumpIfFalseConstantWide(const interpreter::BytecodeArrayIterator & iterator)1638 void BytecodeGraphBuilder::VisitJumpIfFalseConstantWide(
1639     const interpreter::BytecodeArrayIterator& iterator) {
1640   BuildJumpIfEqual(jsgraph()->FalseConstant());
1641 }
1642 
1643 
VisitJumpIfToBooleanTrue(const interpreter::BytecodeArrayIterator & iterator)1644 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
1645     const interpreter::BytecodeArrayIterator& iterator) {
1646   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1647 }
1648 
1649 
VisitJumpIfToBooleanTrueConstant(const interpreter::BytecodeArrayIterator & iterator)1650 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
1651     const interpreter::BytecodeArrayIterator& iterator) {
1652   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1653 }
1654 
1655 
VisitJumpIfToBooleanTrueConstantWide(const interpreter::BytecodeArrayIterator & iterator)1656 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstantWide(
1657     const interpreter::BytecodeArrayIterator& iterator) {
1658   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1659 }
1660 
1661 
VisitJumpIfToBooleanFalse(const interpreter::BytecodeArrayIterator & iterator)1662 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
1663     const interpreter::BytecodeArrayIterator& iterator) {
1664   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1665 }
1666 
1667 
VisitJumpIfToBooleanFalseConstant(const interpreter::BytecodeArrayIterator & iterator)1668 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
1669     const interpreter::BytecodeArrayIterator& iterator) {
1670   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1671 }
1672 
1673 
VisitJumpIfToBooleanFalseConstantWide(const interpreter::BytecodeArrayIterator & iterator)1674 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstantWide(
1675     const interpreter::BytecodeArrayIterator& iterator) {
1676   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1677 }
1678 
1679 
VisitJumpIfNull(const interpreter::BytecodeArrayIterator & iterator)1680 void BytecodeGraphBuilder::VisitJumpIfNull(
1681     const interpreter::BytecodeArrayIterator& iterator) {
1682   BuildJumpIfEqual(jsgraph()->NullConstant());
1683 }
1684 
1685 
VisitJumpIfNullConstant(const interpreter::BytecodeArrayIterator & iterator)1686 void BytecodeGraphBuilder::VisitJumpIfNullConstant(
1687     const interpreter::BytecodeArrayIterator& iterator) {
1688   BuildJumpIfEqual(jsgraph()->NullConstant());
1689 }
1690 
1691 
VisitJumpIfNullConstantWide(const interpreter::BytecodeArrayIterator & iterator)1692 void BytecodeGraphBuilder::VisitJumpIfNullConstantWide(
1693     const interpreter::BytecodeArrayIterator& iterator) {
1694   BuildJumpIfEqual(jsgraph()->NullConstant());
1695 }
1696 
1697 
VisitJumpIfUndefined(const interpreter::BytecodeArrayIterator & iterator)1698 void BytecodeGraphBuilder::VisitJumpIfUndefined(
1699     const interpreter::BytecodeArrayIterator& iterator) {
1700   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1701 }
1702 
1703 
VisitJumpIfUndefinedConstant(const interpreter::BytecodeArrayIterator & iterator)1704 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
1705     const interpreter::BytecodeArrayIterator& iterator) {
1706   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1707 }
1708 
1709 
VisitJumpIfUndefinedConstantWide(const interpreter::BytecodeArrayIterator & iterator)1710 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide(
1711     const interpreter::BytecodeArrayIterator& iterator) {
1712   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1713 }
1714 
1715 
VisitReturn(const interpreter::BytecodeArrayIterator & iterator)1716 void 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 
VisitForInPrepare(const interpreter::BytecodeArrayIterator & iterator)1725 void 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 
VisitForInDone(const interpreter::BytecodeArrayIterator & iterator)1743 void 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 
VisitForInNext(const interpreter::BytecodeArrayIterator & iterator)1754 void 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 
VisitForInStep(const interpreter::BytecodeArrayIterator & iterator)1770 void 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 
MergeEnvironmentsOfBackwardBranches(int source_offset,int target_offset)1779 void 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 
MergeEnvironmentsOfForwardBranches(int source_offset)1799 void 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 
BuildLoopHeaderForBackwardBranches(int source_offset)1819 void 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 
BuildJump(int source_offset,int target_offset)1829 void 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 
BuildJump()1839 void 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 
BuildConditionalJump(Node * condition)1846 void 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 
BuildJumpIfEqual(Node * comperand)1857 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
1858   Node* accumulator = environment()->LookupAccumulator();
1859   Node* condition =
1860       NewNode(javascript()->StrictEqual(), accumulator, comperand);
1861   BuildConditionalJump(condition);
1862 }
1863 
1864 
BuildJumpIfToBooleanEqual(Node * comperand)1865 void 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 
EnsureInputBufferSize(int size)1874 Node** 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 
PrepareEntryFrameState(Node * node)1884 void 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 
MakeNode(const Operator * op,int value_input_count,Node ** value_inputs,bool incomplete)1894 Node* 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 
NewPhi(int count,Node * input,Node * control)1956 Node* 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 
NewEffectPhi(int count,Node * input,Node * control)1965 Node* 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 
MergeControl(Node * control,Node * other)1975 Node* 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 
MergeEffect(Node * value,Node * other,Node * control)1997 Node* 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 
MergeValue(Node * value,Node * other,Node * control)2014 Node* 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 
UpdateControlDependencyToLeaveFunction(Node * exit)2032 void 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