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