• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ast/ast.h"
8 #include "src/ast/scopes.h"
9 #include "src/compiler/access-builder.h"
10 #include "src/compiler/compiler-source-position-table.h"
11 #include "src/compiler/linkage.h"
12 #include "src/compiler/node-matchers.h"
13 #include "src/compiler/operator-properties.h"
14 #include "src/compiler/simplified-operator.h"
15 #include "src/interpreter/bytecodes.h"
16 #include "src/objects-inl.h"
17 #include "src/objects/js-array-inl.h"
18 #include "src/objects/js-generator.h"
19 #include "src/objects/literal-objects-inl.h"
20 #include "src/vector-slot-pair.h"
21 
22 namespace v8 {
23 namespace internal {
24 namespace compiler {
25 
26 // The abstract execution environment simulates the content of the interpreter
27 // register file. The environment performs SSA-renaming of all tracked nodes at
28 // split and merge points in the control flow.
29 class BytecodeGraphBuilder::Environment : public ZoneObject {
30  public:
31   Environment(BytecodeGraphBuilder* builder, int register_count,
32               int parameter_count,
33               interpreter::Register incoming_new_target_or_generator,
34               Node* control_dependency);
35 
36   // Specifies whether environment binding methods should attach frame state
37   // inputs to nodes representing the value being bound. This is done because
38   // the {OutputFrameStateCombine} is closely related to the binding method.
39   enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
40 
parameter_count() const41   int parameter_count() const { return parameter_count_; }
register_count() const42   int register_count() const { return register_count_; }
43 
44   Node* LookupAccumulator() const;
45   Node* LookupRegister(interpreter::Register the_register) const;
46   Node* LookupGeneratorState() const;
47 
48   void BindAccumulator(Node* node,
49                        FrameStateAttachmentMode mode = kDontAttachFrameState);
50   void BindRegister(interpreter::Register the_register, Node* node,
51                     FrameStateAttachmentMode mode = kDontAttachFrameState);
52   void BindRegistersToProjections(
53       interpreter::Register first_reg, Node* node,
54       FrameStateAttachmentMode mode = kDontAttachFrameState);
55   void BindGeneratorState(Node* node);
56   void RecordAfterState(Node* node,
57                         FrameStateAttachmentMode mode = kDontAttachFrameState);
58 
59   // Effect dependency tracked by this environment.
GetEffectDependency()60   Node* GetEffectDependency() { return effect_dependency_; }
UpdateEffectDependency(Node * dependency)61   void UpdateEffectDependency(Node* dependency) {
62     effect_dependency_ = dependency;
63   }
64 
65   // Preserve a checkpoint of the environment for the IR graph. Any
66   // further mutation of the environment will not affect checkpoints.
67   Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine,
68                    const BytecodeLivenessState* liveness);
69 
70   // Control dependency tracked by this environment.
GetControlDependency() const71   Node* GetControlDependency() const { return control_dependency_; }
UpdateControlDependency(Node * dependency)72   void UpdateControlDependency(Node* dependency) {
73     control_dependency_ = dependency;
74   }
75 
Context() const76   Node* Context() const { return context_; }
SetContext(Node * new_context)77   void SetContext(Node* new_context) { context_ = new_context; }
78 
79   Environment* Copy();
80   void Merge(Environment* other, const BytecodeLivenessState* liveness);
81 
82   void FillWithOsrValues();
83   void PrepareForLoop(const BytecodeLoopAssignments& assignments,
84                       const BytecodeLivenessState* liveness);
85   void PrepareForLoopExit(Node* loop,
86                           const BytecodeLoopAssignments& assignments,
87                           const BytecodeLivenessState* liveness);
88 
89  private:
90   explicit Environment(const Environment* copy);
91 
92   bool StateValuesRequireUpdate(Node** state_values, Node** values, int count);
93   void UpdateStateValues(Node** state_values, Node** values, int count);
94   Node* GetStateValuesFromCache(Node** values, int count,
95                                 const BitVector* liveness, int liveness_offset);
96 
97   int RegisterToValuesIndex(interpreter::Register the_register) const;
98 
zone() const99   Zone* zone() const { return builder_->local_zone(); }
graph() const100   Graph* graph() const { return builder_->graph(); }
common() const101   CommonOperatorBuilder* common() const { return builder_->common(); }
builder() const102   BytecodeGraphBuilder* builder() const { return builder_; }
values() const103   const NodeVector* values() const { return &values_; }
values()104   NodeVector* values() { return &values_; }
register_base() const105   int register_base() const { return register_base_; }
accumulator_base() const106   int accumulator_base() const { return accumulator_base_; }
107 
108   BytecodeGraphBuilder* builder_;
109   int register_count_;
110   int parameter_count_;
111   Node* context_;
112   Node* control_dependency_;
113   Node* effect_dependency_;
114   NodeVector values_;
115   Node* parameters_state_values_;
116   Node* generator_state_;
117   int register_base_;
118   int accumulator_base_;
119 };
120 
121 // A helper for creating a temporary sub-environment for simple branches.
122 struct BytecodeGraphBuilder::SubEnvironment final {
123  public:
SubEnvironmentv8::internal::compiler::BytecodeGraphBuilder::SubEnvironment124   explicit SubEnvironment(BytecodeGraphBuilder* builder)
125       : builder_(builder), parent_(builder->environment()->Copy()) {}
126 
~SubEnvironmentv8::internal::compiler::BytecodeGraphBuilder::SubEnvironment127   ~SubEnvironment() { builder_->set_environment(parent_); }
128 
129  private:
130   BytecodeGraphBuilder* builder_;
131   BytecodeGraphBuilder::Environment* parent_;
132 };
133 
134 // Issues:
135 // - Scopes - intimately tied to AST. Need to eval what is needed.
136 // - Need to resolve closure parameter treatment.
Environment(BytecodeGraphBuilder * builder,int register_count,int parameter_count,interpreter::Register incoming_new_target_or_generator,Node * control_dependency)137 BytecodeGraphBuilder::Environment::Environment(
138     BytecodeGraphBuilder* builder, int register_count, int parameter_count,
139     interpreter::Register incoming_new_target_or_generator,
140     Node* control_dependency)
141     : builder_(builder),
142       register_count_(register_count),
143       parameter_count_(parameter_count),
144       control_dependency_(control_dependency),
145       effect_dependency_(control_dependency),
146       values_(builder->local_zone()),
147       parameters_state_values_(nullptr),
148       generator_state_(nullptr) {
149   // The layout of values_ is:
150   //
151   // [receiver] [parameters] [registers] [accumulator]
152   //
153   // parameter[0] is the receiver (this), parameters 1..N are the
154   // parameters supplied to the method (arg0..argN-1). The accumulator
155   // is stored separately.
156 
157   // Parameters including the receiver
158   for (int i = 0; i < parameter_count; i++) {
159     const char* debug_name = (i == 0) ? "%this" : nullptr;
160     const Operator* op = common()->Parameter(i, debug_name);
161     Node* parameter = builder->graph()->NewNode(op, graph()->start());
162     values()->push_back(parameter);
163   }
164 
165   // Registers
166   register_base_ = static_cast<int>(values()->size());
167   Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
168   values()->insert(values()->end(), register_count, undefined_constant);
169 
170   // Accumulator
171   accumulator_base_ = static_cast<int>(values()->size());
172   values()->push_back(undefined_constant);
173 
174   // Context
175   int context_index = Linkage::GetJSCallContextParamIndex(parameter_count);
176   const Operator* op = common()->Parameter(context_index, "%context");
177   context_ = builder->graph()->NewNode(op, graph()->start());
178 
179   // Incoming new.target or generator register
180   if (incoming_new_target_or_generator.is_valid()) {
181     int new_target_index =
182         Linkage::GetJSCallNewTargetParamIndex(parameter_count);
183     const Operator* op = common()->Parameter(new_target_index, "%new.target");
184     Node* new_target_node = builder->graph()->NewNode(op, graph()->start());
185 
186     int values_index = RegisterToValuesIndex(incoming_new_target_or_generator);
187     values()->at(values_index) = new_target_node;
188   }
189 }
190 
Environment(const BytecodeGraphBuilder::Environment * other)191 BytecodeGraphBuilder::Environment::Environment(
192     const BytecodeGraphBuilder::Environment* other)
193     : builder_(other->builder_),
194       register_count_(other->register_count_),
195       parameter_count_(other->parameter_count_),
196       context_(other->context_),
197       control_dependency_(other->control_dependency_),
198       effect_dependency_(other->effect_dependency_),
199       values_(other->zone()),
200       parameters_state_values_(other->parameters_state_values_),
201       generator_state_(other->generator_state_),
202       register_base_(other->register_base_),
203       accumulator_base_(other->accumulator_base_) {
204   values_ = other->values_;
205 }
206 
207 
RegisterToValuesIndex(interpreter::Register the_register) const208 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
209     interpreter::Register the_register) const {
210   if (the_register.is_parameter()) {
211     return the_register.ToParameterIndex(parameter_count());
212   } else {
213     return the_register.index() + register_base();
214   }
215 }
216 
LookupAccumulator() const217 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
218   return values()->at(accumulator_base_);
219 }
220 
LookupGeneratorState() const221 Node* BytecodeGraphBuilder::Environment::LookupGeneratorState() const {
222   DCHECK_NOT_NULL(generator_state_);
223   return generator_state_;
224 }
225 
LookupRegister(interpreter::Register the_register) const226 Node* BytecodeGraphBuilder::Environment::LookupRegister(
227     interpreter::Register the_register) const {
228   if (the_register.is_current_context()) {
229     return Context();
230   } else if (the_register.is_function_closure()) {
231     return builder()->GetFunctionClosure();
232   } else {
233     int values_index = RegisterToValuesIndex(the_register);
234     return values()->at(values_index);
235   }
236 }
237 
BindAccumulator(Node * node,FrameStateAttachmentMode mode)238 void BytecodeGraphBuilder::Environment::BindAccumulator(
239     Node* node, FrameStateAttachmentMode mode) {
240   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
241     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
242   }
243   values()->at(accumulator_base_) = node;
244 }
245 
BindGeneratorState(Node * node)246 void BytecodeGraphBuilder::Environment::BindGeneratorState(Node* node) {
247   generator_state_ = node;
248 }
249 
BindRegister(interpreter::Register the_register,Node * node,FrameStateAttachmentMode mode)250 void BytecodeGraphBuilder::Environment::BindRegister(
251     interpreter::Register the_register, Node* node,
252     FrameStateAttachmentMode mode) {
253   int values_index = RegisterToValuesIndex(the_register);
254   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
255     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
256                                            accumulator_base_ - values_index));
257   }
258   values()->at(values_index) = node;
259 }
260 
BindRegistersToProjections(interpreter::Register first_reg,Node * node,FrameStateAttachmentMode mode)261 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
262     interpreter::Register first_reg, Node* node,
263     FrameStateAttachmentMode mode) {
264   int values_index = RegisterToValuesIndex(first_reg);
265   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
266     builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
267                                            accumulator_base_ - values_index));
268   }
269   for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
270     values()->at(values_index + i) =
271         builder()->NewNode(common()->Projection(i), node);
272   }
273 }
274 
RecordAfterState(Node * node,FrameStateAttachmentMode mode)275 void BytecodeGraphBuilder::Environment::RecordAfterState(
276     Node* node, FrameStateAttachmentMode mode) {
277   if (mode == FrameStateAttachmentMode::kAttachFrameState) {
278     builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
279   }
280 }
281 
Copy()282 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::Environment::Copy() {
283   return new (zone()) Environment(this);
284 }
285 
Merge(BytecodeGraphBuilder::Environment * other,const BytecodeLivenessState * liveness)286 void BytecodeGraphBuilder::Environment::Merge(
287     BytecodeGraphBuilder::Environment* other,
288     const BytecodeLivenessState* liveness) {
289   // Create a merge of the control dependencies of both environments and update
290   // the current environment's control dependency accordingly.
291   Node* control = builder()->MergeControl(GetControlDependency(),
292                                           other->GetControlDependency());
293   UpdateControlDependency(control);
294 
295   // Create a merge of the effect dependencies of both environments and update
296   // the current environment's effect dependency accordingly.
297   Node* effect = builder()->MergeEffect(GetEffectDependency(),
298                                         other->GetEffectDependency(), control);
299   UpdateEffectDependency(effect);
300 
301   // Introduce Phi nodes for values that are live and have differing inputs at
302   // the merge point, potentially extending an existing Phi node if possible.
303   context_ = builder()->MergeValue(context_, other->context_, control);
304   for (int i = 0; i < parameter_count(); i++) {
305     values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
306   }
307   for (int i = 0; i < register_count(); i++) {
308     int index = register_base() + i;
309     if (liveness == nullptr || liveness->RegisterIsLive(i)) {
310 #if DEBUG
311       // We only do these DCHECKs when we are not in the resume path of a
312       // generator -- this is, when either there is no generator state at all,
313       // or the generator state is not the constant "executing" value.
314       if (generator_state_ == nullptr ||
315           NumberMatcher(generator_state_)
316               .Is(JSGeneratorObject::kGeneratorExecuting)) {
317         DCHECK_NE(values_[index], builder()->jsgraph()->OptimizedOutConstant());
318         DCHECK_NE(other->values_[index],
319                   builder()->jsgraph()->OptimizedOutConstant());
320       }
321 #endif
322 
323       values_[index] =
324           builder()->MergeValue(values_[index], other->values_[index], control);
325 
326     } else {
327       values_[index] = builder()->jsgraph()->OptimizedOutConstant();
328     }
329   }
330 
331   if (liveness == nullptr || liveness->AccumulatorIsLive()) {
332     DCHECK_NE(values_[accumulator_base()],
333               builder()->jsgraph()->OptimizedOutConstant());
334     DCHECK_NE(other->values_[accumulator_base()],
335               builder()->jsgraph()->OptimizedOutConstant());
336 
337     values_[accumulator_base()] =
338         builder()->MergeValue(values_[accumulator_base()],
339                               other->values_[accumulator_base()], control);
340   } else {
341     values_[accumulator_base()] = builder()->jsgraph()->OptimizedOutConstant();
342   }
343 
344   if (generator_state_ != nullptr) {
345     DCHECK_NOT_NULL(other->generator_state_);
346     generator_state_ = builder()->MergeValue(generator_state_,
347                                              other->generator_state_, control);
348   }
349 }
350 
PrepareForLoop(const BytecodeLoopAssignments & assignments,const BytecodeLivenessState * liveness)351 void BytecodeGraphBuilder::Environment::PrepareForLoop(
352     const BytecodeLoopAssignments& assignments,
353     const BytecodeLivenessState* liveness) {
354   // Create a control node for the loop header.
355   Node* control = builder()->NewLoop();
356 
357   // Create a Phi for external effects.
358   Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
359   UpdateEffectDependency(effect);
360 
361   // Create Phis for any values that are live on entry to the loop and may be
362   // updated by the end of the loop.
363   context_ = builder()->NewPhi(1, context_, control);
364   for (int i = 0; i < parameter_count(); i++) {
365     if (assignments.ContainsParameter(i)) {
366       values_[i] = builder()->NewPhi(1, values_[i], control);
367     }
368   }
369   for (int i = 0; i < register_count(); i++) {
370     if (assignments.ContainsLocal(i) &&
371         (liveness == nullptr || liveness->RegisterIsLive(i))) {
372       int index = register_base() + i;
373       values_[index] = builder()->NewPhi(1, values_[index], control);
374     }
375   }
376   // The accumulator should not be live on entry.
377   DCHECK_IMPLIES(liveness != nullptr, !liveness->AccumulatorIsLive());
378 
379   if (generator_state_ != nullptr) {
380     generator_state_ = builder()->NewPhi(1, generator_state_, control);
381   }
382 
383   // Connect to the loop end.
384   Node* terminate = builder()->graph()->NewNode(
385       builder()->common()->Terminate(), effect, control);
386   builder()->exit_controls_.push_back(terminate);
387 }
388 
FillWithOsrValues()389 void BytecodeGraphBuilder::Environment::FillWithOsrValues() {
390   Node* start = graph()->start();
391 
392   // Create OSR values for each environment value.
393   SetContext(graph()->NewNode(
394       common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), start));
395   int size = static_cast<int>(values()->size());
396   for (int i = 0; i < size; i++) {
397     int idx = i;  // Indexing scheme follows {StandardFrame}, adapt accordingly.
398     if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
399     if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
400     values()->at(i) = graph()->NewNode(common()->OsrValue(idx), start);
401   }
402 }
403 
StateValuesRequireUpdate(Node ** state_values,Node ** values,int count)404 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
405     Node** state_values, Node** values, int count) {
406   if (*state_values == nullptr) {
407     return true;
408   }
409   Node::Inputs inputs = (*state_values)->inputs();
410   if (inputs.count() != count) return true;
411   for (int i = 0; i < count; i++) {
412     if (inputs[i] != values[i]) {
413       return true;
414     }
415   }
416   return false;
417 }
418 
PrepareForLoopExit(Node * loop,const BytecodeLoopAssignments & assignments,const BytecodeLivenessState * liveness)419 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(
420     Node* loop, const BytecodeLoopAssignments& assignments,
421     const BytecodeLivenessState* liveness) {
422   DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
423 
424   Node* control = GetControlDependency();
425 
426   // Create the loop exit node.
427   Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
428   UpdateControlDependency(loop_exit);
429 
430   // Rename the effect.
431   Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
432                                          GetEffectDependency(), loop_exit);
433   UpdateEffectDependency(effect_rename);
434 
435   // TODO(jarin) We should also rename context here. However, unconditional
436   // renaming confuses global object and native context specialization.
437   // We should only rename if the context is assigned in the loop.
438 
439   // Rename the environment values if they were assigned in the loop and are
440   // live after exiting the loop.
441   for (int i = 0; i < parameter_count(); i++) {
442     if (assignments.ContainsParameter(i)) {
443       Node* rename =
444           graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit);
445       values_[i] = rename;
446     }
447   }
448   for (int i = 0; i < register_count(); i++) {
449     if (assignments.ContainsLocal(i) &&
450         (liveness == nullptr || liveness->RegisterIsLive(i))) {
451       Node* rename = graph()->NewNode(common()->LoopExitValue(),
452                                       values_[register_base() + i], loop_exit);
453       values_[register_base() + i] = rename;
454     }
455   }
456   if (liveness == nullptr || liveness->AccumulatorIsLive()) {
457     Node* rename = graph()->NewNode(common()->LoopExitValue(),
458                                     values_[accumulator_base()], loop_exit);
459     values_[accumulator_base()] = rename;
460   }
461 
462   if (generator_state_ != nullptr) {
463     generator_state_ = graph()->NewNode(common()->LoopExitValue(),
464                                         generator_state_, loop_exit);
465   }
466 }
467 
UpdateStateValues(Node ** state_values,Node ** values,int count)468 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
469                                                           Node** values,
470                                                           int count) {
471   if (StateValuesRequireUpdate(state_values, values, count)) {
472     const Operator* op = common()->StateValues(count, SparseInputMask::Dense());
473     (*state_values) = graph()->NewNode(op, count, values);
474   }
475 }
476 
GetStateValuesFromCache(Node ** values,int count,const BitVector * liveness,int liveness_offset)477 Node* BytecodeGraphBuilder::Environment::GetStateValuesFromCache(
478     Node** values, int count, const BitVector* liveness, int liveness_offset) {
479   return builder_->state_values_cache_.GetNodeForValues(
480       values, static_cast<size_t>(count), liveness, liveness_offset);
481 }
482 
Checkpoint(BailoutId bailout_id,OutputFrameStateCombine combine,const BytecodeLivenessState * liveness)483 Node* BytecodeGraphBuilder::Environment::Checkpoint(
484     BailoutId bailout_id, OutputFrameStateCombine combine,
485     const BytecodeLivenessState* liveness) {
486   if (parameter_count() == register_count()) {
487     // Re-use the state-value cache if the number of local registers happens
488     // to match the parameter count.
489     parameters_state_values_ = GetStateValuesFromCache(
490         &values()->at(0), parameter_count(), nullptr, 0);
491   } else {
492     UpdateStateValues(&parameters_state_values_, &values()->at(0),
493                       parameter_count());
494   }
495 
496   Node* registers_state_values =
497       GetStateValuesFromCache(&values()->at(register_base()), register_count(),
498                               liveness ? &liveness->bit_vector() : nullptr, 0);
499 
500   bool accumulator_is_live = !liveness || liveness->AccumulatorIsLive();
501   Node* accumulator_state_value =
502       accumulator_is_live && combine != OutputFrameStateCombine::PokeAt(0)
503           ? values()->at(accumulator_base())
504           : builder()->jsgraph()->OptimizedOutConstant();
505 
506   const Operator* op = common()->FrameState(
507       bailout_id, combine, builder()->frame_state_function_info());
508   Node* result = graph()->NewNode(
509       op, parameters_state_values_, registers_state_values,
510       accumulator_state_value, Context(), builder()->GetFunctionClosure(),
511       builder()->graph()->start());
512 
513   return result;
514 }
515 
BytecodeGraphBuilder(Zone * local_zone,Handle<SharedFunctionInfo> shared_info,Handle<FeedbackVector> feedback_vector,BailoutId osr_offset,JSGraph * jsgraph,CallFrequency & invocation_frequency,SourcePositionTable * source_positions,Handle<Context> native_context,int inlining_id,JSTypeHintLowering::Flags flags,bool stack_check,bool analyze_environment_liveness)516 BytecodeGraphBuilder::BytecodeGraphBuilder(
517     Zone* local_zone, Handle<SharedFunctionInfo> shared_info,
518     Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
519     JSGraph* jsgraph, CallFrequency& invocation_frequency,
520     SourcePositionTable* source_positions, Handle<Context> native_context,
521     int inlining_id, JSTypeHintLowering::Flags flags, bool stack_check,
522     bool analyze_environment_liveness)
523     : local_zone_(local_zone),
524       jsgraph_(jsgraph),
525       invocation_frequency_(invocation_frequency),
526       bytecode_array_(
527           handle(shared_info->GetBytecodeArray(), jsgraph->isolate())),
528       feedback_vector_(feedback_vector),
529       type_hint_lowering_(jsgraph, feedback_vector, flags),
530       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
531           FrameStateType::kInterpretedFunction,
532           bytecode_array()->parameter_count(),
533           bytecode_array()->register_count(), shared_info)),
534       bytecode_iterator_(nullptr),
535       bytecode_analysis_(nullptr),
536       environment_(nullptr),
537       osr_offset_(osr_offset),
538       currently_peeled_loop_offset_(-1),
539       stack_check_(stack_check),
540       analyze_environment_liveness_(analyze_environment_liveness),
541       merge_environments_(local_zone),
542       generator_merge_environments_(local_zone),
543       exception_handlers_(local_zone),
544       current_exception_handler_(0),
545       input_buffer_size_(0),
546       input_buffer_(nullptr),
547       needs_eager_checkpoint_(true),
548       exit_controls_(local_zone),
549       state_values_cache_(jsgraph),
550       source_positions_(source_positions),
551       start_position_(shared_info->StartPosition(), inlining_id),
552       native_context_(native_context) {}
553 
GetFunctionClosure()554 Node* BytecodeGraphBuilder::GetFunctionClosure() {
555   if (!function_closure_.is_set()) {
556     int index = Linkage::kJSCallClosureParamIndex;
557     const Operator* op = common()->Parameter(index, "%closure");
558     Node* node = NewNode(op, graph()->start());
559     function_closure_.set(node);
560   }
561   return function_closure_.get();
562 }
563 
BuildLoadNativeContextField(int index)564 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
565   const Operator* op =
566       javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
567   Node* native_context = NewNode(op);
568   Node* result = NewNode(javascript()->LoadContext(0, index, true));
569   NodeProperties::ReplaceContextInput(result, native_context);
570   return result;
571 }
572 
CreateVectorSlotPair(int slot_id)573 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
574   return VectorSlotPair(feedback_vector(), FeedbackVector::ToSlot(slot_id));
575 }
576 
CreateGraph()577 void BytecodeGraphBuilder::CreateGraph() {
578   SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
579 
580   // Set up the basic structure of the graph. Outputs for {Start} are the formal
581   // parameters (including the receiver) plus new target, number of arguments,
582   // context and closure.
583   int actual_parameter_count = bytecode_array()->parameter_count() + 4;
584   graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
585 
586   Environment env(this, bytecode_array()->register_count(),
587                   bytecode_array()->parameter_count(),
588                   bytecode_array()->incoming_new_target_or_generator_register(),
589                   graph()->start());
590   set_environment(&env);
591 
592   VisitBytecodes();
593 
594   // Finish the basic structure of the graph.
595   DCHECK_NE(0u, exit_controls_.size());
596   int const input_count = static_cast<int>(exit_controls_.size());
597   Node** const inputs = &exit_controls_.front();
598   Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
599   graph()->SetEnd(end);
600 }
601 
PrepareEagerCheckpoint()602 void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
603   if (needs_eager_checkpoint()) {
604     // Create an explicit checkpoint node for before the operation. This only
605     // needs to happen if we aren't effect-dominated by a {Checkpoint} already.
606     mark_as_needing_eager_checkpoint(false);
607     Node* node = NewNode(common()->Checkpoint());
608     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
609     DCHECK_EQ(IrOpcode::kDead,
610               NodeProperties::GetFrameStateInput(node)->opcode());
611     BailoutId bailout_id(bytecode_iterator().current_offset());
612 
613     const BytecodeLivenessState* liveness_before =
614         bytecode_analysis()->GetInLivenessFor(
615             bytecode_iterator().current_offset());
616 
617     Node* frame_state_before = environment()->Checkpoint(
618         bailout_id, OutputFrameStateCombine::Ignore(), liveness_before);
619     NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
620 #ifdef DEBUG
621   } else {
622     // In case we skipped checkpoint creation above, we must be able to find an
623     // existing checkpoint that effect-dominates the nodes about to be created.
624     // Starting a search from the current effect-dependency has to succeed.
625     Node* effect = environment()->GetEffectDependency();
626     while (effect->opcode() != IrOpcode::kCheckpoint) {
627       DCHECK(effect->op()->HasProperty(Operator::kNoWrite));
628       DCHECK_EQ(1, effect->op()->EffectInputCount());
629       effect = NodeProperties::GetEffectInput(effect);
630     }
631   }
632 #else
633   }
634 #endif  // DEBUG
635 }
636 
PrepareFrameState(Node * node,OutputFrameStateCombine combine)637 void BytecodeGraphBuilder::PrepareFrameState(Node* node,
638                                              OutputFrameStateCombine combine) {
639   if (OperatorProperties::HasFrameStateInput(node->op())) {
640     // Add the frame state for after the operation. The node in question has
641     // already been created and had a {Dead} frame state input up until now.
642     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
643     DCHECK_EQ(IrOpcode::kDead,
644               NodeProperties::GetFrameStateInput(node)->opcode());
645     BailoutId bailout_id(bytecode_iterator().current_offset());
646 
647     const BytecodeLivenessState* liveness_after =
648         bytecode_analysis()->GetOutLivenessFor(
649             bytecode_iterator().current_offset());
650 
651     Node* frame_state_after =
652         environment()->Checkpoint(bailout_id, combine, liveness_after);
653     NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
654   }
655 }
656 
657 // Stores the state of the SourcePosition iterator, and the index to the
658 // current exception handlers stack. We need, during the OSR graph generation,
659 // to backup the states of these iterators at the LoopHeader offset of each
660 // outer loop which contains the OSR loop. The iterators are then restored when
661 // peeling the loops, so that both exception handling and synchronisation with
662 // the source position can be achieved.
663 class BytecodeGraphBuilder::OsrIteratorState {
664  public:
OsrIteratorState(interpreter::BytecodeArrayIterator * iterator,SourcePositionTableIterator * source_position_iterator,BytecodeGraphBuilder * graph_builder)665   OsrIteratorState(interpreter::BytecodeArrayIterator* iterator,
666                    SourcePositionTableIterator* source_position_iterator,
667                    BytecodeGraphBuilder* graph_builder)
668       : iterator_(iterator),
669         source_position_iterator_(source_position_iterator),
670         graph_builder_(graph_builder),
671         saved_states_(graph_builder->local_zone()) {}
672 
ProcessOsrPrelude()673   void ProcessOsrPrelude() {
674     ZoneVector<int> outer_loop_offsets(graph_builder_->local_zone());
675 
676     const BytecodeAnalysis& bytecode_analysis =
677         *(graph_builder_->bytecode_analysis());
678     int osr_offset = bytecode_analysis.osr_entry_point();
679 
680     // We find here the outermost loop which contains the OSR loop.
681     int outermost_loop_offset = osr_offset;
682     while ((outermost_loop_offset =
683                 bytecode_analysis.GetLoopInfoFor(outermost_loop_offset)
684                     .parent_offset()) != -1) {
685       outer_loop_offsets.push_back(outermost_loop_offset);
686     }
687     outermost_loop_offset =
688         outer_loop_offsets.empty() ? osr_offset : outer_loop_offsets.back();
689 
690     // We will not processs any bytecode before the outermost_loop_offset, but
691     // the source_position_iterator needs to be advanced step by step through
692     // the bytecode.
693     for (; iterator_->current_offset() != outermost_loop_offset;
694          iterator_->Advance()) {
695       graph_builder_->UpdateSourcePosition(source_position_iterator_,
696                                            iterator_->current_offset());
697     }
698 
699     // We save some iterators states at the offsets of the loop headers of the
700     // outer loops (the ones containing the OSR loop). They will be used for
701     // jumping back in the bytecode.
702     for (ZoneVector<int>::const_reverse_iterator it =
703              outer_loop_offsets.crbegin();
704          it != outer_loop_offsets.crend(); ++it) {
705       int next_loop_offset = *it;
706       for (; iterator_->current_offset() != next_loop_offset;
707            iterator_->Advance()) {
708         graph_builder_->UpdateSourcePosition(source_position_iterator_,
709                                              iterator_->current_offset());
710       }
711       graph_builder_->ExitThenEnterExceptionHandlers(
712           iterator_->current_offset());
713       saved_states_.push(
714           IteratorsStates(graph_builder_->current_exception_handler(),
715                           source_position_iterator_->GetState()));
716     }
717 
718     // Finishing by advancing to the OSR entry
719     for (; iterator_->current_offset() != osr_offset; iterator_->Advance()) {
720       graph_builder_->UpdateSourcePosition(source_position_iterator_,
721                                            iterator_->current_offset());
722     }
723 
724     // Enters all remaining exception handler which end before the OSR loop
725     // so that on next call of VisitSingleBytecode they will get popped from
726     // the exception handlers stack.
727     graph_builder_->ExitThenEnterExceptionHandlers(osr_offset);
728     graph_builder_->set_currently_peeled_loop_offset(
729         bytecode_analysis.GetLoopInfoFor(osr_offset).parent_offset());
730   }
731 
RestoreState(int target_offset,int new_parent_offset)732   void RestoreState(int target_offset, int new_parent_offset) {
733     iterator_->SetOffset(target_offset);
734     // In case of a return, we must not build loop exits for
735     // not-yet-built outer loops.
736     graph_builder_->set_currently_peeled_loop_offset(new_parent_offset);
737     IteratorsStates saved_state = saved_states_.top();
738     source_position_iterator_->RestoreState(saved_state.source_iterator_state_);
739     graph_builder_->set_current_exception_handler(
740         saved_state.exception_handler_index_);
741     saved_states_.pop();
742   }
743 
744  private:
745   struct IteratorsStates {
746     int exception_handler_index_;
747     SourcePositionTableIterator::IndexAndPosition source_iterator_state_;
748 
IteratorsStatesv8::internal::compiler::BytecodeGraphBuilder::OsrIteratorState::IteratorsStates749     IteratorsStates(
750         int exception_handler_index,
751         SourcePositionTableIterator::IndexAndPosition source_iterator_state)
752         : exception_handler_index_(exception_handler_index),
753           source_iterator_state_(source_iterator_state) {}
754   };
755 
756   interpreter::BytecodeArrayIterator* iterator_;
757   SourcePositionTableIterator* source_position_iterator_;
758   BytecodeGraphBuilder* graph_builder_;
759   ZoneStack<IteratorsStates> saved_states_;
760 };
761 
RemoveMergeEnvironmentsBeforeOffset(int limit_offset)762 void BytecodeGraphBuilder::RemoveMergeEnvironmentsBeforeOffset(
763     int limit_offset) {
764   if (!merge_environments_.empty()) {
765     ZoneMap<int, Environment*>::iterator it = merge_environments_.begin();
766     ZoneMap<int, Environment*>::iterator stop_it = merge_environments_.end();
767     while (it != stop_it && it->first <= limit_offset) {
768       it = merge_environments_.erase(it);
769     }
770   }
771 }
772 
773 // We will iterate through the OSR loop, then its parent, and so on
774 // until we have reached the outmost loop containing the OSR loop. We do
775 // not generate nodes for anything before the outermost loop.
AdvanceToOsrEntryAndPeelLoops(interpreter::BytecodeArrayIterator * iterator,SourcePositionTableIterator * source_position_iterator)776 void BytecodeGraphBuilder::AdvanceToOsrEntryAndPeelLoops(
777     interpreter::BytecodeArrayIterator* iterator,
778     SourcePositionTableIterator* source_position_iterator) {
779   const BytecodeAnalysis& analysis = *(bytecode_analysis());
780   int osr_offset = analysis.osr_entry_point();
781   OsrIteratorState iterator_states(iterator, source_position_iterator, this);
782 
783   iterator_states.ProcessOsrPrelude();
784   DCHECK_EQ(iterator->current_offset(), osr_offset);
785 
786   environment()->FillWithOsrValues();
787 
788   // Suppose we have n nested loops, loop_0 being the outermost one, and
789   // loop_n being the OSR loop. We start iterating the bytecode at the header
790   // of loop_n (the OSR loop), and then we peel the part of the the body of
791   // loop_{n-1} following the end of loop_n. We then rewind the iterator to
792   // the header of loop_{n-1}, and so on until we have partly peeled loop 0.
793   // The full loop_0 body will be generating with the rest of the function,
794   // outside the OSR generation.
795 
796   // To do so, if we are visiting a loop, we continue to visit what's left
797   // of its parent, and then when reaching the parent's JumpLoop, we do not
798   // create any jump for that but rewind the bytecode iterator to visit the
799   // parent loop entirely, and so on.
800 
801   int current_parent_offset =
802       analysis.GetLoopInfoFor(osr_offset).parent_offset();
803   while (current_parent_offset != -1) {
804     LoopInfo current_parent_loop =
805         analysis.GetLoopInfoFor(current_parent_offset);
806     // We iterate until the back edge of the parent loop, which we detect by
807     // the offset that the JumpLoop targets.
808     for (; !iterator->done(); iterator->Advance()) {
809       if (iterator->current_bytecode() == interpreter::Bytecode::kJumpLoop &&
810           iterator->GetJumpTargetOffset() == current_parent_offset) {
811         // Reached the end of the current parent loop.
812         break;
813       }
814       VisitSingleBytecode(source_position_iterator);
815     }
816     DCHECK(!iterator->done());  // Should have found the loop's jump target.
817 
818     // We also need to take care of the merge environments and exceptions
819     // handlers here because the omitted JumpLoop bytecode can still be the
820     // target of jumps or the first bytecode after a try block.
821     ExitThenEnterExceptionHandlers(iterator->current_offset());
822     SwitchToMergeEnvironment(iterator->current_offset());
823 
824     // This jump is the jump of our parent loop, which is not yet created.
825     // So we do not build the jump nodes, but restore the bytecode and the
826     // SourcePosition iterators to the values they had when we were visiting
827     // the offset pointed at by the JumpLoop we've just reached.
828     // We have already built nodes for inner loops, but now we will
829     // iterate again over them and build new nodes corresponding to the same
830     // bytecode offsets. Any jump or reference to this inner loops must now
831     // point to the new nodes we will build, hence we clear the relevant part
832     // of the environment.
833     // Completely clearing the environment is not possible because merge
834     // environments for forward jumps out of the loop need to be preserved
835     // (e.g. a return or a labeled break in the middle of a loop).
836     RemoveMergeEnvironmentsBeforeOffset(iterator->current_offset());
837     iterator_states.RestoreState(current_parent_offset,
838                                  current_parent_loop.parent_offset());
839     current_parent_offset = current_parent_loop.parent_offset();
840   }
841 }
842 
VisitSingleBytecode(SourcePositionTableIterator * source_position_iterator)843 void BytecodeGraphBuilder::VisitSingleBytecode(
844     SourcePositionTableIterator* source_position_iterator) {
845   const interpreter::BytecodeArrayIterator& iterator = bytecode_iterator();
846   int current_offset = iterator.current_offset();
847   UpdateSourcePosition(source_position_iterator, current_offset);
848   ExitThenEnterExceptionHandlers(current_offset);
849   DCHECK_GE(exception_handlers_.empty() ? current_offset
850                                         : exception_handlers_.top().end_offset_,
851             current_offset);
852   SwitchToMergeEnvironment(current_offset);
853 
854   if (environment() != nullptr) {
855     BuildLoopHeaderEnvironment(current_offset);
856 
857     // Skip the first stack check if stack_check is false
858     if (!stack_check() &&
859         iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) {
860       set_stack_check(true);
861       return;
862     }
863 
864     switch (iterator.current_bytecode()) {
865 #define BYTECODE_CASE(name, ...)       \
866   case interpreter::Bytecode::k##name: \
867     Visit##name();                     \
868     break;
869       BYTECODE_LIST(BYTECODE_CASE)
870 #undef BYTECODE_CODE
871     }
872   }
873 }
874 
VisitBytecodes()875 void BytecodeGraphBuilder::VisitBytecodes() {
876   BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(),
877                                      analyze_environment_liveness());
878   bytecode_analysis.Analyze(osr_offset_);
879   set_bytecode_analysis(&bytecode_analysis);
880 
881   interpreter::BytecodeArrayIterator iterator(bytecode_array());
882   set_bytecode_iterator(&iterator);
883   SourcePositionTableIterator source_position_iterator(
884       handle(bytecode_array()->SourcePositionTable(), isolate()));
885 
886   if (analyze_environment_liveness() && FLAG_trace_environment_liveness) {
887     StdoutStream of;
888     bytecode_analysis.PrintLivenessTo(of);
889   }
890 
891   if (!bytecode_analysis.resume_jump_targets().empty()) {
892     environment()->BindGeneratorState(
893         jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
894   }
895 
896   if (bytecode_analysis.HasOsrEntryPoint()) {
897     // We peel the OSR loop and any outer loop containing it except that we
898     // leave the nodes corresponding to the whole outermost loop (including
899     // the last copies of the loops it contains) to be generated by the normal
900     // bytecode iteration below.
901     AdvanceToOsrEntryAndPeelLoops(&iterator, &source_position_iterator);
902   }
903 
904   for (; !iterator.done(); iterator.Advance()) {
905     VisitSingleBytecode(&source_position_iterator);
906   }
907   set_bytecode_analysis(nullptr);
908   set_bytecode_iterator(nullptr);
909   DCHECK(exception_handlers_.empty());
910 }
911 
VisitLdaZero()912 void BytecodeGraphBuilder::VisitLdaZero() {
913   Node* node = jsgraph()->ZeroConstant();
914   environment()->BindAccumulator(node);
915 }
916 
VisitLdaSmi()917 void BytecodeGraphBuilder::VisitLdaSmi() {
918   Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
919   environment()->BindAccumulator(node);
920 }
921 
VisitLdaConstant()922 void BytecodeGraphBuilder::VisitLdaConstant() {
923   Node* node = jsgraph()->Constant(
924       handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
925   environment()->BindAccumulator(node);
926 }
927 
VisitLdaUndefined()928 void BytecodeGraphBuilder::VisitLdaUndefined() {
929   Node* node = jsgraph()->UndefinedConstant();
930   environment()->BindAccumulator(node);
931 }
932 
VisitLdaNull()933 void BytecodeGraphBuilder::VisitLdaNull() {
934   Node* node = jsgraph()->NullConstant();
935   environment()->BindAccumulator(node);
936 }
937 
VisitLdaTheHole()938 void BytecodeGraphBuilder::VisitLdaTheHole() {
939   Node* node = jsgraph()->TheHoleConstant();
940   environment()->BindAccumulator(node);
941 }
942 
VisitLdaTrue()943 void BytecodeGraphBuilder::VisitLdaTrue() {
944   Node* node = jsgraph()->TrueConstant();
945   environment()->BindAccumulator(node);
946 }
947 
VisitLdaFalse()948 void BytecodeGraphBuilder::VisitLdaFalse() {
949   Node* node = jsgraph()->FalseConstant();
950   environment()->BindAccumulator(node);
951 }
952 
VisitLdar()953 void BytecodeGraphBuilder::VisitLdar() {
954   Node* value =
955       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
956   environment()->BindAccumulator(value);
957 }
958 
VisitStar()959 void BytecodeGraphBuilder::VisitStar() {
960   Node* value = environment()->LookupAccumulator();
961   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
962 }
963 
VisitMov()964 void BytecodeGraphBuilder::VisitMov() {
965   Node* value =
966       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
967   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
968 }
969 
BuildLoadGlobal(Handle<Name> name,uint32_t feedback_slot_index,TypeofMode typeof_mode)970 Node* BytecodeGraphBuilder::BuildLoadGlobal(Handle<Name> name,
971                                             uint32_t feedback_slot_index,
972                                             TypeofMode typeof_mode) {
973   VectorSlotPair feedback = CreateVectorSlotPair(feedback_slot_index);
974   DCHECK(IsLoadGlobalICKind(feedback_vector()->GetKind(feedback.slot())));
975   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
976   return NewNode(op);
977 }
978 
VisitLdaGlobal()979 void BytecodeGraphBuilder::VisitLdaGlobal() {
980   PrepareEagerCheckpoint();
981   Handle<Name> name(
982       Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
983   uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
984   Node* node =
985       BuildLoadGlobal(name, feedback_slot_index, TypeofMode::NOT_INSIDE_TYPEOF);
986   environment()->BindAccumulator(node, Environment::kAttachFrameState);
987 }
988 
VisitLdaGlobalInsideTypeof()989 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
990   PrepareEagerCheckpoint();
991   Handle<Name> name(
992       Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
993   uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
994   Node* node =
995       BuildLoadGlobal(name, feedback_slot_index, TypeofMode::INSIDE_TYPEOF);
996   environment()->BindAccumulator(node, Environment::kAttachFrameState);
997 }
998 
VisitStaGlobal()999 void BytecodeGraphBuilder::VisitStaGlobal() {
1000   PrepareEagerCheckpoint();
1001   Handle<Name> name(
1002       Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
1003   VectorSlotPair feedback =
1004       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
1005   Node* value = environment()->LookupAccumulator();
1006 
1007   LanguageMode language_mode =
1008       feedback.vector()->GetLanguageMode(feedback.slot());
1009   const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
1010   Node* node = NewNode(op, value);
1011   environment()->RecordAfterState(node, Environment::kAttachFrameState);
1012 }
1013 
VisitStaInArrayLiteral()1014 void BytecodeGraphBuilder::VisitStaInArrayLiteral() {
1015   PrepareEagerCheckpoint();
1016   Node* value = environment()->LookupAccumulator();
1017   Node* array =
1018       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1019   Node* index =
1020       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1021   VectorSlotPair feedback =
1022       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1023   const Operator* op = javascript()->StoreInArrayLiteral(feedback);
1024 
1025   JSTypeHintLowering::LoweringResult lowering =
1026       TryBuildSimplifiedStoreKeyed(op, array, index, value, feedback.slot());
1027   if (lowering.IsExit()) return;
1028 
1029   Node* node = nullptr;
1030   if (lowering.IsSideEffectFree()) {
1031     node = lowering.value();
1032   } else {
1033     DCHECK(!lowering.Changed());
1034     node = NewNode(op, array, index, value);
1035   }
1036 
1037   environment()->RecordAfterState(node, Environment::kAttachFrameState);
1038 }
1039 
VisitStaDataPropertyInLiteral()1040 void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
1041   PrepareEagerCheckpoint();
1042 
1043   Node* object =
1044       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1045   Node* name =
1046       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1047   Node* value = environment()->LookupAccumulator();
1048   int flags = bytecode_iterator().GetFlagOperand(2);
1049   VectorSlotPair feedback =
1050       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
1051 
1052   const Operator* op = javascript()->StoreDataPropertyInLiteral(feedback);
1053   Node* node = NewNode(op, object, name, value, jsgraph()->Constant(flags));
1054   environment()->RecordAfterState(node, Environment::kAttachFrameState);
1055 }
1056 
VisitCollectTypeProfile()1057 void BytecodeGraphBuilder::VisitCollectTypeProfile() {
1058   PrepareEagerCheckpoint();
1059 
1060   Node* position =
1061       jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
1062   Node* value = environment()->LookupAccumulator();
1063   Node* vector = jsgraph()->Constant(feedback_vector());
1064 
1065   const Operator* op = javascript()->CallRuntime(Runtime::kCollectTypeProfile);
1066 
1067   Node* node = NewNode(op, position, value, vector);
1068   environment()->RecordAfterState(node, Environment::kAttachFrameState);
1069 }
1070 
VisitLdaContextSlot()1071 void BytecodeGraphBuilder::VisitLdaContextSlot() {
1072   const Operator* op = javascript()->LoadContext(
1073       bytecode_iterator().GetUnsignedImmediateOperand(2),
1074       bytecode_iterator().GetIndexOperand(1), false);
1075   Node* node = NewNode(op);
1076   Node* context =
1077       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1078   NodeProperties::ReplaceContextInput(node, context);
1079   environment()->BindAccumulator(node);
1080 }
1081 
VisitLdaImmutableContextSlot()1082 void BytecodeGraphBuilder::VisitLdaImmutableContextSlot() {
1083   const Operator* op = javascript()->LoadContext(
1084       bytecode_iterator().GetUnsignedImmediateOperand(2),
1085       bytecode_iterator().GetIndexOperand(1), true);
1086   Node* node = NewNode(op);
1087   Node* context =
1088       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1089   NodeProperties::ReplaceContextInput(node, context);
1090   environment()->BindAccumulator(node);
1091 }
1092 
VisitLdaCurrentContextSlot()1093 void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
1094   const Operator* op = javascript()->LoadContext(
1095       0, bytecode_iterator().GetIndexOperand(0), false);
1096   Node* node = NewNode(op);
1097   environment()->BindAccumulator(node);
1098 }
1099 
VisitLdaImmutableCurrentContextSlot()1100 void BytecodeGraphBuilder::VisitLdaImmutableCurrentContextSlot() {
1101   const Operator* op = javascript()->LoadContext(
1102       0, bytecode_iterator().GetIndexOperand(0), true);
1103   Node* node = NewNode(op);
1104   environment()->BindAccumulator(node);
1105 }
1106 
VisitStaContextSlot()1107 void BytecodeGraphBuilder::VisitStaContextSlot() {
1108   const Operator* op = javascript()->StoreContext(
1109       bytecode_iterator().GetUnsignedImmediateOperand(2),
1110       bytecode_iterator().GetIndexOperand(1));
1111   Node* value = environment()->LookupAccumulator();
1112   Node* node = NewNode(op, value);
1113   Node* context =
1114       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1115   NodeProperties::ReplaceContextInput(node, context);
1116 }
1117 
VisitStaCurrentContextSlot()1118 void BytecodeGraphBuilder::VisitStaCurrentContextSlot() {
1119   const Operator* op =
1120       javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0));
1121   Node* value = environment()->LookupAccumulator();
1122   NewNode(op, value);
1123 }
1124 
BuildLdaLookupSlot(TypeofMode typeof_mode)1125 void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
1126   PrepareEagerCheckpoint();
1127   Node* name = jsgraph()->Constant(
1128       handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
1129   const Operator* op =
1130       javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
1131                                     ? Runtime::kLoadLookupSlot
1132                                     : Runtime::kLoadLookupSlotInsideTypeof);
1133   Node* value = NewNode(op, name);
1134   environment()->BindAccumulator(value, Environment::kAttachFrameState);
1135 }
1136 
VisitLdaLookupSlot()1137 void BytecodeGraphBuilder::VisitLdaLookupSlot() {
1138   BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
1139 }
1140 
VisitLdaLookupSlotInsideTypeof()1141 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
1142   BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
1143 }
1144 
CheckContextExtensions(uint32_t depth)1145 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
1146     uint32_t depth) {
1147   // Output environment where the context has an extension
1148   Environment* slow_environment = nullptr;
1149 
1150   // We only need to check up to the last-but-one depth, because the an eval
1151   // in the same scope as the variable itself has no way of shadowing it.
1152   for (uint32_t d = 0; d < depth; d++) {
1153     Node* extension_slot =
1154         NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false));
1155 
1156     Node* check_no_extension =
1157         NewNode(simplified()->ReferenceEqual(), extension_slot,
1158                 jsgraph()->TheHoleConstant());
1159 
1160     NewBranch(check_no_extension);
1161 
1162     {
1163       SubEnvironment sub_environment(this);
1164 
1165       NewIfFalse();
1166       // If there is an extension, merge into the slow path.
1167       if (slow_environment == nullptr) {
1168         slow_environment = environment();
1169         NewMerge();
1170       } else {
1171         slow_environment->Merge(environment(),
1172                                 bytecode_analysis()->GetInLivenessFor(
1173                                     bytecode_iterator().current_offset()));
1174       }
1175     }
1176 
1177     NewIfTrue();
1178     // Do nothing on if there is no extension, eventually falling through to
1179     // the fast path.
1180   }
1181 
1182   // The depth can be zero, in which case no slow-path checks are built, and
1183   // the slow path environment can be null.
1184   DCHECK(depth == 0 || slow_environment != nullptr);
1185 
1186   return slow_environment;
1187 }
1188 
BuildLdaLookupContextSlot(TypeofMode typeof_mode)1189 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
1190   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
1191 
1192   // Check if any context in the depth has an extension.
1193   Environment* slow_environment = CheckContextExtensions(depth);
1194 
1195   // Fast path, do a context load.
1196   {
1197     uint32_t slot_index = bytecode_iterator().GetIndexOperand(1);
1198 
1199     const Operator* op = javascript()->LoadContext(depth, slot_index, false);
1200     environment()->BindAccumulator(NewNode(op));
1201   }
1202 
1203   // Only build the slow path if there were any slow-path checks.
1204   if (slow_environment != nullptr) {
1205     // Add a merge to the fast environment.
1206     NewMerge();
1207     Environment* fast_environment = environment();
1208 
1209     // Slow path, do a runtime load lookup.
1210     set_environment(slow_environment);
1211     {
1212       Node* name = jsgraph()->Constant(
1213           handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
1214 
1215       const Operator* op =
1216           javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
1217                                         ? Runtime::kLoadLookupSlot
1218                                         : Runtime::kLoadLookupSlotInsideTypeof);
1219       Node* value = NewNode(op, name);
1220       environment()->BindAccumulator(value, Environment::kAttachFrameState);
1221     }
1222 
1223     fast_environment->Merge(environment(),
1224                             bytecode_analysis()->GetOutLivenessFor(
1225                                 bytecode_iterator().current_offset()));
1226     set_environment(fast_environment);
1227     mark_as_needing_eager_checkpoint(true);
1228   }
1229 }
1230 
VisitLdaLookupContextSlot()1231 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() {
1232   BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF);
1233 }
1234 
VisitLdaLookupContextSlotInsideTypeof()1235 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() {
1236   BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF);
1237 }
1238 
BuildLdaLookupGlobalSlot(TypeofMode typeof_mode)1239 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
1240   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
1241 
1242   // Check if any context in the depth has an extension.
1243   Environment* slow_environment = CheckContextExtensions(depth);
1244 
1245   // Fast path, do a global load.
1246   {
1247     PrepareEagerCheckpoint();
1248     Handle<Name> name(
1249         Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1250         isolate());
1251     uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
1252     Node* node = BuildLoadGlobal(name, feedback_slot_index, typeof_mode);
1253     environment()->BindAccumulator(node, Environment::kAttachFrameState);
1254   }
1255 
1256   // Only build the slow path if there were any slow-path checks.
1257   if (slow_environment != nullptr) {
1258     // Add a merge to the fast environment.
1259     NewMerge();
1260     Environment* fast_environment = environment();
1261 
1262     // Slow path, do a runtime load lookup.
1263     set_environment(slow_environment);
1264     {
1265       Node* name = jsgraph()->Constant(
1266           handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
1267 
1268       const Operator* op =
1269           javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
1270                                         ? Runtime::kLoadLookupSlot
1271                                         : Runtime::kLoadLookupSlotInsideTypeof);
1272       Node* value = NewNode(op, name);
1273       environment()->BindAccumulator(value, Environment::kAttachFrameState);
1274     }
1275 
1276     fast_environment->Merge(environment(),
1277                             bytecode_analysis()->GetOutLivenessFor(
1278                                 bytecode_iterator().current_offset()));
1279     set_environment(fast_environment);
1280     mark_as_needing_eager_checkpoint(true);
1281   }
1282 }
1283 
VisitLdaLookupGlobalSlot()1284 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() {
1285   BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF);
1286 }
1287 
VisitLdaLookupGlobalSlotInsideTypeof()1288 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
1289   BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF);
1290 }
1291 
VisitStaLookupSlot()1292 void BytecodeGraphBuilder::VisitStaLookupSlot() {
1293   PrepareEagerCheckpoint();
1294   Node* value = environment()->LookupAccumulator();
1295   Node* name = jsgraph()->Constant(
1296       handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
1297   int bytecode_flags = bytecode_iterator().GetFlagOperand(1);
1298   LanguageMode language_mode = static_cast<LanguageMode>(
1299       interpreter::StoreLookupSlotFlags::LanguageModeBit::decode(
1300           bytecode_flags));
1301   LookupHoistingMode lookup_hoisting_mode = static_cast<LookupHoistingMode>(
1302       interpreter::StoreLookupSlotFlags::LookupHoistingModeBit::decode(
1303           bytecode_flags));
1304   DCHECK_IMPLIES(lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy,
1305                  is_sloppy(language_mode));
1306   const Operator* op = javascript()->CallRuntime(
1307       is_strict(language_mode)
1308           ? Runtime::kStoreLookupSlot_Strict
1309           : lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy
1310                 ? Runtime::kStoreLookupSlot_SloppyHoisting
1311                 : Runtime::kStoreLookupSlot_Sloppy);
1312   Node* store = NewNode(op, name, value);
1313   environment()->BindAccumulator(store, Environment::kAttachFrameState);
1314 }
1315 
VisitLdaNamedProperty()1316 void BytecodeGraphBuilder::VisitLdaNamedProperty() {
1317   PrepareEagerCheckpoint();
1318   Node* object =
1319       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1320   Handle<Name> name(
1321       Name::cast(bytecode_iterator().GetConstantForIndexOperand(1)), isolate());
1322   VectorSlotPair feedback =
1323       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1324   const Operator* op = javascript()->LoadNamed(name, feedback);
1325 
1326   JSTypeHintLowering::LoweringResult lowering =
1327       TryBuildSimplifiedLoadNamed(op, object, feedback.slot());
1328   if (lowering.IsExit()) return;
1329 
1330   Node* node = nullptr;
1331   if (lowering.IsSideEffectFree()) {
1332     node = lowering.value();
1333   } else {
1334     DCHECK(!lowering.Changed());
1335     node = NewNode(op, object);
1336   }
1337   environment()->BindAccumulator(node, Environment::kAttachFrameState);
1338 }
1339 
VisitLdaKeyedProperty()1340 void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
1341   PrepareEagerCheckpoint();
1342   Node* key = environment()->LookupAccumulator();
1343   Node* object =
1344       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1345   VectorSlotPair feedback =
1346       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
1347   const Operator* op = javascript()->LoadProperty(feedback);
1348 
1349   JSTypeHintLowering::LoweringResult lowering =
1350       TryBuildSimplifiedLoadKeyed(op, object, key, feedback.slot());
1351   if (lowering.IsExit()) return;
1352 
1353   Node* node = nullptr;
1354   if (lowering.IsSideEffectFree()) {
1355     node = lowering.value();
1356   } else {
1357     DCHECK(!lowering.Changed());
1358     node = NewNode(op, object, key);
1359   }
1360   environment()->BindAccumulator(node, Environment::kAttachFrameState);
1361 }
1362 
BuildNamedStore(StoreMode store_mode)1363 void BytecodeGraphBuilder::BuildNamedStore(StoreMode store_mode) {
1364   PrepareEagerCheckpoint();
1365   Node* value = environment()->LookupAccumulator();
1366   Node* object =
1367       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1368   Handle<Name> name(
1369       Name::cast(bytecode_iterator().GetConstantForIndexOperand(1)), isolate());
1370   VectorSlotPair feedback =
1371       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1372 
1373   const Operator* op;
1374   if (store_mode == StoreMode::kOwn) {
1375     DCHECK_EQ(FeedbackSlotKind::kStoreOwnNamed,
1376               feedback.vector()->GetKind(feedback.slot()));
1377     op = javascript()->StoreNamedOwn(name, feedback);
1378   } else {
1379     DCHECK_EQ(StoreMode::kNormal, store_mode);
1380     LanguageMode language_mode =
1381         feedback.vector()->GetLanguageMode(feedback.slot());
1382     op = javascript()->StoreNamed(language_mode, name, feedback);
1383   }
1384 
1385   JSTypeHintLowering::LoweringResult lowering =
1386       TryBuildSimplifiedStoreNamed(op, object, value, feedback.slot());
1387   if (lowering.IsExit()) return;
1388 
1389   Node* node = nullptr;
1390   if (lowering.IsSideEffectFree()) {
1391     node = lowering.value();
1392   } else {
1393     DCHECK(!lowering.Changed());
1394     node = NewNode(op, object, value);
1395   }
1396   environment()->RecordAfterState(node, Environment::kAttachFrameState);
1397 }
1398 
VisitStaNamedProperty()1399 void BytecodeGraphBuilder::VisitStaNamedProperty() {
1400   BuildNamedStore(StoreMode::kNormal);
1401 }
1402 
VisitStaNamedOwnProperty()1403 void BytecodeGraphBuilder::VisitStaNamedOwnProperty() {
1404   BuildNamedStore(StoreMode::kOwn);
1405 }
1406 
VisitStaKeyedProperty()1407 void BytecodeGraphBuilder::VisitStaKeyedProperty() {
1408   PrepareEagerCheckpoint();
1409   Node* value = environment()->LookupAccumulator();
1410   Node* object =
1411       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1412   Node* key =
1413       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1414   VectorSlotPair feedback =
1415       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1416   LanguageMode language_mode =
1417       feedback.vector()->GetLanguageMode(feedback.slot());
1418   const Operator* op = javascript()->StoreProperty(language_mode, feedback);
1419 
1420   JSTypeHintLowering::LoweringResult lowering =
1421       TryBuildSimplifiedStoreKeyed(op, object, key, value, feedback.slot());
1422   if (lowering.IsExit()) return;
1423 
1424   Node* node = nullptr;
1425   if (lowering.IsSideEffectFree()) {
1426     node = lowering.value();
1427   } else {
1428     DCHECK(!lowering.Changed());
1429     node = NewNode(op, object, key, value);
1430   }
1431 
1432   environment()->RecordAfterState(node, Environment::kAttachFrameState);
1433 }
1434 
VisitLdaModuleVariable()1435 void BytecodeGraphBuilder::VisitLdaModuleVariable() {
1436   int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
1437   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
1438   Node* module =
1439       NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
1440   Node* value = NewNode(javascript()->LoadModule(cell_index), module);
1441   environment()->BindAccumulator(value);
1442 }
1443 
VisitStaModuleVariable()1444 void BytecodeGraphBuilder::VisitStaModuleVariable() {
1445   int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
1446   uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
1447   Node* module =
1448       NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
1449   Node* value = environment()->LookupAccumulator();
1450   NewNode(javascript()->StoreModule(cell_index), module, value);
1451 }
1452 
VisitPushContext()1453 void BytecodeGraphBuilder::VisitPushContext() {
1454   Node* new_context = environment()->LookupAccumulator();
1455   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
1456                               environment()->Context());
1457   environment()->SetContext(new_context);
1458 }
1459 
VisitPopContext()1460 void BytecodeGraphBuilder::VisitPopContext() {
1461   Node* context =
1462       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1463   environment()->SetContext(context);
1464 }
1465 
VisitCreateClosure()1466 void BytecodeGraphBuilder::VisitCreateClosure() {
1467   Handle<SharedFunctionInfo> shared_info(
1468       SharedFunctionInfo::cast(
1469           bytecode_iterator().GetConstantForIndexOperand(0)),
1470       isolate());
1471   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
1472   FeedbackNexus nexus(feedback_vector(), slot);
1473   PretenureFlag tenured =
1474       interpreter::CreateClosureFlags::PretenuredBit::decode(
1475           bytecode_iterator().GetFlagOperand(2))
1476           ? TENURED
1477           : NOT_TENURED;
1478   const Operator* op = javascript()->CreateClosure(
1479       shared_info, nexus.GetFeedbackCell(),
1480       handle(jsgraph()->isolate()->builtins()->builtin(Builtins::kCompileLazy),
1481              isolate()),
1482       tenured);
1483   Node* closure = NewNode(op);
1484   environment()->BindAccumulator(closure);
1485 }
1486 
VisitCreateBlockContext()1487 void BytecodeGraphBuilder::VisitCreateBlockContext() {
1488   Handle<ScopeInfo> scope_info(
1489       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1490       isolate());
1491 
1492   const Operator* op = javascript()->CreateBlockContext(scope_info);
1493   Node* context = NewNode(op);
1494   environment()->BindAccumulator(context);
1495 }
1496 
VisitCreateFunctionContext()1497 void BytecodeGraphBuilder::VisitCreateFunctionContext() {
1498   Handle<ScopeInfo> scope_info(
1499       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1500       isolate());
1501   uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
1502   const Operator* op =
1503       javascript()->CreateFunctionContext(scope_info, slots, FUNCTION_SCOPE);
1504   Node* context = NewNode(op);
1505   environment()->BindAccumulator(context);
1506 }
1507 
VisitCreateEvalContext()1508 void BytecodeGraphBuilder::VisitCreateEvalContext() {
1509   Handle<ScopeInfo> scope_info(
1510       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1511       isolate());
1512   uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
1513   const Operator* op =
1514       javascript()->CreateFunctionContext(scope_info, slots, EVAL_SCOPE);
1515   Node* context = NewNode(op);
1516   environment()->BindAccumulator(context);
1517 }
1518 
VisitCreateCatchContext()1519 void BytecodeGraphBuilder::VisitCreateCatchContext() {
1520   interpreter::Register reg = bytecode_iterator().GetRegisterOperand(0);
1521   Node* exception = environment()->LookupRegister(reg);
1522   Handle<ScopeInfo> scope_info(
1523       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(1)),
1524       isolate());
1525 
1526   const Operator* op = javascript()->CreateCatchContext(scope_info);
1527   Node* context = NewNode(op, exception);
1528   environment()->BindAccumulator(context);
1529 }
1530 
VisitCreateWithContext()1531 void BytecodeGraphBuilder::VisitCreateWithContext() {
1532   Node* object =
1533       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1534   Handle<ScopeInfo> scope_info(
1535       ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(1)),
1536       isolate());
1537 
1538   const Operator* op = javascript()->CreateWithContext(scope_info);
1539   Node* context = NewNode(op, object);
1540   environment()->BindAccumulator(context);
1541 }
1542 
BuildCreateArguments(CreateArgumentsType type)1543 void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
1544   const Operator* op = javascript()->CreateArguments(type);
1545   Node* object = NewNode(op, GetFunctionClosure());
1546   environment()->BindAccumulator(object, Environment::kAttachFrameState);
1547 }
1548 
VisitCreateMappedArguments()1549 void BytecodeGraphBuilder::VisitCreateMappedArguments() {
1550   BuildCreateArguments(CreateArgumentsType::kMappedArguments);
1551 }
1552 
VisitCreateUnmappedArguments()1553 void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
1554   BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
1555 }
1556 
VisitCreateRestParameter()1557 void BytecodeGraphBuilder::VisitCreateRestParameter() {
1558   BuildCreateArguments(CreateArgumentsType::kRestParameter);
1559 }
1560 
VisitCreateRegExpLiteral()1561 void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
1562   Handle<String> constant_pattern(
1563       String::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1564       isolate());
1565   int const slot_id = bytecode_iterator().GetIndexOperand(1);
1566   VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1567   int literal_flags = bytecode_iterator().GetFlagOperand(2);
1568   Node* literal = NewNode(
1569       javascript()->CreateLiteralRegExp(constant_pattern, pair, literal_flags));
1570   environment()->BindAccumulator(literal, Environment::kAttachFrameState);
1571 }
1572 
VisitCreateArrayLiteral()1573 void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
1574   Handle<ArrayBoilerplateDescription> array_boilerplate_description(
1575       ArrayBoilerplateDescription::cast(
1576           bytecode_iterator().GetConstantForIndexOperand(0)),
1577       isolate());
1578   int const slot_id = bytecode_iterator().GetIndexOperand(1);
1579   VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1580   int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
1581   int literal_flags =
1582       interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
1583   // Disable allocation site mementos. Only unoptimized code will collect
1584   // feedback about allocation site. Once the code is optimized we expect the
1585   // data to converge. So, we disable allocation site mementos in optimized
1586   // code. We can revisit this when we have data to the contrary.
1587   literal_flags |= ArrayLiteral::kDisableMementos;
1588   // TODO(mstarzinger): Thread through number of elements. The below number is
1589   // only an estimate and does not match {ArrayLiteral::values::length}.
1590   int number_of_elements =
1591       array_boilerplate_description->constant_elements()->length();
1592   Node* literal = NewNode(javascript()->CreateLiteralArray(
1593       array_boilerplate_description, pair, literal_flags, number_of_elements));
1594   environment()->BindAccumulator(literal, Environment::kAttachFrameState);
1595 }
1596 
VisitCreateEmptyArrayLiteral()1597 void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
1598   int const slot_id = bytecode_iterator().GetIndexOperand(0);
1599   VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1600   Node* literal = NewNode(javascript()->CreateEmptyLiteralArray(pair));
1601   environment()->BindAccumulator(literal);
1602 }
1603 
VisitCreateObjectLiteral()1604 void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
1605   Handle<ObjectBoilerplateDescription> constant_properties(
1606       ObjectBoilerplateDescription::cast(
1607           bytecode_iterator().GetConstantForIndexOperand(0)),
1608       isolate());
1609   int const slot_id = bytecode_iterator().GetIndexOperand(1);
1610   VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1611   int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
1612   int literal_flags =
1613       interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
1614   // TODO(mstarzinger): Thread through number of properties. The below number is
1615   // only an estimate and does not match {ObjectLiteral::properties_count}.
1616   int number_of_properties = constant_properties->size();
1617   Node* literal = NewNode(javascript()->CreateLiteralObject(
1618       constant_properties, pair, literal_flags, number_of_properties));
1619   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3),
1620                               literal, Environment::kAttachFrameState);
1621 }
1622 
VisitCreateEmptyObjectLiteral()1623 void BytecodeGraphBuilder::VisitCreateEmptyObjectLiteral() {
1624   Node* literal =
1625       NewNode(javascript()->CreateEmptyLiteralObject(), GetFunctionClosure());
1626   environment()->BindAccumulator(literal);
1627 }
1628 
VisitCloneObject()1629 void BytecodeGraphBuilder::VisitCloneObject() {
1630   PrepareEagerCheckpoint();
1631   Node* source =
1632       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1633   int flags = bytecode_iterator().GetFlagOperand(1);
1634   int slot = bytecode_iterator().GetIndexOperand(2);
1635   const Operator* op =
1636       javascript()->CloneObject(CreateVectorSlotPair(slot), flags);
1637   Node* value = NewNode(op, source);
1638   environment()->BindAccumulator(value, Environment::kAttachFrameState);
1639 }
1640 
VisitGetTemplateObject()1641 void BytecodeGraphBuilder::VisitGetTemplateObject() {
1642   Handle<TemplateObjectDescription> description(
1643       TemplateObjectDescription::cast(
1644           bytecode_iterator().GetConstantForIndexOperand(0)),
1645       isolate());
1646   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
1647   FeedbackNexus nexus(feedback_vector(), slot);
1648 
1649   Handle<JSArray> cached_value;
1650   if (nexus.GetFeedback() == MaybeObject::FromSmi(Smi::kZero)) {
1651     // It's not observable when the template object is created, so we
1652     // can just create it eagerly during graph building and bake in
1653     // the JSArray constant here.
1654     cached_value =
1655         TemplateObjectDescription::CreateTemplateObject(isolate(), description);
1656     nexus.vector()->Set(slot, *cached_value);
1657   } else {
1658     cached_value = handle(
1659         JSArray::cast(nexus.GetFeedback()->ToStrongHeapObject()), isolate());
1660   }
1661 
1662   Node* template_object = jsgraph()->HeapConstant(cached_value);
1663   environment()->BindAccumulator(template_object);
1664 }
1665 
GetCallArgumentsFromRegisters(Node * callee,Node * receiver,interpreter::Register first_arg,int arg_count)1666 Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
1667     Node* callee, Node* receiver, interpreter::Register first_arg,
1668     int arg_count) {
1669   // The arity of the Call node -- includes the callee, receiver and function
1670   // arguments.
1671   int arity = 2 + arg_count;
1672 
1673   Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1674 
1675   all[0] = callee;
1676   all[1] = receiver;
1677 
1678   // The function arguments are in consecutive registers.
1679   int arg_base = first_arg.index();
1680   for (int i = 0; i < arg_count; ++i) {
1681     all[2 + i] =
1682         environment()->LookupRegister(interpreter::Register(arg_base + i));
1683   }
1684 
1685   return all;
1686 }
1687 
ProcessCallArguments(const Operator * call_op,Node * const * args,int arg_count)1688 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
1689                                                  Node* const* args,
1690                                                  int arg_count) {
1691   return MakeNode(call_op, arg_count, args, false);
1692 }
1693 
ProcessCallArguments(const Operator * call_op,Node * callee,interpreter::Register receiver,size_t reg_count)1694 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
1695                                                  Node* callee,
1696                                                  interpreter::Register receiver,
1697                                                  size_t reg_count) {
1698   Node* receiver_node = environment()->LookupRegister(receiver);
1699   // The receiver is followed by the arguments in the consecutive registers.
1700   DCHECK_GE(reg_count, 1);
1701   interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
1702   int arg_count = static_cast<int>(reg_count) - 1;
1703 
1704   Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
1705                                                          first_arg, arg_count);
1706   return ProcessCallArguments(call_op, call_args, 2 + arg_count);
1707 }
1708 
BuildCall(ConvertReceiverMode receiver_mode,Node * const * args,size_t arg_count,int slot_id)1709 void BytecodeGraphBuilder::BuildCall(ConvertReceiverMode receiver_mode,
1710                                      Node* const* args, size_t arg_count,
1711                                      int slot_id) {
1712   DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
1713                 bytecode_iterator().current_bytecode()),
1714             receiver_mode);
1715   PrepareEagerCheckpoint();
1716 
1717   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1718 
1719   CallFrequency frequency = ComputeCallFrequency(slot_id);
1720   const Operator* op =
1721       javascript()->Call(arg_count, frequency, feedback, receiver_mode,
1722                          GetSpeculationMode(slot_id));
1723   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
1724       op, args, static_cast<int>(arg_count), feedback.slot());
1725   if (lowering.IsExit()) return;
1726 
1727   Node* node = nullptr;
1728   if (lowering.IsSideEffectFree()) {
1729     node = lowering.value();
1730   } else {
1731     DCHECK(!lowering.Changed());
1732     node = ProcessCallArguments(op, args, static_cast<int>(arg_count));
1733   }
1734   environment()->BindAccumulator(node, Environment::kAttachFrameState);
1735 }
1736 
ProcessCallVarArgs(ConvertReceiverMode receiver_mode,Node * callee,interpreter::Register first_reg,int arg_count)1737 Node* const* BytecodeGraphBuilder::ProcessCallVarArgs(
1738     ConvertReceiverMode receiver_mode, Node* callee,
1739     interpreter::Register first_reg, int arg_count) {
1740   DCHECK_GE(arg_count, 0);
1741   Node* receiver_node;
1742   interpreter::Register first_arg;
1743 
1744   if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
1745     // The receiver is implicit (and undefined), the arguments are in
1746     // consecutive registers.
1747     receiver_node = jsgraph()->UndefinedConstant();
1748     first_arg = first_reg;
1749   } else {
1750     // The receiver is the first register, followed by the arguments in the
1751     // consecutive registers.
1752     receiver_node = environment()->LookupRegister(first_reg);
1753     first_arg = interpreter::Register(first_reg.index() + 1);
1754   }
1755 
1756   Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
1757                                                          first_arg, arg_count);
1758   return call_args;
1759 }
1760 
BuildCallVarArgs(ConvertReceiverMode receiver_mode)1761 void BytecodeGraphBuilder::BuildCallVarArgs(ConvertReceiverMode receiver_mode) {
1762   DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
1763                 bytecode_iterator().current_bytecode()),
1764             receiver_mode);
1765   Node* callee =
1766       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1767   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1768   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1769   int const slot_id = bytecode_iterator().GetIndexOperand(3);
1770 
1771   int arg_count = receiver_mode == ConvertReceiverMode::kNullOrUndefined
1772                       ? static_cast<int>(reg_count)
1773                       : static_cast<int>(reg_count) - 1;
1774   Node* const* call_args =
1775       ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count);
1776   BuildCall(receiver_mode, call_args, static_cast<size_t>(2 + arg_count),
1777             slot_id);
1778 }
1779 
VisitCallAnyReceiver()1780 void BytecodeGraphBuilder::VisitCallAnyReceiver() {
1781   BuildCallVarArgs(ConvertReceiverMode::kAny);
1782 }
1783 
VisitCallProperty()1784 void BytecodeGraphBuilder::VisitCallProperty() {
1785   BuildCallVarArgs(ConvertReceiverMode::kNotNullOrUndefined);
1786 }
1787 
VisitCallProperty0()1788 void BytecodeGraphBuilder::VisitCallProperty0() {
1789   Node* callee =
1790       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1791   Node* receiver =
1792       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1793   int const slot_id = bytecode_iterator().GetIndexOperand(2);
1794   BuildCall(ConvertReceiverMode::kNotNullOrUndefined, {callee, receiver},
1795             slot_id);
1796 }
1797 
VisitCallProperty1()1798 void BytecodeGraphBuilder::VisitCallProperty1() {
1799   Node* callee =
1800       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1801   Node* receiver =
1802       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1803   Node* arg0 =
1804       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1805   int const slot_id = bytecode_iterator().GetIndexOperand(3);
1806   BuildCall(ConvertReceiverMode::kNotNullOrUndefined, {callee, receiver, arg0},
1807             slot_id);
1808 }
1809 
VisitCallProperty2()1810 void BytecodeGraphBuilder::VisitCallProperty2() {
1811   Node* callee =
1812       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1813   Node* receiver =
1814       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1815   Node* arg0 =
1816       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1817   Node* arg1 =
1818       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
1819   int const slot_id = bytecode_iterator().GetIndexOperand(4);
1820   BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
1821             {callee, receiver, arg0, arg1}, slot_id);
1822 }
1823 
VisitCallUndefinedReceiver()1824 void BytecodeGraphBuilder::VisitCallUndefinedReceiver() {
1825   BuildCallVarArgs(ConvertReceiverMode::kNullOrUndefined);
1826 }
1827 
VisitCallUndefinedReceiver0()1828 void BytecodeGraphBuilder::VisitCallUndefinedReceiver0() {
1829   Node* callee =
1830       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1831   Node* receiver = jsgraph()->UndefinedConstant();
1832   int const slot_id = bytecode_iterator().GetIndexOperand(1);
1833   BuildCall(ConvertReceiverMode::kNullOrUndefined, {callee, receiver}, slot_id);
1834 }
1835 
VisitCallUndefinedReceiver1()1836 void BytecodeGraphBuilder::VisitCallUndefinedReceiver1() {
1837   Node* callee =
1838       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1839   Node* receiver = jsgraph()->UndefinedConstant();
1840   Node* arg0 =
1841       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1842   int const slot_id = bytecode_iterator().GetIndexOperand(2);
1843   BuildCall(ConvertReceiverMode::kNullOrUndefined, {callee, receiver, arg0},
1844             slot_id);
1845 }
1846 
VisitCallUndefinedReceiver2()1847 void BytecodeGraphBuilder::VisitCallUndefinedReceiver2() {
1848   Node* callee =
1849       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1850   Node* receiver = jsgraph()->UndefinedConstant();
1851   Node* arg0 =
1852       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1853   Node* arg1 =
1854       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1855   int const slot_id = bytecode_iterator().GetIndexOperand(3);
1856   BuildCall(ConvertReceiverMode::kNullOrUndefined,
1857             {callee, receiver, arg0, arg1}, slot_id);
1858 }
1859 
VisitCallWithSpread()1860 void BytecodeGraphBuilder::VisitCallWithSpread() {
1861   PrepareEagerCheckpoint();
1862   Node* callee =
1863       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1864   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1865   Node* receiver_node = environment()->LookupRegister(receiver);
1866   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1867   interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
1868   int arg_count = static_cast<int>(reg_count) - 1;
1869   Node* const* args = GetCallArgumentsFromRegisters(callee, receiver_node,
1870                                                     first_arg, arg_count);
1871   int const slot_id = bytecode_iterator().GetIndexOperand(3);
1872   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1873 
1874   CallFrequency frequency = ComputeCallFrequency(slot_id);
1875   const Operator* op = javascript()->CallWithSpread(
1876       static_cast<int>(reg_count + 1), frequency, feedback);
1877 
1878   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
1879       op, args, static_cast<int>(arg_count), feedback.slot());
1880   if (lowering.IsExit()) return;
1881 
1882   Node* node = nullptr;
1883   if (lowering.IsSideEffectFree()) {
1884     node = lowering.value();
1885   } else {
1886     DCHECK(!lowering.Changed());
1887     node = ProcessCallArguments(op, args, 2 + arg_count);
1888   }
1889   environment()->BindAccumulator(node, Environment::kAttachFrameState);
1890 }
1891 
VisitCallJSRuntime()1892 void BytecodeGraphBuilder::VisitCallJSRuntime() {
1893   PrepareEagerCheckpoint();
1894   Node* callee = BuildLoadNativeContextField(
1895       bytecode_iterator().GetNativeContextIndexOperand(0));
1896   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1897   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1898   int arg_count = static_cast<int>(reg_count);
1899 
1900   const Operator* call = javascript()->Call(2 + arg_count);
1901   Node* const* call_args = ProcessCallVarArgs(
1902       ConvertReceiverMode::kNullOrUndefined, callee, first_reg, arg_count);
1903   Node* value = ProcessCallArguments(call, call_args, 2 + arg_count);
1904   environment()->BindAccumulator(value, Environment::kAttachFrameState);
1905 }
1906 
ProcessCallRuntimeArguments(const Operator * call_runtime_op,interpreter::Register receiver,size_t reg_count)1907 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
1908     const Operator* call_runtime_op, interpreter::Register receiver,
1909     size_t reg_count) {
1910   int arg_count = static_cast<int>(reg_count);
1911   // arity is args.
1912   int arity = arg_count;
1913   Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1914   int first_arg_index = receiver.index();
1915   for (int i = 0; i < static_cast<int>(reg_count); ++i) {
1916     all[i] = environment()->LookupRegister(
1917         interpreter::Register(first_arg_index + i));
1918   }
1919   Node* value = MakeNode(call_runtime_op, arity, all, false);
1920   return value;
1921 }
1922 
VisitCallRuntime()1923 void BytecodeGraphBuilder::VisitCallRuntime() {
1924   PrepareEagerCheckpoint();
1925   Runtime::FunctionId function_id = bytecode_iterator().GetRuntimeIdOperand(0);
1926   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1927   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1928 
1929   // Create node to perform the runtime call.
1930   const Operator* call = javascript()->CallRuntime(function_id, reg_count);
1931   Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
1932   environment()->BindAccumulator(value, Environment::kAttachFrameState);
1933 
1934   // Connect to the end if {function_id} is non-returning.
1935   if (Runtime::IsNonReturning(function_id)) {
1936     // TODO(7099): Investigate if we need LoopExit node here.
1937     Node* control = NewNode(common()->Throw());
1938     MergeControlToLeaveFunction(control);
1939   }
1940 }
1941 
VisitCallRuntimeForPair()1942 void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
1943   PrepareEagerCheckpoint();
1944   Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
1945   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1946   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1947   interpreter::Register first_return =
1948       bytecode_iterator().GetRegisterOperand(3);
1949 
1950   // Create node to perform the runtime call.
1951   const Operator* call = javascript()->CallRuntime(functionId, reg_count);
1952   Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count);
1953   environment()->BindRegistersToProjections(first_return, return_pair,
1954                                             Environment::kAttachFrameState);
1955 }
1956 
GetConstructArgumentsFromRegister(Node * target,Node * new_target,interpreter::Register first_arg,int arg_count)1957 Node* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister(
1958     Node* target, Node* new_target, interpreter::Register first_arg,
1959     int arg_count) {
1960   // arity is args + callee and new target.
1961   int arity = arg_count + 2;
1962   Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1963   all[0] = target;
1964   int first_arg_index = first_arg.index();
1965   for (int i = 0; i < arg_count; ++i) {
1966     all[1 + i] = environment()->LookupRegister(
1967         interpreter::Register(first_arg_index + i));
1968   }
1969   all[arity - 1] = new_target;
1970   return all;
1971 }
1972 
ProcessConstructArguments(const Operator * op,Node * const * args,int arg_count)1973 Node* BytecodeGraphBuilder::ProcessConstructArguments(const Operator* op,
1974                                                       Node* const* args,
1975                                                       int arg_count) {
1976   return MakeNode(op, arg_count, args, false);
1977 }
1978 
VisitConstruct()1979 void BytecodeGraphBuilder::VisitConstruct() {
1980   PrepareEagerCheckpoint();
1981   interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1982   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1983   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1984   int const slot_id = bytecode_iterator().GetIndexOperand(3);
1985   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1986 
1987   Node* new_target = environment()->LookupAccumulator();
1988   Node* callee = environment()->LookupRegister(callee_reg);
1989 
1990   CallFrequency frequency = ComputeCallFrequency(slot_id);
1991   const Operator* op = javascript()->Construct(
1992       static_cast<uint32_t>(reg_count + 2), frequency, feedback);
1993   int arg_count = static_cast<int>(reg_count);
1994   Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
1995                                                         first_reg, arg_count);
1996   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
1997       op, args, static_cast<int>(arg_count), feedback.slot());
1998   if (lowering.IsExit()) return;
1999 
2000   Node* node = nullptr;
2001   if (lowering.IsSideEffectFree()) {
2002     node = lowering.value();
2003   } else {
2004     DCHECK(!lowering.Changed());
2005     node = ProcessConstructArguments(op, args, 2 + arg_count);
2006   }
2007   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2008 }
2009 
VisitConstructWithSpread()2010 void BytecodeGraphBuilder::VisitConstructWithSpread() {
2011   PrepareEagerCheckpoint();
2012   interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
2013   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2014   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2015   int const slot_id = bytecode_iterator().GetIndexOperand(3);
2016   VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
2017 
2018   Node* new_target = environment()->LookupAccumulator();
2019   Node* callee = environment()->LookupRegister(callee_reg);
2020 
2021   CallFrequency frequency = ComputeCallFrequency(slot_id);
2022   const Operator* op = javascript()->ConstructWithSpread(
2023       static_cast<uint32_t>(reg_count + 2), frequency, feedback);
2024   int arg_count = static_cast<int>(reg_count);
2025   Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
2026                                                         first_reg, arg_count);
2027   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
2028       op, args, static_cast<int>(arg_count), feedback.slot());
2029   if (lowering.IsExit()) return;
2030 
2031   Node* node = nullptr;
2032   if (lowering.IsSideEffectFree()) {
2033     node = lowering.value();
2034   } else {
2035     DCHECK(!lowering.Changed());
2036     node = ProcessConstructArguments(op, args, 2 + arg_count);
2037   }
2038   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2039 }
2040 
VisitInvokeIntrinsic()2041 void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
2042   PrepareEagerCheckpoint();
2043   Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
2044   interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
2045   size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2046 
2047   // Create node to perform the runtime call. Turbofan will take care of the
2048   // lowering.
2049   const Operator* call = javascript()->CallRuntime(functionId, reg_count);
2050   Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
2051   environment()->BindAccumulator(value, Environment::kAttachFrameState);
2052 }
2053 
VisitThrow()2054 void BytecodeGraphBuilder::VisitThrow() {
2055   BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
2056       bytecode_iterator().current_offset()));
2057   Node* value = environment()->LookupAccumulator();
2058   Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
2059   environment()->BindAccumulator(call, Environment::kAttachFrameState);
2060   Node* control = NewNode(common()->Throw());
2061   MergeControlToLeaveFunction(control);
2062 }
2063 
VisitAbort()2064 void BytecodeGraphBuilder::VisitAbort() {
2065   BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
2066       bytecode_iterator().current_offset()));
2067   AbortReason reason =
2068       static_cast<AbortReason>(bytecode_iterator().GetIndexOperand(0));
2069   NewNode(simplified()->RuntimeAbort(reason));
2070   Node* control = NewNode(common()->Throw());
2071   MergeControlToLeaveFunction(control);
2072 }
2073 
VisitReThrow()2074 void BytecodeGraphBuilder::VisitReThrow() {
2075   BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
2076       bytecode_iterator().current_offset()));
2077   Node* value = environment()->LookupAccumulator();
2078   NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
2079   Node* control = NewNode(common()->Throw());
2080   MergeControlToLeaveFunction(control);
2081 }
2082 
BuildHoleCheckAndThrow(Node * condition,Runtime::FunctionId runtime_id,Node * name)2083 void BytecodeGraphBuilder::BuildHoleCheckAndThrow(
2084     Node* condition, Runtime::FunctionId runtime_id, Node* name) {
2085   Node* accumulator = environment()->LookupAccumulator();
2086   NewBranch(condition, BranchHint::kFalse);
2087   {
2088     SubEnvironment sub_environment(this);
2089 
2090     NewIfTrue();
2091     BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
2092         bytecode_iterator().current_offset()));
2093     Node* node;
2094     const Operator* op = javascript()->CallRuntime(runtime_id);
2095     if (runtime_id == Runtime::kThrowReferenceError) {
2096       DCHECK_NOT_NULL(name);
2097       node = NewNode(op, name);
2098     } else {
2099       DCHECK(runtime_id == Runtime::kThrowSuperAlreadyCalledError ||
2100              runtime_id == Runtime::kThrowSuperNotCalled);
2101       node = NewNode(op);
2102     }
2103     environment()->RecordAfterState(node, Environment::kAttachFrameState);
2104     Node* control = NewNode(common()->Throw());
2105     MergeControlToLeaveFunction(control);
2106   }
2107   NewIfFalse();
2108   environment()->BindAccumulator(accumulator);
2109 }
2110 
VisitThrowReferenceErrorIfHole()2111 void BytecodeGraphBuilder::VisitThrowReferenceErrorIfHole() {
2112   Node* accumulator = environment()->LookupAccumulator();
2113   Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2114                                  jsgraph()->TheHoleConstant());
2115   Node* name = jsgraph()->Constant(
2116       handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
2117   BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowReferenceError, name);
2118 }
2119 
VisitThrowSuperNotCalledIfHole()2120 void BytecodeGraphBuilder::VisitThrowSuperNotCalledIfHole() {
2121   Node* accumulator = environment()->LookupAccumulator();
2122   Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2123                                  jsgraph()->TheHoleConstant());
2124   BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowSuperNotCalled);
2125 }
2126 
VisitThrowSuperAlreadyCalledIfNotHole()2127 void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
2128   Node* accumulator = environment()->LookupAccumulator();
2129   Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2130                                  jsgraph()->TheHoleConstant());
2131   Node* check_for_not_hole =
2132       NewNode(simplified()->BooleanNot(), check_for_hole);
2133   BuildHoleCheckAndThrow(check_for_not_hole,
2134                          Runtime::kThrowSuperAlreadyCalledError);
2135 }
2136 
BuildUnaryOp(const Operator * op)2137 void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) {
2138   PrepareEagerCheckpoint();
2139   Node* operand = environment()->LookupAccumulator();
2140 
2141   FeedbackSlot slot =
2142       bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex);
2143   JSTypeHintLowering::LoweringResult lowering =
2144       TryBuildSimplifiedUnaryOp(op, operand, slot);
2145   if (lowering.IsExit()) return;
2146 
2147   Node* node = nullptr;
2148   if (lowering.IsSideEffectFree()) {
2149     node = lowering.value();
2150   } else {
2151     DCHECK(!lowering.Changed());
2152     node = NewNode(op, operand);
2153   }
2154 
2155   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2156 }
2157 
BuildBinaryOp(const Operator * op)2158 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) {
2159   PrepareEagerCheckpoint();
2160   Node* left =
2161       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2162   Node* right = environment()->LookupAccumulator();
2163 
2164   FeedbackSlot slot =
2165       bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex);
2166   JSTypeHintLowering::LoweringResult lowering =
2167       TryBuildSimplifiedBinaryOp(op, left, right, slot);
2168   if (lowering.IsExit()) return;
2169 
2170   Node* node = nullptr;
2171   if (lowering.IsSideEffectFree()) {
2172     node = lowering.value();
2173   } else {
2174     DCHECK(!lowering.Changed());
2175     node = NewNode(op, left, right);
2176   }
2177 
2178   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2179 }
2180 
2181 // Helper function to create binary operation hint from the recorded type
2182 // feedback.
GetBinaryOperationHint(int operand_index)2183 BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint(
2184     int operand_index) {
2185   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index);
2186   FeedbackNexus nexus(feedback_vector(), slot);
2187   return nexus.GetBinaryOperationFeedback();
2188 }
2189 
2190 // Helper function to create compare operation hint from the recorded type
2191 // feedback.
GetCompareOperationHint()2192 CompareOperationHint BytecodeGraphBuilder::GetCompareOperationHint() {
2193   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
2194   FeedbackNexus nexus(feedback_vector(), slot);
2195   return nexus.GetCompareOperationFeedback();
2196 }
2197 
2198 // Helper function to create for-in mode from the recorded type feedback.
GetForInMode(int operand_index)2199 ForInMode BytecodeGraphBuilder::GetForInMode(int operand_index) {
2200   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index);
2201   FeedbackNexus nexus(feedback_vector(), slot);
2202   switch (nexus.GetForInFeedback()) {
2203     case ForInHint::kNone:
2204     case ForInHint::kEnumCacheKeysAndIndices:
2205       return ForInMode::kUseEnumCacheKeysAndIndices;
2206     case ForInHint::kEnumCacheKeys:
2207       return ForInMode::kUseEnumCacheKeys;
2208     case ForInHint::kAny:
2209       return ForInMode::kGeneric;
2210   }
2211   UNREACHABLE();
2212 }
2213 
ComputeCallFrequency(int slot_id) const2214 CallFrequency BytecodeGraphBuilder::ComputeCallFrequency(int slot_id) const {
2215   if (invocation_frequency_.IsUnknown()) return CallFrequency();
2216   FeedbackNexus nexus(feedback_vector(), FeedbackVector::ToSlot(slot_id));
2217   return CallFrequency(nexus.ComputeCallFrequency() *
2218                        invocation_frequency_.value());
2219 }
2220 
GetSpeculationMode(int slot_id) const2221 SpeculationMode BytecodeGraphBuilder::GetSpeculationMode(int slot_id) const {
2222   FeedbackNexus nexus(feedback_vector(), FeedbackVector::ToSlot(slot_id));
2223   return nexus.GetSpeculationMode();
2224 }
2225 
VisitBitwiseNot()2226 void BytecodeGraphBuilder::VisitBitwiseNot() {
2227   BuildUnaryOp(javascript()->BitwiseNot());
2228 }
2229 
VisitDec()2230 void BytecodeGraphBuilder::VisitDec() {
2231   BuildUnaryOp(javascript()->Decrement());
2232 }
2233 
VisitInc()2234 void BytecodeGraphBuilder::VisitInc() {
2235   BuildUnaryOp(javascript()->Increment());
2236 }
2237 
VisitNegate()2238 void BytecodeGraphBuilder::VisitNegate() {
2239   BuildUnaryOp(javascript()->Negate());
2240 }
2241 
VisitAdd()2242 void BytecodeGraphBuilder::VisitAdd() {
2243   BuildBinaryOp(
2244       javascript()->Add(GetBinaryOperationHint(kBinaryOperationHintIndex)));
2245 }
2246 
VisitSub()2247 void BytecodeGraphBuilder::VisitSub() {
2248   BuildBinaryOp(javascript()->Subtract());
2249 }
2250 
VisitMul()2251 void BytecodeGraphBuilder::VisitMul() {
2252   BuildBinaryOp(javascript()->Multiply());
2253 }
2254 
VisitDiv()2255 void BytecodeGraphBuilder::VisitDiv() { BuildBinaryOp(javascript()->Divide()); }
2256 
VisitMod()2257 void BytecodeGraphBuilder::VisitMod() {
2258   BuildBinaryOp(javascript()->Modulus());
2259 }
2260 
VisitExp()2261 void BytecodeGraphBuilder::VisitExp() {
2262   BuildBinaryOp(javascript()->Exponentiate());
2263 }
2264 
VisitBitwiseOr()2265 void BytecodeGraphBuilder::VisitBitwiseOr() {
2266   BuildBinaryOp(javascript()->BitwiseOr());
2267 }
2268 
VisitBitwiseXor()2269 void BytecodeGraphBuilder::VisitBitwiseXor() {
2270   BuildBinaryOp(javascript()->BitwiseXor());
2271 }
2272 
VisitBitwiseAnd()2273 void BytecodeGraphBuilder::VisitBitwiseAnd() {
2274   BuildBinaryOp(javascript()->BitwiseAnd());
2275 }
2276 
VisitShiftLeft()2277 void BytecodeGraphBuilder::VisitShiftLeft() {
2278   BuildBinaryOp(javascript()->ShiftLeft());
2279 }
2280 
VisitShiftRight()2281 void BytecodeGraphBuilder::VisitShiftRight() {
2282   BuildBinaryOp(javascript()->ShiftRight());
2283 }
2284 
VisitShiftRightLogical()2285 void BytecodeGraphBuilder::VisitShiftRightLogical() {
2286   BuildBinaryOp(javascript()->ShiftRightLogical());
2287 }
2288 
BuildBinaryOpWithImmediate(const Operator * op)2289 void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) {
2290   PrepareEagerCheckpoint();
2291   Node* left = environment()->LookupAccumulator();
2292   Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
2293 
2294   FeedbackSlot slot =
2295       bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex);
2296   JSTypeHintLowering::LoweringResult lowering =
2297       TryBuildSimplifiedBinaryOp(op, left, right, slot);
2298   if (lowering.IsExit()) return;
2299 
2300   Node* node = nullptr;
2301   if (lowering.IsSideEffectFree()) {
2302     node = lowering.value();
2303   } else {
2304     DCHECK(!lowering.Changed());
2305     node = NewNode(op, left, right);
2306   }
2307   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2308 }
2309 
VisitAddSmi()2310 void BytecodeGraphBuilder::VisitAddSmi() {
2311   BuildBinaryOpWithImmediate(
2312       javascript()->Add(GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
2313 }
2314 
VisitSubSmi()2315 void BytecodeGraphBuilder::VisitSubSmi() {
2316   BuildBinaryOpWithImmediate(javascript()->Subtract());
2317 }
2318 
VisitMulSmi()2319 void BytecodeGraphBuilder::VisitMulSmi() {
2320   BuildBinaryOpWithImmediate(javascript()->Multiply());
2321 }
2322 
VisitDivSmi()2323 void BytecodeGraphBuilder::VisitDivSmi() {
2324   BuildBinaryOpWithImmediate(javascript()->Divide());
2325 }
2326 
VisitModSmi()2327 void BytecodeGraphBuilder::VisitModSmi() {
2328   BuildBinaryOpWithImmediate(javascript()->Modulus());
2329 }
2330 
VisitExpSmi()2331 void BytecodeGraphBuilder::VisitExpSmi() {
2332   BuildBinaryOpWithImmediate(javascript()->Exponentiate());
2333 }
2334 
VisitBitwiseOrSmi()2335 void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
2336   BuildBinaryOpWithImmediate(javascript()->BitwiseOr());
2337 }
2338 
VisitBitwiseXorSmi()2339 void BytecodeGraphBuilder::VisitBitwiseXorSmi() {
2340   BuildBinaryOpWithImmediate(javascript()->BitwiseXor());
2341 }
2342 
VisitBitwiseAndSmi()2343 void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
2344   BuildBinaryOpWithImmediate(javascript()->BitwiseAnd());
2345 }
2346 
VisitShiftLeftSmi()2347 void BytecodeGraphBuilder::VisitShiftLeftSmi() {
2348   BuildBinaryOpWithImmediate(javascript()->ShiftLeft());
2349 }
2350 
VisitShiftRightSmi()2351 void BytecodeGraphBuilder::VisitShiftRightSmi() {
2352   BuildBinaryOpWithImmediate(javascript()->ShiftRight());
2353 }
2354 
VisitShiftRightLogicalSmi()2355 void BytecodeGraphBuilder::VisitShiftRightLogicalSmi() {
2356   BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical());
2357 }
2358 
VisitLogicalNot()2359 void BytecodeGraphBuilder::VisitLogicalNot() {
2360   Node* value = environment()->LookupAccumulator();
2361   Node* node = NewNode(simplified()->BooleanNot(), value);
2362   environment()->BindAccumulator(node);
2363 }
2364 
VisitToBooleanLogicalNot()2365 void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
2366   Node* value =
2367       NewNode(simplified()->ToBoolean(), environment()->LookupAccumulator());
2368   Node* node = NewNode(simplified()->BooleanNot(), value);
2369   environment()->BindAccumulator(node);
2370 }
2371 
VisitTypeOf()2372 void BytecodeGraphBuilder::VisitTypeOf() {
2373   Node* node =
2374       NewNode(simplified()->TypeOf(), environment()->LookupAccumulator());
2375   environment()->BindAccumulator(node);
2376 }
2377 
BuildDelete(LanguageMode language_mode)2378 void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
2379   PrepareEagerCheckpoint();
2380   Node* key = environment()->LookupAccumulator();
2381   Node* object =
2382       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2383   Node* mode = jsgraph()->Constant(static_cast<int32_t>(language_mode));
2384   Node* node = NewNode(javascript()->DeleteProperty(), object, key, mode);
2385   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2386 }
2387 
VisitDeletePropertyStrict()2388 void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
2389   BuildDelete(LanguageMode::kStrict);
2390 }
2391 
VisitDeletePropertySloppy()2392 void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
2393   BuildDelete(LanguageMode::kSloppy);
2394 }
2395 
VisitGetSuperConstructor()2396 void BytecodeGraphBuilder::VisitGetSuperConstructor() {
2397   Node* node = NewNode(javascript()->GetSuperConstructor(),
2398                        environment()->LookupAccumulator());
2399   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
2400                               Environment::kAttachFrameState);
2401 }
2402 
BuildCompareOp(const Operator * op)2403 void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) {
2404   PrepareEagerCheckpoint();
2405   Node* left =
2406       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2407   Node* right = environment()->LookupAccumulator();
2408 
2409   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
2410   JSTypeHintLowering::LoweringResult lowering =
2411       TryBuildSimplifiedBinaryOp(op, left, right, slot);
2412   if (lowering.IsExit()) return;
2413 
2414   Node* node = nullptr;
2415   if (lowering.IsSideEffectFree()) {
2416     node = lowering.value();
2417   } else {
2418     DCHECK(!lowering.Changed());
2419     node = NewNode(op, left, right);
2420   }
2421   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2422 }
2423 
VisitTestEqual()2424 void BytecodeGraphBuilder::VisitTestEqual() {
2425   BuildCompareOp(javascript()->Equal(GetCompareOperationHint()));
2426 }
2427 
VisitTestEqualStrict()2428 void BytecodeGraphBuilder::VisitTestEqualStrict() {
2429   BuildCompareOp(javascript()->StrictEqual(GetCompareOperationHint()));
2430 }
2431 
VisitTestLessThan()2432 void BytecodeGraphBuilder::VisitTestLessThan() {
2433   BuildCompareOp(javascript()->LessThan(GetCompareOperationHint()));
2434 }
2435 
VisitTestGreaterThan()2436 void BytecodeGraphBuilder::VisitTestGreaterThan() {
2437   BuildCompareOp(javascript()->GreaterThan(GetCompareOperationHint()));
2438 }
2439 
VisitTestLessThanOrEqual()2440 void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
2441   BuildCompareOp(javascript()->LessThanOrEqual(GetCompareOperationHint()));
2442 }
2443 
VisitTestGreaterThanOrEqual()2444 void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
2445   BuildCompareOp(javascript()->GreaterThanOrEqual(GetCompareOperationHint()));
2446 }
2447 
VisitTestReferenceEqual()2448 void BytecodeGraphBuilder::VisitTestReferenceEqual() {
2449   Node* left =
2450       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2451   Node* right = environment()->LookupAccumulator();
2452   Node* result = NewNode(simplified()->ReferenceEqual(), left, right);
2453   environment()->BindAccumulator(result);
2454 }
2455 
VisitTestIn()2456 void BytecodeGraphBuilder::VisitTestIn() {
2457   PrepareEagerCheckpoint();
2458   Node* object = environment()->LookupAccumulator();
2459   Node* key =
2460       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2461   Node* node = NewNode(javascript()->HasProperty(), object, key);
2462   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2463 }
2464 
VisitTestInstanceOf()2465 void BytecodeGraphBuilder::VisitTestInstanceOf() {
2466   int const slot_index = bytecode_iterator().GetIndexOperand(1);
2467   BuildCompareOp(javascript()->InstanceOf(CreateVectorSlotPair(slot_index)));
2468 }
2469 
VisitTestUndetectable()2470 void BytecodeGraphBuilder::VisitTestUndetectable() {
2471   Node* object = environment()->LookupAccumulator();
2472   Node* node = NewNode(jsgraph()->simplified()->ObjectIsUndetectable(), object);
2473   environment()->BindAccumulator(node);
2474 }
2475 
VisitTestNull()2476 void BytecodeGraphBuilder::VisitTestNull() {
2477   Node* object = environment()->LookupAccumulator();
2478   Node* result = NewNode(simplified()->ReferenceEqual(), object,
2479                          jsgraph()->NullConstant());
2480   environment()->BindAccumulator(result);
2481 }
2482 
VisitTestUndefined()2483 void BytecodeGraphBuilder::VisitTestUndefined() {
2484   Node* object = environment()->LookupAccumulator();
2485   Node* result = NewNode(simplified()->ReferenceEqual(), object,
2486                          jsgraph()->UndefinedConstant());
2487   environment()->BindAccumulator(result);
2488 }
2489 
VisitTestTypeOf()2490 void BytecodeGraphBuilder::VisitTestTypeOf() {
2491   Node* object = environment()->LookupAccumulator();
2492   auto literal_flag = interpreter::TestTypeOfFlags::Decode(
2493       bytecode_iterator().GetFlagOperand(0));
2494   Node* result;
2495   switch (literal_flag) {
2496     case interpreter::TestTypeOfFlags::LiteralFlag::kNumber:
2497       result = NewNode(simplified()->ObjectIsNumber(), object);
2498       break;
2499     case interpreter::TestTypeOfFlags::LiteralFlag::kString:
2500       result = NewNode(simplified()->ObjectIsString(), object);
2501       break;
2502     case interpreter::TestTypeOfFlags::LiteralFlag::kSymbol:
2503       result = NewNode(simplified()->ObjectIsSymbol(), object);
2504       break;
2505     case interpreter::TestTypeOfFlags::LiteralFlag::kBigInt:
2506       result = NewNode(simplified()->ObjectIsBigInt(), object);
2507       break;
2508     case interpreter::TestTypeOfFlags::LiteralFlag::kBoolean:
2509       result = NewNode(common()->Select(MachineRepresentation::kTagged),
2510                        NewNode(simplified()->ReferenceEqual(), object,
2511                                jsgraph()->TrueConstant()),
2512                        jsgraph()->TrueConstant(),
2513                        NewNode(simplified()->ReferenceEqual(), object,
2514                                jsgraph()->FalseConstant()));
2515       break;
2516     case interpreter::TestTypeOfFlags::LiteralFlag::kUndefined:
2517       result = graph()->NewNode(
2518           common()->Select(MachineRepresentation::kTagged),
2519           graph()->NewNode(simplified()->ReferenceEqual(), object,
2520                            jsgraph()->NullConstant()),
2521           jsgraph()->FalseConstant(),
2522           graph()->NewNode(simplified()->ObjectIsUndetectable(), object));
2523       break;
2524     case interpreter::TestTypeOfFlags::LiteralFlag::kFunction:
2525       result =
2526           graph()->NewNode(simplified()->ObjectIsDetectableCallable(), object);
2527       break;
2528     case interpreter::TestTypeOfFlags::LiteralFlag::kObject:
2529       result = graph()->NewNode(
2530           common()->Select(MachineRepresentation::kTagged),
2531           graph()->NewNode(simplified()->ObjectIsNonCallable(), object),
2532           jsgraph()->TrueConstant(),
2533           graph()->NewNode(simplified()->ReferenceEqual(), object,
2534                            jsgraph()->NullConstant()));
2535       break;
2536     case interpreter::TestTypeOfFlags::LiteralFlag::kOther:
2537       UNREACHABLE();  // Should never be emitted.
2538       break;
2539   }
2540   environment()->BindAccumulator(result);
2541 }
2542 
BuildCastOperator(const Operator * js_op)2543 void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
2544   Node* value = NewNode(js_op, environment()->LookupAccumulator());
2545   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
2546                               Environment::kAttachFrameState);
2547 }
2548 
VisitToName()2549 void BytecodeGraphBuilder::VisitToName() {
2550   BuildCastOperator(javascript()->ToName());
2551 }
2552 
VisitToObject()2553 void BytecodeGraphBuilder::VisitToObject() {
2554   BuildCastOperator(javascript()->ToObject());
2555 }
2556 
VisitToString()2557 void BytecodeGraphBuilder::VisitToString() {
2558   Node* value =
2559       NewNode(javascript()->ToString(), environment()->LookupAccumulator());
2560   environment()->BindAccumulator(value, Environment::kAttachFrameState);
2561 }
2562 
VisitToNumber()2563 void BytecodeGraphBuilder::VisitToNumber() {
2564   PrepareEagerCheckpoint();
2565   Node* object = environment()->LookupAccumulator();
2566 
2567   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
2568   JSTypeHintLowering::LoweringResult lowering =
2569       TryBuildSimplifiedToNumber(object, slot);
2570 
2571   Node* node = nullptr;
2572   if (lowering.IsSideEffectFree()) {
2573     node = lowering.value();
2574   } else {
2575     DCHECK(!lowering.Changed());
2576     node = NewNode(javascript()->ToNumber(), object);
2577   }
2578 
2579   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2580 }
2581 
VisitToNumeric()2582 void BytecodeGraphBuilder::VisitToNumeric() {
2583   PrepareEagerCheckpoint();
2584   Node* object = environment()->LookupAccumulator();
2585 
2586   // If we have some kind of Number feedback, we do the same lowering as for
2587   // ToNumber.
2588   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
2589   JSTypeHintLowering::LoweringResult lowering =
2590       TryBuildSimplifiedToNumber(object, slot);
2591 
2592   Node* node = nullptr;
2593   if (lowering.IsSideEffectFree()) {
2594     node = lowering.value();
2595   } else {
2596     DCHECK(!lowering.Changed());
2597     node = NewNode(javascript()->ToNumeric(), object);
2598   }
2599 
2600   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2601 }
2602 
VisitJump()2603 void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
2604 
VisitJumpConstant()2605 void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
2606 
VisitJumpIfTrue()2607 void BytecodeGraphBuilder::VisitJumpIfTrue() { BuildJumpIfTrue(); }
2608 
VisitJumpIfTrueConstant()2609 void BytecodeGraphBuilder::VisitJumpIfTrueConstant() { BuildJumpIfTrue(); }
2610 
VisitJumpIfFalse()2611 void BytecodeGraphBuilder::VisitJumpIfFalse() { BuildJumpIfFalse(); }
2612 
VisitJumpIfFalseConstant()2613 void BytecodeGraphBuilder::VisitJumpIfFalseConstant() { BuildJumpIfFalse(); }
2614 
VisitJumpIfToBooleanTrue()2615 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
2616   BuildJumpIfToBooleanTrue();
2617 }
2618 
VisitJumpIfToBooleanTrueConstant()2619 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
2620   BuildJumpIfToBooleanTrue();
2621 }
2622 
VisitJumpIfToBooleanFalse()2623 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
2624   BuildJumpIfToBooleanFalse();
2625 }
2626 
VisitJumpIfToBooleanFalseConstant()2627 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
2628   BuildJumpIfToBooleanFalse();
2629 }
2630 
VisitJumpIfJSReceiver()2631 void BytecodeGraphBuilder::VisitJumpIfJSReceiver() { BuildJumpIfJSReceiver(); }
2632 
VisitJumpIfJSReceiverConstant()2633 void BytecodeGraphBuilder::VisitJumpIfJSReceiverConstant() {
2634   BuildJumpIfJSReceiver();
2635 }
2636 
VisitJumpIfNull()2637 void BytecodeGraphBuilder::VisitJumpIfNull() {
2638   BuildJumpIfEqual(jsgraph()->NullConstant());
2639 }
2640 
VisitJumpIfNullConstant()2641 void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
2642   BuildJumpIfEqual(jsgraph()->NullConstant());
2643 }
2644 
VisitJumpIfNotNull()2645 void BytecodeGraphBuilder::VisitJumpIfNotNull() {
2646   BuildJumpIfNotEqual(jsgraph()->NullConstant());
2647 }
2648 
VisitJumpIfNotNullConstant()2649 void BytecodeGraphBuilder::VisitJumpIfNotNullConstant() {
2650   BuildJumpIfNotEqual(jsgraph()->NullConstant());
2651 }
2652 
VisitJumpIfUndefined()2653 void BytecodeGraphBuilder::VisitJumpIfUndefined() {
2654   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
2655 }
2656 
VisitJumpIfUndefinedConstant()2657 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
2658   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
2659 }
2660 
VisitJumpIfNotUndefined()2661 void BytecodeGraphBuilder::VisitJumpIfNotUndefined() {
2662   BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
2663 }
2664 
VisitJumpIfNotUndefinedConstant()2665 void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
2666   BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
2667 }
2668 
VisitJumpLoop()2669 void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
2670 
BuildSwitchOnSmi(Node * condition)2671 void BytecodeGraphBuilder::BuildSwitchOnSmi(Node* condition) {
2672   interpreter::JumpTableTargetOffsets offsets =
2673       bytecode_iterator().GetJumpTableTargetOffsets();
2674 
2675   NewSwitch(condition, offsets.size() + 1);
2676   for (const auto& entry : offsets) {
2677     SubEnvironment sub_environment(this);
2678     NewIfValue(entry.case_value);
2679     MergeIntoSuccessorEnvironment(entry.target_offset);
2680   }
2681   NewIfDefault();
2682 }
2683 
VisitSwitchOnSmiNoFeedback()2684 void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
2685   PrepareEagerCheckpoint();
2686 
2687   Node* acc = environment()->LookupAccumulator();
2688   Node* acc_smi = NewNode(simplified()->CheckSmi(VectorSlotPair()), acc);
2689   BuildSwitchOnSmi(acc_smi);
2690 }
2691 
VisitStackCheck()2692 void BytecodeGraphBuilder::VisitStackCheck() {
2693   PrepareEagerCheckpoint();
2694   Node* node = NewNode(javascript()->StackCheck());
2695   environment()->RecordAfterState(node, Environment::kAttachFrameState);
2696 }
2697 
VisitSetPendingMessage()2698 void BytecodeGraphBuilder::VisitSetPendingMessage() {
2699   Node* previous_message = NewNode(javascript()->LoadMessage());
2700   NewNode(javascript()->StoreMessage(), environment()->LookupAccumulator());
2701   environment()->BindAccumulator(previous_message);
2702 }
2703 
BuildReturn(const BytecodeLivenessState * liveness)2704 void BytecodeGraphBuilder::BuildReturn(const BytecodeLivenessState* liveness) {
2705   BuildLoopExitsForFunctionExit(liveness);
2706   Node* pop_node = jsgraph()->ZeroConstant();
2707   Node* control =
2708       NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
2709   MergeControlToLeaveFunction(control);
2710 }
2711 
VisitReturn()2712 void BytecodeGraphBuilder::VisitReturn() {
2713   BuildReturn(bytecode_analysis()->GetInLivenessFor(
2714       bytecode_iterator().current_offset()));
2715 }
2716 
VisitDebugger()2717 void BytecodeGraphBuilder::VisitDebugger() {
2718   PrepareEagerCheckpoint();
2719   Node* call = NewNode(javascript()->Debugger());
2720   environment()->RecordAfterState(call, Environment::kAttachFrameState);
2721 }
2722 
2723 // We cannot create a graph from the debugger copy of the bytecode array.
2724 #define DEBUG_BREAK(Name, ...) \
2725   void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
2726 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
2727 #undef DEBUG_BREAK
2728 
VisitIncBlockCounter()2729 void BytecodeGraphBuilder::VisitIncBlockCounter() {
2730   Node* closure = GetFunctionClosure();
2731   Node* coverage_array_slot =
2732       jsgraph()->Constant(bytecode_iterator().GetIndexOperand(0));
2733 
2734   const Operator* op = javascript()->CallRuntime(Runtime::kIncBlockCounter);
2735 
2736   NewNode(op, closure, coverage_array_slot);
2737 }
2738 
VisitForInEnumerate()2739 void BytecodeGraphBuilder::VisitForInEnumerate() {
2740   Node* receiver =
2741       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2742   Node* enumerator = NewNode(javascript()->ForInEnumerate(), receiver);
2743   environment()->BindAccumulator(enumerator, Environment::kAttachFrameState);
2744 }
2745 
VisitForInPrepare()2746 void BytecodeGraphBuilder::VisitForInPrepare() {
2747   PrepareEagerCheckpoint();
2748   Node* enumerator = environment()->LookupAccumulator();
2749 
2750   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
2751   JSTypeHintLowering::LoweringResult lowering =
2752       TryBuildSimplifiedForInPrepare(enumerator, slot);
2753   if (lowering.IsExit()) return;
2754   DCHECK(!lowering.Changed());
2755   Node* node = NewNode(javascript()->ForInPrepare(GetForInMode(1)), enumerator);
2756   environment()->BindRegistersToProjections(
2757       bytecode_iterator().GetRegisterOperand(0), node);
2758 }
2759 
VisitForInContinue()2760 void BytecodeGraphBuilder::VisitForInContinue() {
2761   PrepareEagerCheckpoint();
2762   Node* index =
2763       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2764   Node* cache_length =
2765       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2766   Node* exit_cond = NewNode(simplified()->SpeculativeNumberLessThan(
2767                                 NumberOperationHint::kSignedSmall),
2768                             index, cache_length);
2769   environment()->BindAccumulator(exit_cond);
2770 }
2771 
VisitForInNext()2772 void BytecodeGraphBuilder::VisitForInNext() {
2773   PrepareEagerCheckpoint();
2774   Node* receiver =
2775       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2776   Node* index =
2777       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2778   int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
2779   Node* cache_type = environment()->LookupRegister(
2780       interpreter::Register(catch_reg_pair_index));
2781   Node* cache_array = environment()->LookupRegister(
2782       interpreter::Register(catch_reg_pair_index + 1));
2783 
2784   // We need to rename the {index} here, as in case of OSR we loose the
2785   // information that the {index} is always a valid unsigned Smi value.
2786   index = graph()->NewNode(common()->TypeGuard(Type::UnsignedSmall()), index,
2787                            environment()->GetEffectDependency(),
2788                            environment()->GetControlDependency());
2789   environment()->UpdateEffectDependency(index);
2790 
2791   FeedbackSlot slot = bytecode_iterator().GetSlotOperand(3);
2792   JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedForInNext(
2793       receiver, cache_array, cache_type, index, slot);
2794   if (lowering.IsExit()) return;
2795 
2796   DCHECK(!lowering.Changed());
2797   Node* node = NewNode(javascript()->ForInNext(GetForInMode(3)), receiver,
2798                        cache_array, cache_type, index);
2799   environment()->BindAccumulator(node, Environment::kAttachFrameState);
2800 }
2801 
VisitForInStep()2802 void BytecodeGraphBuilder::VisitForInStep() {
2803   PrepareEagerCheckpoint();
2804   Node* index =
2805       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2806   index = NewNode(simplified()->SpeculativeSafeIntegerAdd(
2807                       NumberOperationHint::kSignedSmall),
2808                   index, jsgraph()->OneConstant());
2809   environment()->BindAccumulator(index, Environment::kAttachFrameState);
2810 }
2811 
VisitSuspendGenerator()2812 void BytecodeGraphBuilder::VisitSuspendGenerator() {
2813   Node* generator = environment()->LookupRegister(
2814       bytecode_iterator().GetRegisterOperand(0));
2815   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2816   // We assume we are storing a range starting from index 0.
2817   CHECK_EQ(0, first_reg.index());
2818   int register_count =
2819       static_cast<int>(bytecode_iterator().GetRegisterCountOperand(2));
2820   int parameter_count_without_receiver =
2821       bytecode_array()->parameter_count() - 1;
2822 
2823   Node* suspend_id = jsgraph()->SmiConstant(
2824       bytecode_iterator().GetUnsignedImmediateOperand(3));
2825 
2826   // The offsets used by the bytecode iterator are relative to a different base
2827   // than what is used in the interpreter, hence the addition.
2828   Node* offset =
2829       jsgraph()->Constant(bytecode_iterator().current_offset() +
2830                           (BytecodeArray::kHeaderSize - kHeapObjectTag));
2831 
2832   const BytecodeLivenessState* liveness = bytecode_analysis()->GetInLivenessFor(
2833       bytecode_iterator().current_offset());
2834 
2835   // Maybe overallocate the value list since we don't know how many registers
2836   // are live.
2837   // TODO(leszeks): We could get this count from liveness rather than the
2838   // register list.
2839   int value_input_count = 3 + parameter_count_without_receiver + register_count;
2840 
2841   Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
2842   value_inputs[0] = generator;
2843   value_inputs[1] = suspend_id;
2844   value_inputs[2] = offset;
2845 
2846   int count_written = 0;
2847   // Store the parameters.
2848   for (int i = 0; i < parameter_count_without_receiver; i++) {
2849     value_inputs[3 + count_written++] =
2850         environment()->LookupRegister(interpreter::Register::FromParameterIndex(
2851             i, parameter_count_without_receiver));
2852   }
2853 
2854   // Store the registers.
2855   for (int i = 0; i < register_count; ++i) {
2856     if (liveness == nullptr || liveness->RegisterIsLive(i)) {
2857       int index_in_parameters_and_registers =
2858           parameter_count_without_receiver + i;
2859       while (count_written < index_in_parameters_and_registers) {
2860         value_inputs[3 + count_written++] = jsgraph()->OptimizedOutConstant();
2861       }
2862       value_inputs[3 + count_written++] =
2863           environment()->LookupRegister(interpreter::Register(i));
2864       DCHECK_EQ(count_written, index_in_parameters_and_registers + 1);
2865     }
2866   }
2867 
2868   // Use the actual written count rather than the register count to create the
2869   // node.
2870   MakeNode(javascript()->GeneratorStore(count_written), 3 + count_written,
2871            value_inputs, false);
2872 
2873   // TODO(leszeks): This over-approximates the liveness at exit, only the
2874   // accumulator should be live by this point.
2875   BuildReturn(bytecode_analysis()->GetInLivenessFor(
2876       bytecode_iterator().current_offset()));
2877 }
2878 
BuildSwitchOnGeneratorState(const ZoneVector<ResumeJumpTarget> & resume_jump_targets,bool allow_fallthrough_on_executing)2879 void BytecodeGraphBuilder::BuildSwitchOnGeneratorState(
2880     const ZoneVector<ResumeJumpTarget>& resume_jump_targets,
2881     bool allow_fallthrough_on_executing) {
2882   Node* generator_state = environment()->LookupGeneratorState();
2883 
2884   int extra_cases = allow_fallthrough_on_executing ? 2 : 1;
2885   NewSwitch(generator_state,
2886             static_cast<int>(resume_jump_targets.size() + extra_cases));
2887   for (const ResumeJumpTarget& target : resume_jump_targets) {
2888     SubEnvironment sub_environment(this);
2889     NewIfValue(target.suspend_id());
2890     if (target.is_leaf()) {
2891       // Mark that we are resuming executing.
2892       environment()->BindGeneratorState(
2893           jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
2894     }
2895     // Jump to the target offset, whether it's a loop header or the resume.
2896     MergeIntoSuccessorEnvironment(target.target_offset());
2897   }
2898 
2899   {
2900     SubEnvironment sub_environment(this);
2901     // We should never hit the default case (assuming generator state cannot be
2902     // corrupted), so abort if we do.
2903     // TODO(leszeks): Maybe only check this in debug mode, and otherwise use
2904     // the default to represent one of the cases above/fallthrough below?
2905     NewIfDefault();
2906     NewNode(simplified()->RuntimeAbort(AbortReason::kInvalidJumpTableIndex));
2907     // TODO(7099): Investigate if we need LoopExit here.
2908     Node* control = NewNode(common()->Throw());
2909     MergeControlToLeaveFunction(control);
2910   }
2911 
2912   if (allow_fallthrough_on_executing) {
2913     // If we are executing (rather than resuming), and we allow it, just fall
2914     // through to the actual loop body.
2915     NewIfValue(JSGeneratorObject::kGeneratorExecuting);
2916   } else {
2917     // Otherwise, this environment is dead.
2918     set_environment(nullptr);
2919   }
2920 }
2921 
VisitSwitchOnGeneratorState()2922 void BytecodeGraphBuilder::VisitSwitchOnGeneratorState() {
2923   Node* generator =
2924       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2925 
2926   Node* generator_is_undefined =
2927       NewNode(simplified()->ReferenceEqual(), generator,
2928               jsgraph()->UndefinedConstant());
2929 
2930   NewBranch(generator_is_undefined);
2931   {
2932     SubEnvironment resume_env(this);
2933     NewIfFalse();
2934 
2935     Node* generator_state =
2936         NewNode(javascript()->GeneratorRestoreContinuation(), generator);
2937     environment()->BindGeneratorState(generator_state);
2938 
2939     Node* generator_context =
2940         NewNode(javascript()->GeneratorRestoreContext(), generator);
2941     environment()->SetContext(generator_context);
2942 
2943     BuildSwitchOnGeneratorState(bytecode_analysis()->resume_jump_targets(),
2944                                 false);
2945   }
2946 
2947   // Fallthrough for the first-call case.
2948   NewIfTrue();
2949 }
2950 
VisitResumeGenerator()2951 void BytecodeGraphBuilder::VisitResumeGenerator() {
2952   Node* generator =
2953       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2954   interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2955   // We assume we are restoring registers starting fromm index 0.
2956   CHECK_EQ(0, first_reg.index());
2957 
2958   const BytecodeLivenessState* liveness =
2959       bytecode_analysis()->GetOutLivenessFor(
2960           bytecode_iterator().current_offset());
2961 
2962   int parameter_count_without_receiver =
2963       bytecode_array()->parameter_count() - 1;
2964 
2965   // Mapping between registers and array indices must match that used in
2966   // InterpreterAssembler::ExportParametersAndRegisterFile.
2967   for (int i = 0; i < environment()->register_count(); ++i) {
2968     if (liveness == nullptr || liveness->RegisterIsLive(i)) {
2969       Node* value = NewNode(javascript()->GeneratorRestoreRegister(
2970                                 parameter_count_without_receiver + i),
2971                             generator);
2972       environment()->BindRegister(interpreter::Register(i), value);
2973     }
2974   }
2975 
2976   // Update the accumulator with the generator's input_or_debug_pos.
2977   Node* input_or_debug_pos =
2978       NewNode(javascript()->GeneratorRestoreInputOrDebugPos(), generator);
2979   environment()->BindAccumulator(input_or_debug_pos);
2980 }
2981 
VisitWide()2982 void BytecodeGraphBuilder::VisitWide() {
2983   // Consumed by the BytecodeArrayIterator.
2984   UNREACHABLE();
2985 }
2986 
VisitExtraWide()2987 void BytecodeGraphBuilder::VisitExtraWide() {
2988   // Consumed by the BytecodeArrayIterator.
2989   UNREACHABLE();
2990 }
2991 
VisitIllegal()2992 void BytecodeGraphBuilder::VisitIllegal() {
2993   // Not emitted in valid bytecode.
2994   UNREACHABLE();
2995 }
2996 
SwitchToMergeEnvironment(int current_offset)2997 void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
2998   auto it = merge_environments_.find(current_offset);
2999   if (it != merge_environments_.end()) {
3000     mark_as_needing_eager_checkpoint(true);
3001     if (environment() != nullptr) {
3002       it->second->Merge(environment(),
3003                         bytecode_analysis()->GetInLivenessFor(current_offset));
3004     }
3005     set_environment(it->second);
3006   }
3007 }
3008 
BuildLoopHeaderEnvironment(int current_offset)3009 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
3010   if (bytecode_analysis()->IsLoopHeader(current_offset)) {
3011     mark_as_needing_eager_checkpoint(true);
3012     const LoopInfo& loop_info =
3013         bytecode_analysis()->GetLoopInfoFor(current_offset);
3014     const BytecodeLivenessState* liveness =
3015         bytecode_analysis()->GetInLivenessFor(current_offset);
3016 
3017     const auto& resume_jump_targets = loop_info.resume_jump_targets();
3018     bool generate_suspend_switch = !resume_jump_targets.empty();
3019 
3020     // Add loop header.
3021     environment()->PrepareForLoop(loop_info.assignments(), liveness);
3022 
3023     // Store a copy of the environment so we can connect merged back edge inputs
3024     // to the loop header.
3025     merge_environments_[current_offset] = environment()->Copy();
3026 
3027     // If this loop contains resumes, create a new switch just after the loop
3028     // for those resumes.
3029     if (generate_suspend_switch) {
3030       BuildSwitchOnGeneratorState(loop_info.resume_jump_targets(), true);
3031 
3032       // TODO(leszeks): At this point we know we are executing rather than
3033       // resuming, so we should be able to prune off the phis in the environment
3034       // related to the resume path.
3035 
3036       // Set the generator state to a known constant.
3037       environment()->BindGeneratorState(
3038           jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
3039     }
3040   }
3041 }
3042 
MergeIntoSuccessorEnvironment(int target_offset)3043 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
3044   BuildLoopExitsForBranch(target_offset);
3045   Environment*& merge_environment = merge_environments_[target_offset];
3046 
3047   if (merge_environment == nullptr) {
3048     // Append merge nodes to the environment. We may merge here with another
3049     // environment. So add a place holder for merge nodes. We may add redundant
3050     // but will be eliminated in a later pass.
3051     // TODO(mstarzinger): Be smarter about this!
3052     NewMerge();
3053     merge_environment = environment();
3054   } else {
3055     // Merge any values which are live coming into the successor.
3056     merge_environment->Merge(
3057         environment(), bytecode_analysis()->GetInLivenessFor(target_offset));
3058   }
3059   set_environment(nullptr);
3060 }
3061 
MergeControlToLeaveFunction(Node * exit)3062 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
3063   exit_controls_.push_back(exit);
3064   set_environment(nullptr);
3065 }
3066 
BuildLoopExitsForBranch(int target_offset)3067 void BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
3068   int origin_offset = bytecode_iterator().current_offset();
3069   // Only build loop exits for forward edges.
3070   if (target_offset > origin_offset) {
3071     BuildLoopExitsUntilLoop(
3072         bytecode_analysis()->GetLoopOffsetFor(target_offset),
3073         bytecode_analysis()->GetInLivenessFor(target_offset));
3074   }
3075 }
3076 
BuildLoopExitsUntilLoop(int loop_offset,const BytecodeLivenessState * liveness)3077 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(
3078     int loop_offset, const BytecodeLivenessState* liveness) {
3079   int origin_offset = bytecode_iterator().current_offset();
3080   int current_loop = bytecode_analysis()->GetLoopOffsetFor(origin_offset);
3081   // The limit_offset is the stop offset for building loop exists, used for OSR.
3082   // It prevents the creations of loopexits for loops which do not exist.
3083   loop_offset = std::max(loop_offset, currently_peeled_loop_offset_);
3084 
3085   while (loop_offset < current_loop) {
3086     Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
3087     const LoopInfo& loop_info =
3088         bytecode_analysis()->GetLoopInfoFor(current_loop);
3089     environment()->PrepareForLoopExit(loop_node, loop_info.assignments(),
3090                                       liveness);
3091     current_loop = loop_info.parent_offset();
3092   }
3093 }
3094 
BuildLoopExitsForFunctionExit(const BytecodeLivenessState * liveness)3095 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit(
3096     const BytecodeLivenessState* liveness) {
3097   BuildLoopExitsUntilLoop(-1, liveness);
3098 }
3099 
BuildJump()3100 void BytecodeGraphBuilder::BuildJump() {
3101   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3102 }
3103 
BuildJumpIf(Node * condition)3104 void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
3105   NewBranch(condition, BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck);
3106   {
3107     SubEnvironment sub_environment(this);
3108     NewIfTrue();
3109     MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3110   }
3111   NewIfFalse();
3112 }
3113 
BuildJumpIfNot(Node * condition)3114 void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
3115   NewBranch(condition, BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck);
3116   {
3117     SubEnvironment sub_environment(this);
3118     NewIfFalse();
3119     MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3120   }
3121   NewIfTrue();
3122 }
3123 
BuildJumpIfEqual(Node * comperand)3124 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
3125   Node* accumulator = environment()->LookupAccumulator();
3126   Node* condition =
3127       NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
3128   BuildJumpIf(condition);
3129 }
3130 
BuildJumpIfNotEqual(Node * comperand)3131 void BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
3132   Node* accumulator = environment()->LookupAccumulator();
3133   Node* condition =
3134       NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
3135   BuildJumpIfNot(condition);
3136 }
3137 
BuildJumpIfFalse()3138 void BytecodeGraphBuilder::BuildJumpIfFalse() {
3139   NewBranch(environment()->LookupAccumulator(), BranchHint::kNone,
3140             IsSafetyCheck::kNoSafetyCheck);
3141   {
3142     SubEnvironment sub_environment(this);
3143     NewIfFalse();
3144     environment()->BindAccumulator(jsgraph()->FalseConstant());
3145     MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3146   }
3147   NewIfTrue();
3148   environment()->BindAccumulator(jsgraph()->TrueConstant());
3149 }
3150 
BuildJumpIfTrue()3151 void BytecodeGraphBuilder::BuildJumpIfTrue() {
3152   NewBranch(environment()->LookupAccumulator(), BranchHint::kNone,
3153             IsSafetyCheck::kNoSafetyCheck);
3154   {
3155     SubEnvironment sub_environment(this);
3156     NewIfTrue();
3157     environment()->BindAccumulator(jsgraph()->TrueConstant());
3158     MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3159   }
3160   NewIfFalse();
3161   environment()->BindAccumulator(jsgraph()->FalseConstant());
3162 }
3163 
BuildJumpIfToBooleanTrue()3164 void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
3165   Node* accumulator = environment()->LookupAccumulator();
3166   Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
3167   BuildJumpIf(condition);
3168 }
3169 
BuildJumpIfToBooleanFalse()3170 void BytecodeGraphBuilder::BuildJumpIfToBooleanFalse() {
3171   Node* accumulator = environment()->LookupAccumulator();
3172   Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
3173   BuildJumpIfNot(condition);
3174 }
3175 
BuildJumpIfNotHole()3176 void BytecodeGraphBuilder::BuildJumpIfNotHole() {
3177   Node* accumulator = environment()->LookupAccumulator();
3178   Node* condition = NewNode(simplified()->ReferenceEqual(), accumulator,
3179                             jsgraph()->TheHoleConstant());
3180   BuildJumpIfNot(condition);
3181 }
3182 
BuildJumpIfJSReceiver()3183 void BytecodeGraphBuilder::BuildJumpIfJSReceiver() {
3184   Node* accumulator = environment()->LookupAccumulator();
3185   Node* condition = NewNode(simplified()->ObjectIsReceiver(), accumulator);
3186   BuildJumpIf(condition);
3187 }
3188 
3189 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedUnaryOp(const Operator * op,Node * operand,FeedbackSlot slot)3190 BytecodeGraphBuilder::TryBuildSimplifiedUnaryOp(const Operator* op,
3191                                                 Node* operand,
3192                                                 FeedbackSlot slot) {
3193   Node* effect = environment()->GetEffectDependency();
3194   Node* control = environment()->GetControlDependency();
3195   JSTypeHintLowering::LoweringResult result =
3196       type_hint_lowering().ReduceUnaryOperation(op, operand, effect, control,
3197                                                 slot);
3198   ApplyEarlyReduction(result);
3199   return result;
3200 }
3201 
3202 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedBinaryOp(const Operator * op,Node * left,Node * right,FeedbackSlot slot)3203 BytecodeGraphBuilder::TryBuildSimplifiedBinaryOp(const Operator* op, Node* left,
3204                                                  Node* right,
3205                                                  FeedbackSlot slot) {
3206   Node* effect = environment()->GetEffectDependency();
3207   Node* control = environment()->GetControlDependency();
3208   JSTypeHintLowering::LoweringResult result =
3209       type_hint_lowering().ReduceBinaryOperation(op, left, right, effect,
3210                                                  control, slot);
3211   ApplyEarlyReduction(result);
3212   return result;
3213 }
3214 
3215 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedForInNext(Node * receiver,Node * cache_array,Node * cache_type,Node * index,FeedbackSlot slot)3216 BytecodeGraphBuilder::TryBuildSimplifiedForInNext(Node* receiver,
3217                                                   Node* cache_array,
3218                                                   Node* cache_type, Node* index,
3219                                                   FeedbackSlot slot) {
3220   Node* effect = environment()->GetEffectDependency();
3221   Node* control = environment()->GetControlDependency();
3222   JSTypeHintLowering::LoweringResult result =
3223       type_hint_lowering().ReduceForInNextOperation(
3224           receiver, cache_array, cache_type, index, effect, control, slot);
3225   ApplyEarlyReduction(result);
3226   return result;
3227 }
3228 
3229 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedForInPrepare(Node * enumerator,FeedbackSlot slot)3230 BytecodeGraphBuilder::TryBuildSimplifiedForInPrepare(Node* enumerator,
3231                                                      FeedbackSlot slot) {
3232   Node* effect = environment()->GetEffectDependency();
3233   Node* control = environment()->GetControlDependency();
3234   JSTypeHintLowering::LoweringResult result =
3235       type_hint_lowering().ReduceForInPrepareOperation(enumerator, effect,
3236                                                        control, slot);
3237   ApplyEarlyReduction(result);
3238   return result;
3239 }
3240 
3241 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedToNumber(Node * value,FeedbackSlot slot)3242 BytecodeGraphBuilder::TryBuildSimplifiedToNumber(Node* value,
3243                                                  FeedbackSlot slot) {
3244   Node* effect = environment()->GetEffectDependency();
3245   Node* control = environment()->GetControlDependency();
3246   JSTypeHintLowering::LoweringResult result =
3247       type_hint_lowering().ReduceToNumberOperation(value, effect, control,
3248                                                    slot);
3249   ApplyEarlyReduction(result);
3250   return result;
3251 }
3252 
TryBuildSimplifiedCall(const Operator * op,Node * const * args,int arg_count,FeedbackSlot slot)3253 JSTypeHintLowering::LoweringResult BytecodeGraphBuilder::TryBuildSimplifiedCall(
3254     const Operator* op, Node* const* args, int arg_count, FeedbackSlot slot) {
3255   Node* effect = environment()->GetEffectDependency();
3256   Node* control = environment()->GetControlDependency();
3257   JSTypeHintLowering::LoweringResult result =
3258       type_hint_lowering().ReduceCallOperation(op, args, arg_count, effect,
3259                                                control, slot);
3260   ApplyEarlyReduction(result);
3261   return result;
3262 }
3263 
3264 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedConstruct(const Operator * op,Node * const * args,int arg_count,FeedbackSlot slot)3265 BytecodeGraphBuilder::TryBuildSimplifiedConstruct(const Operator* op,
3266                                                   Node* const* args,
3267                                                   int arg_count,
3268                                                   FeedbackSlot slot) {
3269   Node* effect = environment()->GetEffectDependency();
3270   Node* control = environment()->GetControlDependency();
3271   JSTypeHintLowering::LoweringResult result =
3272       type_hint_lowering().ReduceConstructOperation(op, args, arg_count, effect,
3273                                                     control, slot);
3274   ApplyEarlyReduction(result);
3275   return result;
3276 }
3277 
3278 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedLoadNamed(const Operator * op,Node * receiver,FeedbackSlot slot)3279 BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op,
3280                                                   Node* receiver,
3281                                                   FeedbackSlot slot) {
3282   Node* effect = environment()->GetEffectDependency();
3283   Node* control = environment()->GetControlDependency();
3284   JSTypeHintLowering::LoweringResult early_reduction =
3285       type_hint_lowering().ReduceLoadNamedOperation(op, receiver, effect,
3286                                                     control, slot);
3287   ApplyEarlyReduction(early_reduction);
3288   return early_reduction;
3289 }
3290 
3291 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedLoadKeyed(const Operator * op,Node * receiver,Node * key,FeedbackSlot slot)3292 BytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(const Operator* op,
3293                                                   Node* receiver, Node* key,
3294                                                   FeedbackSlot slot) {
3295   Node* effect = environment()->GetEffectDependency();
3296   Node* control = environment()->GetControlDependency();
3297   JSTypeHintLowering::LoweringResult result =
3298       type_hint_lowering().ReduceLoadKeyedOperation(op, receiver, key, effect,
3299                                                     control, slot);
3300   ApplyEarlyReduction(result);
3301   return result;
3302 }
3303 
3304 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedStoreNamed(const Operator * op,Node * receiver,Node * value,FeedbackSlot slot)3305 BytecodeGraphBuilder::TryBuildSimplifiedStoreNamed(const Operator* op,
3306                                                    Node* receiver, Node* value,
3307                                                    FeedbackSlot slot) {
3308   Node* effect = environment()->GetEffectDependency();
3309   Node* control = environment()->GetControlDependency();
3310   JSTypeHintLowering::LoweringResult result =
3311       type_hint_lowering().ReduceStoreNamedOperation(op, receiver, value,
3312                                                      effect, control, slot);
3313   ApplyEarlyReduction(result);
3314   return result;
3315 }
3316 
3317 JSTypeHintLowering::LoweringResult
TryBuildSimplifiedStoreKeyed(const Operator * op,Node * receiver,Node * key,Node * value,FeedbackSlot slot)3318 BytecodeGraphBuilder::TryBuildSimplifiedStoreKeyed(const Operator* op,
3319                                                    Node* receiver, Node* key,
3320                                                    Node* value,
3321                                                    FeedbackSlot slot) {
3322   Node* effect = environment()->GetEffectDependency();
3323   Node* control = environment()->GetControlDependency();
3324   JSTypeHintLowering::LoweringResult result =
3325       type_hint_lowering().ReduceStoreKeyedOperation(op, receiver, key, value,
3326                                                      effect, control, slot);
3327   ApplyEarlyReduction(result);
3328   return result;
3329 }
3330 
ApplyEarlyReduction(JSTypeHintLowering::LoweringResult reduction)3331 void BytecodeGraphBuilder::ApplyEarlyReduction(
3332     JSTypeHintLowering::LoweringResult reduction) {
3333   if (reduction.IsExit()) {
3334     MergeControlToLeaveFunction(reduction.control());
3335   } else if (reduction.IsSideEffectFree()) {
3336     environment()->UpdateEffectDependency(reduction.effect());
3337     environment()->UpdateControlDependency(reduction.control());
3338   } else {
3339     DCHECK(!reduction.Changed());
3340     // At the moment, we assume side-effect free reduction. To support
3341     // side-effects, we would have to invalidate the eager checkpoint,
3342     // so that deoptimization does not repeat the side effect.
3343   }
3344 }
3345 
EnsureInputBufferSize(int size)3346 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
3347   if (size > input_buffer_size_) {
3348     size = size + kInputBufferSizeIncrement + input_buffer_size_;
3349     input_buffer_ = local_zone()->NewArray<Node*>(size);
3350     input_buffer_size_ = size;
3351   }
3352   return input_buffer_;
3353 }
3354 
ExitThenEnterExceptionHandlers(int current_offset)3355 void BytecodeGraphBuilder::ExitThenEnterExceptionHandlers(int current_offset) {
3356   HandlerTable table(*bytecode_array());
3357 
3358   // Potentially exit exception handlers.
3359   while (!exception_handlers_.empty()) {
3360     int current_end = exception_handlers_.top().end_offset_;
3361     if (current_offset < current_end) break;  // Still covered by range.
3362     exception_handlers_.pop();
3363   }
3364 
3365   // Potentially enter exception handlers.
3366   int num_entries = table.NumberOfRangeEntries();
3367   while (current_exception_handler_ < num_entries) {
3368     int next_start = table.GetRangeStart(current_exception_handler_);
3369     if (current_offset < next_start) break;  // Not yet covered by range.
3370     int next_end = table.GetRangeEnd(current_exception_handler_);
3371     int next_handler = table.GetRangeHandler(current_exception_handler_);
3372     int context_register = table.GetRangeData(current_exception_handler_);
3373     exception_handlers_.push(
3374         {next_start, next_end, next_handler, context_register});
3375     current_exception_handler_++;
3376   }
3377 }
3378 
MakeNode(const Operator * op,int value_input_count,Node * const * value_inputs,bool incomplete)3379 Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
3380                                      Node* const* value_inputs,
3381                                      bool incomplete) {
3382   DCHECK_EQ(op->ValueInputCount(), value_input_count);
3383 
3384   bool has_context = OperatorProperties::HasContextInput(op);
3385   bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
3386   bool has_control = op->ControlInputCount() == 1;
3387   bool has_effect = op->EffectInputCount() == 1;
3388 
3389   DCHECK_LT(op->ControlInputCount(), 2);
3390   DCHECK_LT(op->EffectInputCount(), 2);
3391 
3392   Node* result = nullptr;
3393   if (!has_context && !has_frame_state && !has_control && !has_effect) {
3394     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
3395   } else {
3396     bool inside_handler = !exception_handlers_.empty();
3397     int input_count_with_deps = value_input_count;
3398     if (has_context) ++input_count_with_deps;
3399     if (has_frame_state) ++input_count_with_deps;
3400     if (has_control) ++input_count_with_deps;
3401     if (has_effect) ++input_count_with_deps;
3402     Node** buffer = EnsureInputBufferSize(input_count_with_deps);
3403     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
3404     Node** current_input = buffer + value_input_count;
3405     if (has_context) {
3406       *current_input++ = environment()->Context();
3407     }
3408     if (has_frame_state) {
3409       // The frame state will be inserted later. Here we misuse the {Dead} node
3410       // as a sentinel to be later overwritten with the real frame state by the
3411       // calls to {PrepareFrameState} within individual visitor methods.
3412       *current_input++ = jsgraph()->Dead();
3413     }
3414     if (has_effect) {
3415       *current_input++ = environment()->GetEffectDependency();
3416     }
3417     if (has_control) {
3418       *current_input++ = environment()->GetControlDependency();
3419     }
3420     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
3421     // Update the current control dependency for control-producing nodes.
3422     if (result->op()->ControlOutputCount() > 0) {
3423       environment()->UpdateControlDependency(result);
3424     }
3425     // Update the current effect dependency for effect-producing nodes.
3426     if (result->op()->EffectOutputCount() > 0) {
3427       environment()->UpdateEffectDependency(result);
3428     }
3429     // Add implicit exception continuation for throwing nodes.
3430     if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
3431       int handler_offset = exception_handlers_.top().handler_offset_;
3432       int context_index = exception_handlers_.top().context_register_;
3433       interpreter::Register context_register(context_index);
3434       Environment* success_env = environment()->Copy();
3435       const Operator* op = common()->IfException();
3436       Node* effect = environment()->GetEffectDependency();
3437       Node* on_exception = graph()->NewNode(op, effect, result);
3438       Node* context = environment()->LookupRegister(context_register);
3439       environment()->UpdateControlDependency(on_exception);
3440       environment()->UpdateEffectDependency(on_exception);
3441       environment()->BindAccumulator(on_exception);
3442       environment()->SetContext(context);
3443       MergeIntoSuccessorEnvironment(handler_offset);
3444       set_environment(success_env);
3445     }
3446     // Add implicit success continuation for throwing nodes.
3447     if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
3448       const Operator* if_success = common()->IfSuccess();
3449       Node* on_success = graph()->NewNode(if_success, result);
3450       environment()->UpdateControlDependency(on_success);
3451     }
3452     // Ensure checkpoints are created after operations with side-effects.
3453     if (has_effect && !result->op()->HasProperty(Operator::kNoWrite)) {
3454       mark_as_needing_eager_checkpoint(true);
3455     }
3456   }
3457 
3458   return result;
3459 }
3460 
3461 
NewPhi(int count,Node * input,Node * control)3462 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
3463   const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
3464   Node** buffer = EnsureInputBufferSize(count + 1);
3465   MemsetPointer(buffer, input, count);
3466   buffer[count] = control;
3467   return graph()->NewNode(phi_op, count + 1, buffer, true);
3468 }
3469 
NewEffectPhi(int count,Node * input,Node * control)3470 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
3471                                          Node* control) {
3472   const Operator* phi_op = common()->EffectPhi(count);
3473   Node** buffer = EnsureInputBufferSize(count + 1);
3474   MemsetPointer(buffer, input, count);
3475   buffer[count] = control;
3476   return graph()->NewNode(phi_op, count + 1, buffer, true);
3477 }
3478 
3479 
MergeControl(Node * control,Node * other)3480 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
3481   int inputs = control->op()->ControlInputCount() + 1;
3482   if (control->opcode() == IrOpcode::kLoop) {
3483     // Control node for loop exists, add input.
3484     const Operator* op = common()->Loop(inputs);
3485     control->AppendInput(graph_zone(), other);
3486     NodeProperties::ChangeOp(control, op);
3487   } else if (control->opcode() == IrOpcode::kMerge) {
3488     // Control node for merge exists, add input.
3489     const Operator* op = common()->Merge(inputs);
3490     control->AppendInput(graph_zone(), other);
3491     NodeProperties::ChangeOp(control, op);
3492   } else {
3493     // Control node is a singleton, introduce a merge.
3494     const Operator* op = common()->Merge(inputs);
3495     Node* merge_inputs[] = {control, other};
3496     control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
3497   }
3498   return control;
3499 }
3500 
MergeEffect(Node * value,Node * other,Node * control)3501 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
3502                                         Node* control) {
3503   int inputs = control->op()->ControlInputCount();
3504   if (value->opcode() == IrOpcode::kEffectPhi &&
3505       NodeProperties::GetControlInput(value) == control) {
3506     // Phi already exists, add input.
3507     value->InsertInput(graph_zone(), inputs - 1, other);
3508     NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
3509   } else if (value != other) {
3510     // Phi does not exist yet, introduce one.
3511     value = NewEffectPhi(inputs, value, control);
3512     value->ReplaceInput(inputs - 1, other);
3513   }
3514   return value;
3515 }
3516 
MergeValue(Node * value,Node * other,Node * control)3517 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
3518                                        Node* control) {
3519   int inputs = control->op()->ControlInputCount();
3520   if (value->opcode() == IrOpcode::kPhi &&
3521       NodeProperties::GetControlInput(value) == control) {
3522     // Phi already exists, add input.
3523     value->InsertInput(graph_zone(), inputs - 1, other);
3524     NodeProperties::ChangeOp(
3525         value, common()->Phi(MachineRepresentation::kTagged, inputs));
3526   } else if (value != other) {
3527     // Phi does not exist yet, introduce one.
3528     value = NewPhi(inputs, value, control);
3529     value->ReplaceInput(inputs - 1, other);
3530   }
3531   return value;
3532 }
3533 
UpdateSourcePosition(SourcePositionTableIterator * it,int offset)3534 void BytecodeGraphBuilder::UpdateSourcePosition(SourcePositionTableIterator* it,
3535                                                 int offset) {
3536   if (it->done()) return;
3537   if (it->code_offset() == offset) {
3538     source_positions_->SetCurrentPosition(SourcePosition(
3539         it->source_position().ScriptOffset(), start_position_.InliningId()));
3540     it->Advance();
3541   } else {
3542     DCHECK_GT(it->code_offset(), offset);
3543   }
3544 }
3545 
3546 }  // namespace compiler
3547 }  // namespace internal
3548 }  // namespace v8
3549