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/base/platform/wrappers.h"
9#include "src/codegen/source-position-table.h"
10#include "src/codegen/tick-counter.h"
11#include "src/common/assert-scope.h"
12#include "src/compiler/access-builder.h"
13#include "src/compiler/bytecode-analysis.h"
14#include "src/compiler/common-operator.h"
15#include "src/compiler/compiler-source-position-table.h"
16#include "src/compiler/js-heap-broker.h"
17#include "src/compiler/linkage.h"
18#include "src/compiler/node-matchers.h"
19#include "src/compiler/node-observer.h"
20#include "src/compiler/operator-properties.h"
21#include "src/compiler/simplified-operator.h"
22#include "src/compiler/state-values-utils.h"
23#include "src/interpreter/bytecode-array-iterator.h"
24#include "src/interpreter/bytecode-flags.h"
25#include "src/interpreter/bytecodes.h"
26#include "src/objects/js-array-inl.h"
27#include "src/objects/js-generator.h"
28#include "src/objects/literal-objects-inl.h"
29#include "src/objects/objects-inl.h"
30#include "src/objects/smi.h"
31#include "src/objects/template-objects-inl.h"
32
33namespace v8 {
34namespace internal {
35namespace compiler {
36
37class BytecodeGraphBuilder {
38 public:
39  BytecodeGraphBuilder(JSHeapBroker* broker, Zone* local_zone,
40                       NativeContextRef const& native_context,
41                       SharedFunctionInfoRef const& shared_info,
42                       FeedbackCellRef const& feedback_cell,
43                       BytecodeOffset osr_offset, JSGraph* jsgraph,
44                       CallFrequency const& invocation_frequency,
45                       SourcePositionTable* source_positions, int inlining_id,
46                       CodeKind code_kind, BytecodeGraphBuilderFlags flags,
47                       TickCounter* tick_counter,
48                       ObserveNodeInfo const& observe_node_info);
49
50  BytecodeGraphBuilder(const BytecodeGraphBuilder&) = delete;
51  BytecodeGraphBuilder& operator=(const BytecodeGraphBuilder&) = delete;
52
53  // Creates a graph by visiting bytecodes.
54  void CreateGraph();
55
56 private:
57  class Environment;
58  class OsrIteratorState;
59  struct SubEnvironment;
60
61  void RemoveMergeEnvironmentsBeforeOffset(int limit_offset);
62  void AdvanceToOsrEntryAndPeelLoops();
63
64  // Advance {bytecode_iterator} to the given offset. If possible, also advance
65  // {source_position_iterator} while updating the source position table.
66  void AdvanceIteratorsTo(int bytecode_offset);
67
68  void VisitSingleBytecode();
69  void VisitBytecodes();
70
71  // Get or create the node that represents the outer function closure.
72  Node* GetFunctionClosure();
73
74  // Get or create the node for this parameter index. If such a node is
75  // already cached, it is returned directly and the {debug_name_hint} is
76  // ignored.
77  Node* GetParameter(int index, const char* debug_name_hint = nullptr);
78
79  CodeKind code_kind() const { return code_kind_; }
80
81  // The node representing the current feedback vector is generated once prior
82  // to visiting bytecodes, and is later passed as input to other nodes that
83  // may need it.
84  // TODO(jgruber): Remove feedback_vector() and rename feedback_vector_node()
85  // to feedback_vector() once all uses of the direct heap object reference
86  // have been replaced with a Node* reference.
87  void CreateFeedbackVectorNode();
88  Node* feedback_vector_node() const {
89    DCHECK_NOT_NULL(feedback_vector_node_);
90    return feedback_vector_node_;
91  }
92
93  // Same as above for the feedback vector node.
94  void CreateNativeContextNode();
95  Node* native_context_node() const {
96    DCHECK_NOT_NULL(native_context_node_);
97    return native_context_node_;
98  }
99
100  Node* BuildLoadFeedbackCell(int index);
101
102  // Builder for loading a native context field.
103  Node* BuildLoadNativeContextField(int index);
104
105  // Helper function for creating a feedback source containing type feedback
106  // vector and a feedback slot.
107  FeedbackSource CreateFeedbackSource(int slot_id);
108  FeedbackSource CreateFeedbackSource(FeedbackSlot slot);
109
110  void set_environment(Environment* env) { environment_ = env; }
111  const Environment* environment() const { return environment_; }
112  Environment* environment() { return environment_; }
113
114  // Node creation helpers
115  Node* NewNode(const Operator* op, bool incomplete = false) {
116    return MakeNode(op, 0, static_cast<Node**>(nullptr), incomplete);
117  }
118
119  template <class... Args>
120  Node* NewNode(const Operator* op, Node* n0, Args... nodes) {
121    Node* buffer[] = {n0, nodes...};
122    return MakeNode(op, arraysize(buffer), buffer);
123  }
124
125  // Helpers to create new control nodes.
126  Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
127  Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
128  Node* NewIfValue(int32_t value) { return NewNode(common()->IfValue(value)); }
129  Node* NewIfDefault() { return NewNode(common()->IfDefault()); }
130  Node* NewMerge() { return NewNode(common()->Merge(1), true); }
131  Node* NewLoop() { return NewNode(common()->Loop(1), true); }
132  Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
133    return NewNode(common()->Branch(hint), condition);
134  }
135  Node* NewSwitch(Node* condition, int control_output_count) {
136    return NewNode(common()->Switch(control_output_count), condition);
137  }
138
139  // Creates a new Phi node having {count} input values.
140  Node* NewPhi(int count, Node* input, Node* control);
141  Node* NewEffectPhi(int count, Node* input, Node* control);
142
143  // Helpers for merging control, effect or value dependencies.
144  Node* MergeControl(Node* control, Node* other);
145  Node* MergeEffect(Node* effect, Node* other_effect, Node* control);
146  Node* MergeValue(Node* value, Node* other_value, Node* control);
147
148  // The main node creation chokepoint. Adds context, frame state, effect,
149  // and control dependencies depending on the operator.
150  Node* MakeNode(const Operator* op, int value_input_count,
151                 Node* const* value_inputs, bool incomplete = false);
152
153  Node** EnsureInputBufferSize(int size);
154
155  Node* const* GetCallArgumentsFromRegisters(Node* callee, Node* receiver,
156                                              interpreter::Register first_arg,
157                                              int arg_count);
158  Node* const* ProcessCallVarArgs(ConvertReceiverMode receiver_mode,
159                                  Node* callee, interpreter::Register first_reg,
160                                  int arg_count);
161  Node* const* GetConstructArgumentsFromRegister(
162      Node* target, Node* new_target, interpreter::Register first_arg,
163      int arg_count);
164  Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op,
165                                    interpreter::Register receiver,
166                                    size_t reg_count);
167
168  // Prepare information for eager deoptimization. This information is carried
169  // by dedicated {Checkpoint} nodes that are wired into the effect chain.
170  // Conceptually this frame state is "before" a given operation.
171  void PrepareEagerCheckpoint();
172
173  // Prepare information for lazy deoptimization. This information is attached
174  // to the given node and the output value produced by the node is combined.
175  //
176  // The low-level chokepoint - use the variants below instead.
177  void PrepareFrameState(Node* node, OutputFrameStateCombine combine,
178                         BytecodeOffset bailout_id,
179                         const BytecodeLivenessState* liveness);
180
181  // In the common case, frame states are conceptually "after" a given
182  // operation and at the current bytecode offset.
183  void PrepareFrameState(Node* node, OutputFrameStateCombine combine) {
184    if (!OperatorProperties::HasFrameStateInput(node->op())) return;
185    const int offset = bytecode_iterator().current_offset();
186    return PrepareFrameState(node, combine, BytecodeOffset(offset),
187                             bytecode_analysis().GetOutLivenessFor(offset));
188  }
189
190  // For function-entry stack checks, they're conceptually "before" the first
191  // bytecode and at a special marker bytecode offset.
192  // In the case of FE stack checks, the current bytecode is also the first
193  // bytecode, so we use a special marker bytecode offset to signify a virtual
194  // bytecode before the first physical bytecode.
195  void PrepareFrameStateForFunctionEntryStackCheck(Node* node) {
196    DCHECK_EQ(bytecode_iterator().current_offset(), 0);
197    DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
198    DCHECK(node->opcode() == IrOpcode::kJSStackCheck);
199    return PrepareFrameState(node, OutputFrameStateCombine::Ignore(),
200                             BytecodeOffset(kFunctionEntryBytecodeOffset),
201                             bytecode_analysis().GetInLivenessFor(0));
202  }
203
204  // For OSR-entry stack checks, they're conceptually "before" the first
205  // bytecode of the current loop. We implement this in a similar manner to
206  // function-entry (FE) stack checks above, i.e. we deopt at the predecessor
207  // of the current bytecode.
208  // In the case of OSR-entry stack checks, a physical predecessor bytecode
209  // exists: the JumpLoop bytecode. We attach to JumpLoop by using
210  // `bytecode_analysis().osr_bailout_id()` instead of current_offset (the
211  // former points at JumpLoop, the latter at the loop header, i.e. the target
212  // of JumpLoop).
213  void PrepareFrameStateForOSREntryStackCheck(Node* node) {
214    DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
215    DCHECK(node->opcode() == IrOpcode::kJSStackCheck);
216    const int offset = bytecode_analysis().osr_bailout_id().ToInt();
217    return PrepareFrameState(node, OutputFrameStateCombine::Ignore(),
218                             BytecodeOffset(offset),
219                             bytecode_analysis().GetOutLivenessFor(offset));
220  }
221
222  void BuildCreateArguments(CreateArgumentsType type);
223  Node* BuildLoadGlobal(NameRef name, uint32_t feedback_slot_index,
224                        TypeofMode typeof_mode);
225
226  enum class NamedStoreMode {
227    // Check the prototype chain before storing.
228    kSet,
229    // Define value to the receiver without checking the prototype chain.
230    kDefineOwn,
231  };
232  void BuildNamedStore(NamedStoreMode store_mode);
233  void BuildLdaLookupSlot(TypeofMode typeof_mode);
234  void BuildLdaLookupContextSlot(TypeofMode typeof_mode);
235  void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode);
236  void BuildCallVarArgs(ConvertReceiverMode receiver_mode);
237  void BuildCall(ConvertReceiverMode receiver_mode, Node* const* args,
238                 size_t arg_count, int slot_id);
239  void BuildCall(ConvertReceiverMode receiver_mode,
240                 std::initializer_list<Node*> args, int slot_id) {
241    BuildCall(receiver_mode, args.begin(), args.size(), slot_id);
242  }
243  void BuildUnaryOp(const Operator* op);
244  void BuildBinaryOp(const Operator* op);
245  void BuildBinaryOpWithImmediate(const Operator* op);
246  void BuildCompareOp(const Operator* op);
247  void BuildDelete(LanguageMode language_mode);
248  void BuildCastOperator(const Operator* op);
249  void BuildHoleCheckAndThrow(Node* condition, Runtime::FunctionId runtime_id,
250                              Node* name = nullptr);
251
252  // Optional early lowering to the simplified operator level.  Note that
253  // the result has already been wired into the environment just like
254  // any other invocation of {NewNode} would do.
255  JSTypeHintLowering::LoweringResult TryBuildSimplifiedUnaryOp(
256      const Operator* op, Node* operand, FeedbackSlot slot);
257  JSTypeHintLowering::LoweringResult TryBuildSimplifiedBinaryOp(
258      const Operator* op, Node* left, Node* right, FeedbackSlot slot);
259  JSTypeHintLowering::LoweringResult TryBuildSimplifiedForInNext(
260      Node* receiver, Node* cache_array, Node* cache_type, Node* index,
261      FeedbackSlot slot);
262  JSTypeHintLowering::LoweringResult TryBuildSimplifiedForInPrepare(
263      Node* receiver, FeedbackSlot slot);
264  JSTypeHintLowering::LoweringResult TryBuildSimplifiedToNumber(
265      Node* input, FeedbackSlot slot);
266  JSTypeHintLowering::LoweringResult TryBuildSimplifiedCall(const Operator* op,
267                                                            Node* const* args,
268                                                            int arg_count,
269                                                            FeedbackSlot slot);
270  JSTypeHintLowering::LoweringResult TryBuildSimplifiedConstruct(
271      const Operator* op, Node* const* args, int arg_count, FeedbackSlot slot);
272  JSTypeHintLowering::LoweringResult TryBuildSimplifiedGetIterator(
273      const Operator* op, Node* receiver, FeedbackSlot load_slot,
274      FeedbackSlot call_slot);
275  JSTypeHintLowering::LoweringResult TryBuildSimplifiedLoadNamed(
276      const Operator* op, FeedbackSlot slot);
277  JSTypeHintLowering::LoweringResult TryBuildSimplifiedLoadKeyed(
278      const Operator* op, Node* receiver, Node* key, FeedbackSlot slot);
279  JSTypeHintLowering::LoweringResult TryBuildSimplifiedStoreNamed(
280      const Operator* op, Node* receiver, Node* value, FeedbackSlot slot);
281  JSTypeHintLowering::LoweringResult TryBuildSimplifiedStoreKeyed(
282      const Operator* op, Node* receiver, Node* key, Node* value,
283      FeedbackSlot slot);
284
285  // Applies the given early reduction onto the current environment.
286  void ApplyEarlyReduction(JSTypeHintLowering::LoweringResult reduction);
287
288  // Check the context chain for extensions, for lookup fast paths.
289  Environment* CheckContextExtensions(uint32_t depth);
290  // Slow path taken when we cannot figure out the current scope info.
291  Environment* CheckContextExtensionsSlowPath(uint32_t depth);
292  // Helper function that tries to get the current scope info.
293  base::Optional<ScopeInfoRef> TryGetScopeInfo();
294  // Helper function to create a context extension check.
295  Environment* CheckContextExtensionAtDepth(Environment* slow_environment,
296                                            uint32_t depth);
297
298  // Helper function to create for-in mode from the recorded type feedback.
299  ForInMode GetForInMode(FeedbackSlot slot);
300
301  // Helper function to compute call frequency from the recorded type
302  // feedback. Returns unknown if invocation count is unknown. Returns 0 if
303  // feedback is insufficient.
304  CallFrequency ComputeCallFrequency(int slot_id) const;
305
306  // Helper function to extract the speculation mode from the recorded type
307  // feedback. Returns kDisallowSpeculation if feedback is insufficient.
308  SpeculationMode GetSpeculationMode(int slot_id) const;
309
310  // Helper function to determine the call feedback relation from the recorded
311  // type feedback. Returns kUnrelated if feedback is insufficient.
312  CallFeedbackRelation ComputeCallFeedbackRelation(int slot_id) const;
313
314  // Helpers for building the implicit FunctionEntry and IterationBody
315  // StackChecks.
316  void BuildFunctionEntryStackCheck();
317  void BuildIterationBodyStackCheck();
318  void BuildOSREntryStackCheck();
319
320  // Control flow plumbing.
321  void BuildJump();
322  void BuildJumpIf(Node* condition);
323  void BuildJumpIfNot(Node* condition);
324  void BuildJumpIfEqual(Node* comperand);
325  void BuildJumpIfNotEqual(Node* comperand);
326  void BuildJumpIfTrue();
327  void BuildJumpIfFalse();
328  void BuildJumpIfToBooleanTrue();
329  void BuildJumpIfToBooleanFalse();
330  void BuildJumpIfNotHole();
331  void BuildJumpIfJSReceiver();
332
333  void BuildSwitchOnSmi(Node* condition);
334  void BuildSwitchOnGeneratorState(
335      const ZoneVector<ResumeJumpTarget>& resume_jump_targets,
336      bool allow_fallthrough_on_executing);
337
338  // Simulates control flow by forward-propagating environments.
339  void MergeIntoSuccessorEnvironment(int target_offset);
340  void BuildLoopHeaderEnvironment(int current_offset);
341  void SwitchToMergeEnvironment(int current_offset);
342
343  // Simulates control flow that exits the function body.
344  void MergeControlToLeaveFunction(Node* exit);
345
346  // Builds loop exit nodes for every exited loop between the current bytecode
347  // offset and {target_offset}.
348  void BuildLoopExitsForBranch(int target_offset);
349  void BuildLoopExitsForFunctionExit(const BytecodeLivenessState* liveness);
350  void BuildLoopExitsUntilLoop(int loop_offset,
351                               const BytecodeLivenessState* liveness);
352
353  // Helper for building a return (from an actual return or a suspend).
354  void BuildReturn(const BytecodeLivenessState* liveness);
355
356  // Simulates entry and exit of exception handlers.
357  void ExitThenEnterExceptionHandlers(int current_offset);
358
359  // Update the current position of the {SourcePositionTable} to that of the
360  // bytecode at {offset}, if any.
361  void UpdateSourcePosition(int offset);
362
363  // Growth increment for the temporary buffer used to construct input lists to
364  // new nodes.
365  static const int kInputBufferSizeIncrement = 64;
366
367  // An abstract representation for an exception handler that is being
368  // entered and exited while the graph builder is iterating over the
369  // underlying bytecode. The exception handlers within the bytecode are
370  // well scoped, hence will form a stack during iteration.
371  struct ExceptionHandler {
372    int start_offset_;      // Start offset of the handled area in the bytecode.
373    int end_offset_;        // End offset of the handled area in the bytecode.
374    int handler_offset_;    // Handler entry offset within the bytecode.
375    int context_register_;  // Index of register holding handler context.
376  };
377
378  template <class T = Object>
379  typename ref_traits<T>::ref_type MakeRefForConstantForIndexOperand(
380      int operand_index) {
381    // The BytecodeArray itself was fetched by using a barrier so all reads
382    // from the constant pool are safe.
383    return MakeRefAssumeMemoryFence(
384        broker(), broker()->CanonicalPersistentHandle(Handle<T>::cast(
385                      bytecode_iterator().GetConstantForIndexOperand(
386                          operand_index, local_isolate_))));
387  }
388
389  Graph* graph() const { return jsgraph_->graph(); }
390  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
391  Zone* graph_zone() const { return graph()->zone(); }
392  JSGraph* jsgraph() const { return jsgraph_; }
393  Isolate* isolate() const { return jsgraph_->isolate(); }
394  JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); }
395  SimplifiedOperatorBuilder* simplified() const {
396    return jsgraph_->simplified();
397  }
398  Zone* local_zone() const { return local_zone_; }
399  BytecodeArrayRef bytecode_array() const { return bytecode_array_; }
400  FeedbackVectorRef const& feedback_vector() const { return feedback_vector_; }
401  const JSTypeHintLowering& type_hint_lowering() const {
402    return type_hint_lowering_;
403  }
404  const FrameStateFunctionInfo* frame_state_function_info() const {
405    return frame_state_function_info_;
406  }
407  SourcePositionTableIterator& source_position_iterator() {
408    return *source_position_iterator_.get();
409  }
410  interpreter::BytecodeArrayIterator const& bytecode_iterator() const {
411    return bytecode_iterator_;
412  }
413  interpreter::BytecodeArrayIterator& bytecode_iterator() {
414    return bytecode_iterator_;
415  }
416  BytecodeAnalysis const& bytecode_analysis() const {
417    return bytecode_analysis_;
418  }
419  int currently_peeled_loop_offset() const {
420    return currently_peeled_loop_offset_;
421  }
422  void set_currently_peeled_loop_offset(int offset) {
423    currently_peeled_loop_offset_ = offset;
424  }
425  bool skip_first_stack_check() const {
426    return skip_first_stack_and_tierup_check_;
427  }
428  bool skip_tierup_check() const {
429    return skip_first_stack_and_tierup_check_ || osr_;
430  }
431  int current_exception_handler() const { return current_exception_handler_; }
432  void set_current_exception_handler(int index) {
433    current_exception_handler_ = index;
434  }
435  bool needs_eager_checkpoint() const { return needs_eager_checkpoint_; }
436  void mark_as_needing_eager_checkpoint(bool value) {
437    needs_eager_checkpoint_ = value;
438  }
439  JSHeapBroker* broker() const { return broker_; }
440  NativeContextRef native_context() const { return native_context_; }
441  SharedFunctionInfoRef shared_info() const { return shared_info_; }
442
443#define DECLARE_VISIT_BYTECODE(name, ...) void Visit##name();
444  BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
445#undef DECLARE_VISIT_BYTECODE
446
447  JSHeapBroker* const broker_;
448  LocalIsolate* const local_isolate_;
449  Zone* const local_zone_;
450  JSGraph* const jsgraph_;
451  // The native context for which we optimize.
452  NativeContextRef const native_context_;
453  SharedFunctionInfoRef const shared_info_;
454  BytecodeArrayRef const bytecode_array_;
455  FeedbackCellRef const feedback_cell_;
456  FeedbackVectorRef const feedback_vector_;
457  CallFrequency const invocation_frequency_;
458  JSTypeHintLowering const type_hint_lowering_;
459  const FrameStateFunctionInfo* const frame_state_function_info_;
460  std::unique_ptr<SourcePositionTableIterator> source_position_iterator_;
461  interpreter::BytecodeArrayIterator bytecode_iterator_;
462  BytecodeAnalysis const bytecode_analysis_;
463  Environment* environment_;
464  bool const osr_;
465  int currently_peeled_loop_offset_;
466
467  const bool skip_first_stack_and_tierup_check_;
468
469  // Merge environments are snapshots of the environment at points where the
470  // control flow merges. This models a forward data flow propagation of all
471  // values from all predecessors of the merge in question. They are indexed by
472  // the bytecode offset
473  ZoneMap<int, Environment*> merge_environments_;
474
475  // Generator merge environments are snapshots of the current resume
476  // environment, tracing back through loop headers to the resume switch of a
477  // generator. They allow us to model a single resume jump as several switch
478  // statements across loop headers, keeping those loop headers reducible,
479  // without having to merge the "executing" environments of the generator into
480  // the "resuming" ones. They are indexed by the suspend id of the resume.
481  ZoneMap<int, Environment*> generator_merge_environments_;
482
483  ZoneVector<Node*> cached_parameters_;
484
485  // Exception handlers currently entered by the iteration.
486  ZoneStack<ExceptionHandler> exception_handlers_;
487  int current_exception_handler_;
488
489  // Temporary storage for building node input lists.
490  int input_buffer_size_;
491  Node** input_buffer_;
492
493  const CodeKind code_kind_;
494  Node* feedback_vector_node_;
495  Node* native_context_node_;
496
497  // Optimization to only create checkpoints when the current position in the
498  // control-flow is not effect-dominated by another checkpoint already. All
499  // operations that do not have observable side-effects can be re-evaluated.
500  bool needs_eager_checkpoint_;
501
502  // Nodes representing values in the activation record.
503  SetOncePointer<Node> function_closure_;
504
505  // Control nodes that exit the function body.
506  ZoneVector<Node*> exit_controls_;
507
508  StateValuesCache state_values_cache_;
509
510  // The source position table, to be populated.
511  SourcePositionTable* const source_positions_;
512
513  SourcePosition const start_position_;
514
515  TickCounter* const tick_counter_;
516
517  ObserveNodeInfo const observe_node_info_;
518
519  static constexpr int kBinaryOperationHintIndex = 1;
520  static constexpr int kBinaryOperationSmiHintIndex = 1;
521  static constexpr int kCompareOperationHintIndex = 1;
522  static constexpr int kCountOperationHintIndex = 0;
523  static constexpr int kUnaryOperationHintIndex = 0;
524};
525
526// The abstract execution environment simulates the content of the interpreter
527// register file. The environment performs SSA-renaming of all tracked nodes at
528// split and merge points in the control flow.
529class BytecodeGraphBuilder::Environment : public ZoneObject {
530 public:
531  Environment(BytecodeGraphBuilder* builder, int register_count,
532              int parameter_count,
533              interpreter::Register incoming_new_target_or_generator,
534              Node* control_dependency);
535
536  // Specifies whether environment binding methods should attach frame state
537  // inputs to nodes representing the value being bound. This is done because
538  // the {OutputFrameStateCombine} is closely related to the binding method.
539  enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
540
541  int parameter_count() const { return parameter_count_; }
542  int register_count() const { return register_count_; }
543
544  Node* LookupAccumulator() const;
545  Node* LookupRegister(interpreter::Register the_register) const;
546  Node* LookupGeneratorState() const;
547
548  void BindAccumulator(Node* node,
549                       FrameStateAttachmentMode mode = kDontAttachFrameState);
550  void BindRegister(interpreter::Register the_register, Node* node,
551                    FrameStateAttachmentMode mode = kDontAttachFrameState);
552  void BindRegistersToProjections(
553      interpreter::Register first_reg, Node* node,
554      FrameStateAttachmentMode mode = kDontAttachFrameState);
555  void BindGeneratorState(Node* node);
556  void RecordAfterState(Node* node,
557                        FrameStateAttachmentMode mode = kDontAttachFrameState);
558
559  // Effect dependency tracked by this environment.
560  Node* GetEffectDependency() { return effect_dependency_; }
561  void UpdateEffectDependency(Node* dependency) {
562    effect_dependency_ = dependency;
563  }
564
565  // Preserve a checkpoint of the environment for the IR graph. Any
566  // further mutation of the environment will not affect checkpoints.
567  Node* Checkpoint(BytecodeOffset bytecode_offset,
568                   OutputFrameStateCombine combine,
569                   const BytecodeLivenessState* liveness);
570
571  // Control dependency tracked by this environment.
572  Node* GetControlDependency() const { return control_dependency_; }
573  void UpdateControlDependency(Node* dependency) {
574    control_dependency_ = dependency;
575  }
576
577  Node* Context() const { return context_; }
578  void SetContext(Node* new_context) { context_ = new_context; }
579
580  Environment* Copy();
581  void Merge(Environment* other, const BytecodeLivenessState* liveness);
582
583  void FillWithOsrValues();
584  void PrepareForLoop(const BytecodeLoopAssignments& assignments,
585                      const BytecodeLivenessState* liveness);
586  void PrepareForLoopExit(Node* loop,
587                          const BytecodeLoopAssignments& assignments,
588                          const BytecodeLivenessState* liveness);
589
590 private:
591  friend Zone;
592
593  explicit Environment(const Environment* copy);
594
595  bool StateValuesRequireUpdate(Node** state_values, Node** values, int count);
596  void UpdateStateValues(Node** state_values, Node** values, int count);
597  Node* GetStateValuesFromCache(Node** values, int count,
598                                const BytecodeLivenessState* liveness);
599
600  int RegisterToValuesIndex(interpreter::Register the_register) const;
601
602  Zone* zone() const { return builder_->local_zone(); }
603  Graph* graph() const { return builder_->graph(); }
604  CommonOperatorBuilder* common() const { return builder_->common(); }
605  BytecodeGraphBuilder* builder() const { return builder_; }
606  const NodeVector* values() const { return &values_; }
607  NodeVector* values() { return &values_; }
608  int register_base() const { return register_base_; }
609  int accumulator_base() const { return accumulator_base_; }
610
611  BytecodeGraphBuilder* builder_;
612  int register_count_;
613  int parameter_count_;
614  Node* context_;
615  Node* control_dependency_;
616  Node* effect_dependency_;
617  NodeVector values_;
618  Node* parameters_state_values_;
619  Node* generator_state_;
620  int register_base_;
621  int accumulator_base_;
622};
623
624// A helper for creating a temporary sub-environment for simple branches.
625struct BytecodeGraphBuilder::SubEnvironment final {
626 public:
627  explicit SubEnvironment(BytecodeGraphBuilder* builder)
628      : builder_(builder), parent_(builder->environment()->Copy()) {}
629
630  ~SubEnvironment() { builder_->set_environment(parent_); }
631
632 private:
633  BytecodeGraphBuilder* builder_;
634  BytecodeGraphBuilder::Environment* parent_;
635};
636
637// Issues:
638// - Scopes - intimately tied to AST. Need to eval what is needed.
639// - Need to resolve closure parameter treatment.
640BytecodeGraphBuilder::Environment::Environment(
641    BytecodeGraphBuilder* builder, int register_count, int parameter_count,
642    interpreter::Register incoming_new_target_or_generator,
643    Node* control_dependency)
644    : builder_(builder),
645      register_count_(register_count),
646      parameter_count_(parameter_count),
647      control_dependency_(control_dependency),
648      effect_dependency_(control_dependency),
649      values_(builder->local_zone()),
650      parameters_state_values_(nullptr),
651      generator_state_(nullptr) {
652  // The layout of values_ is:
653  //
654  // [receiver] [parameters] [registers] [accumulator]
655  //
656  // parameter[0] is the receiver (this), parameters 1..N are the
657  // parameters supplied to the method (arg0..argN-1). The accumulator
658  // is stored separately.
659
660  // Parameters including the receiver
661  for (int i = 0; i < parameter_count; i++) {
662    const char* debug_name = (i == 0) ? "%this" : nullptr;
663    Node* parameter = builder->GetParameter(i, debug_name);
664    values()->push_back(parameter);
665  }
666
667  // Registers
668  register_base_ = static_cast<int>(values()->size());
669  Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
670  values()->insert(values()->end(), register_count, undefined_constant);
671
672  // Accumulator
673  accumulator_base_ = static_cast<int>(values()->size());
674  values()->push_back(undefined_constant);
675
676  // Context
677  int context_index = Linkage::GetJSCallContextParamIndex(parameter_count);
678  context_ = builder->GetParameter(context_index, "%context");
679
680  // Incoming new.target or generator register
681  if (incoming_new_target_or_generator.is_valid()) {
682    int new_target_index =
683        Linkage::GetJSCallNewTargetParamIndex(parameter_count);
684    Node* new_target_node =
685        builder->GetParameter(new_target_index, "%new.target");
686
687    int values_index = RegisterToValuesIndex(incoming_new_target_or_generator);
688    values()->at(values_index) = new_target_node;
689  }
690}
691
692BytecodeGraphBuilder::Environment::Environment(
693    const BytecodeGraphBuilder::Environment* other)
694    : builder_(other->builder_),
695      register_count_(other->register_count_),
696      parameter_count_(other->parameter_count_),
697      context_(other->context_),
698      control_dependency_(other->control_dependency_),
699      effect_dependency_(other->effect_dependency_),
700      values_(other->zone()),
701      parameters_state_values_(other->parameters_state_values_),
702      generator_state_(other->generator_state_),
703      register_base_(other->register_base_),
704      accumulator_base_(other->accumulator_base_) {
705  values_ = other->values_;
706}
707
708
709int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
710    interpreter::Register the_register) const {
711  if (the_register.is_parameter()) {
712    return the_register.ToParameterIndex();
713  } else {
714    return the_register.index() + register_base();
715  }
716}
717
718Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
719  return values()->at(accumulator_base_);
720}
721
722Node* BytecodeGraphBuilder::Environment::LookupGeneratorState() const {
723  DCHECK_NOT_NULL(generator_state_);
724  return generator_state_;
725}
726
727Node* BytecodeGraphBuilder::Environment::LookupRegister(
728    interpreter::Register the_register) const {
729  if (the_register.is_current_context()) {
730    return Context();
731  } else if (the_register.is_function_closure()) {
732    return builder()->GetFunctionClosure();
733  } else {
734    int values_index = RegisterToValuesIndex(the_register);
735    return values()->at(values_index);
736  }
737}
738
739void BytecodeGraphBuilder::Environment::BindAccumulator(
740    Node* node, FrameStateAttachmentMode mode) {
741  if (mode == FrameStateAttachmentMode::kAttachFrameState) {
742    builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
743  }
744  values()->at(accumulator_base_) = node;
745}
746
747void BytecodeGraphBuilder::Environment::BindGeneratorState(Node* node) {
748  generator_state_ = node;
749}
750
751void BytecodeGraphBuilder::Environment::BindRegister(
752    interpreter::Register the_register, Node* node,
753    FrameStateAttachmentMode mode) {
754  int values_index = RegisterToValuesIndex(the_register);
755  if (mode == FrameStateAttachmentMode::kAttachFrameState) {
756    builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
757                                           accumulator_base_ - values_index));
758  }
759  values()->at(values_index) = node;
760}
761
762void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
763    interpreter::Register first_reg, Node* node,
764    FrameStateAttachmentMode mode) {
765  int values_index = RegisterToValuesIndex(first_reg);
766  if (mode == FrameStateAttachmentMode::kAttachFrameState) {
767    builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
768                                           accumulator_base_ - values_index));
769  }
770  for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
771    values()->at(values_index + i) =
772        builder()->NewNode(common()->Projection(i), node);
773  }
774}
775
776void BytecodeGraphBuilder::Environment::RecordAfterState(
777    Node* node, FrameStateAttachmentMode mode) {
778  if (mode == FrameStateAttachmentMode::kAttachFrameState) {
779    builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
780  }
781}
782
783BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::Environment::Copy() {
784  return zone()->New<Environment>(this);
785}
786
787void BytecodeGraphBuilder::Environment::Merge(
788    BytecodeGraphBuilder::Environment* other,
789    const BytecodeLivenessState* liveness) {
790  // Create a merge of the control dependencies of both environments and update
791  // the current environment's control dependency accordingly.
792  Node* control = builder()->MergeControl(GetControlDependency(),
793                                          other->GetControlDependency());
794  UpdateControlDependency(control);
795
796  // Create a merge of the effect dependencies of both environments and update
797  // the current environment's effect dependency accordingly.
798  Node* effect = builder()->MergeEffect(GetEffectDependency(),
799                                        other->GetEffectDependency(), control);
800  UpdateEffectDependency(effect);
801
802  // Introduce Phi nodes for values that are live and have differing inputs at
803  // the merge point, potentially extending an existing Phi node if possible.
804  context_ = builder()->MergeValue(context_, other->context_, control);
805  for (int i = 0; i < parameter_count(); i++) {
806    values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
807  }
808  for (int i = 0; i < register_count(); i++) {
809    int index = register_base() + i;
810    if (liveness == nullptr || liveness->RegisterIsLive(i)) {
811#if DEBUG
812      // We only do these DCHECKs when we are not in the resume path of a
813      // generator -- this is, when either there is no generator state at all,
814      // or the generator state is not the constant "executing" value.
815      if (generator_state_ == nullptr ||
816          NumberMatcher(generator_state_)
817              .Is(JSGeneratorObject::kGeneratorExecuting)) {
818        DCHECK_NE(values_[index], builder()->jsgraph()->OptimizedOutConstant());
819        DCHECK_NE(other->values_[index],
820                  builder()->jsgraph()->OptimizedOutConstant());
821      }
822#endif
823
824      values_[index] =
825          builder()->MergeValue(values_[index], other->values_[index], control);
826
827    } else {
828      values_[index] = builder()->jsgraph()->OptimizedOutConstant();
829    }
830  }
831
832  if (liveness == nullptr || liveness->AccumulatorIsLive()) {
833    DCHECK_NE(values_[accumulator_base()],
834              builder()->jsgraph()->OptimizedOutConstant());
835    DCHECK_NE(other->values_[accumulator_base()],
836              builder()->jsgraph()->OptimizedOutConstant());
837
838    values_[accumulator_base()] =
839        builder()->MergeValue(values_[accumulator_base()],
840                              other->values_[accumulator_base()], control);
841  } else {
842    values_[accumulator_base()] = builder()->jsgraph()->OptimizedOutConstant();
843  }
844
845  if (generator_state_ != nullptr) {
846    DCHECK_NOT_NULL(other->generator_state_);
847    generator_state_ = builder()->MergeValue(generator_state_,
848                                             other->generator_state_, control);
849  }
850}
851
852void BytecodeGraphBuilder::Environment::PrepareForLoop(
853    const BytecodeLoopAssignments& assignments,
854    const BytecodeLivenessState* liveness) {
855  // Create a control node for the loop header.
856  Node* control = builder()->NewLoop();
857
858  // Create a Phi for external effects.
859  Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
860  UpdateEffectDependency(effect);
861
862  // Create Phis for any values that are live on entry to the loop and may be
863  // updated by the end of the loop.
864  context_ = builder()->NewPhi(1, context_, control);
865  for (int i = 0; i < parameter_count(); i++) {
866    if (assignments.ContainsParameter(i)) {
867      values_[i] = builder()->NewPhi(1, values_[i], control);
868    }
869  }
870  for (int i = 0; i < register_count(); i++) {
871    if (assignments.ContainsLocal(i) &&
872        (liveness == nullptr || liveness->RegisterIsLive(i))) {
873      int index = register_base() + i;
874      values_[index] = builder()->NewPhi(1, values_[index], control);
875    }
876  }
877  // The accumulator should not be live on entry.
878  DCHECK_IMPLIES(liveness != nullptr, !liveness->AccumulatorIsLive());
879
880  if (generator_state_ != nullptr) {
881    generator_state_ = builder()->NewPhi(1, generator_state_, control);
882  }
883
884  // Connect to the loop end.
885  Node* terminate = builder()->graph()->NewNode(
886      builder()->common()->Terminate(), effect, control);
887  builder()->exit_controls_.push_back(terminate);
888}
889
890void BytecodeGraphBuilder::Environment::FillWithOsrValues() {
891  Node* start = graph()->start();
892
893  // Create OSR values for each environment value.
894  SetContext(graph()->NewNode(
895      common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), start));
896  int size = static_cast<int>(values()->size());
897  for (int i = 0; i < size; i++) {
898    int idx = i;  // Indexing scheme follows {StandardFrame}, adapt accordingly.
899    if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
900    if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
901    values()->at(i) = graph()->NewNode(common()->OsrValue(idx), start);
902  }
903}
904
905bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
906    Node** state_values, Node** values, int count) {
907  if (*state_values == nullptr) {
908    return true;
909  }
910  Node::Inputs inputs = (*state_values)->inputs();
911  if (inputs.count() != count) return true;
912  for (int i = 0; i < count; i++) {
913    if (inputs[i] != values[i]) {
914      return true;
915    }
916  }
917  return false;
918}
919
920void BytecodeGraphBuilder::Environment::PrepareForLoopExit(
921    Node* loop, const BytecodeLoopAssignments& assignments,
922    const BytecodeLivenessState* liveness) {
923  DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
924
925  Node* control = GetControlDependency();
926
927  // Create the loop exit node.
928  Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
929  UpdateControlDependency(loop_exit);
930
931  // Rename the effect.
932  Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
933                                         GetEffectDependency(), loop_exit);
934  UpdateEffectDependency(effect_rename);
935
936  // TODO(jarin) We should also rename context here. However, unconditional
937  // renaming confuses global object and native context specialization.
938  // We should only rename if the context is assigned in the loop.
939
940  // Rename the environment values if they were assigned in the loop and are
941  // live after exiting the loop.
942  for (int i = 0; i < parameter_count(); i++) {
943    if (assignments.ContainsParameter(i)) {
944      Node* rename = graph()->NewNode(
945          common()->LoopExitValue(MachineRepresentation::kTagged), values_[i],
946          loop_exit);
947      values_[i] = rename;
948    }
949  }
950  for (int i = 0; i < register_count(); i++) {
951    if (assignments.ContainsLocal(i) &&
952        (liveness == nullptr || liveness->RegisterIsLive(i))) {
953      Node* rename = graph()->NewNode(
954          common()->LoopExitValue(MachineRepresentation::kTagged),
955          values_[register_base() + i], loop_exit);
956      values_[register_base() + i] = rename;
957    }
958  }
959  if (liveness == nullptr || liveness->AccumulatorIsLive()) {
960    Node* rename = graph()->NewNode(
961        common()->LoopExitValue(MachineRepresentation::kTagged),
962        values_[accumulator_base()], loop_exit);
963    values_[accumulator_base()] = rename;
964  }
965
966  if (generator_state_ != nullptr) {
967    generator_state_ = graph()->NewNode(
968        common()->LoopExitValue(MachineRepresentation::kTagged),
969        generator_state_, loop_exit);
970  }
971}
972
973void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
974                                                          Node** values,
975                                                          int count) {
976  if (StateValuesRequireUpdate(state_values, values, count)) {
977    const Operator* op = common()->StateValues(count, SparseInputMask::Dense());
978    (*state_values) = graph()->NewNode(op, count, values);
979  }
980}
981
982Node* BytecodeGraphBuilder::Environment::GetStateValuesFromCache(
983    Node** values, int count, const BytecodeLivenessState* liveness) {
984  return builder_->state_values_cache_.GetNodeForValues(
985      values, static_cast<size_t>(count), liveness);
986}
987
988Node* BytecodeGraphBuilder::Environment::Checkpoint(
989    BytecodeOffset bailout_id, OutputFrameStateCombine combine,
990    const BytecodeLivenessState* liveness) {
991  if (parameter_count() == register_count()) {
992    // Re-use the state-value cache if the number of local registers happens
993    // to match the parameter count.
994    parameters_state_values_ =
995        GetStateValuesFromCache(&values()->at(0), parameter_count(), nullptr);
996  } else {
997    UpdateStateValues(&parameters_state_values_, &values()->at(0),
998                      parameter_count());
999  }
1000
1001  Node* registers_state_values = GetStateValuesFromCache(
1002      &values()->at(register_base()), register_count(), liveness);
1003
1004  bool accumulator_is_live = !liveness || liveness->AccumulatorIsLive();
1005  Node* accumulator_state_value =
1006      accumulator_is_live && combine != OutputFrameStateCombine::PokeAt(0)
1007          ? values()->at(accumulator_base())
1008          : builder()->jsgraph()->OptimizedOutConstant();
1009
1010  const Operator* op = common()->FrameState(
1011      bailout_id, combine, builder()->frame_state_function_info());
1012  Node* result = graph()->NewNode(
1013      op, parameters_state_values_, registers_state_values,
1014      accumulator_state_value, Context(), builder()->GetFunctionClosure(),
1015      builder()->graph()->start());
1016
1017  return result;
1018}
1019
1020BytecodeGraphBuilder::BytecodeGraphBuilder(
1021    JSHeapBroker* broker, Zone* local_zone,
1022    NativeContextRef const& native_context,
1023    SharedFunctionInfoRef const& shared_info,
1024    FeedbackCellRef const& feedback_cell, BytecodeOffset osr_offset,
1025    JSGraph* jsgraph, CallFrequency const& invocation_frequency,
1026    SourcePositionTable* source_positions, int inlining_id, CodeKind code_kind,
1027    BytecodeGraphBuilderFlags flags, TickCounter* tick_counter,
1028    ObserveNodeInfo const& observe_node_info)
1029    : broker_(broker),
1030      local_isolate_(broker_->local_isolate()
1031                         ? broker_->local_isolate()
1032                         : broker_->isolate()->AsLocalIsolate()),
1033      local_zone_(local_zone),
1034      jsgraph_(jsgraph),
1035      native_context_(native_context),
1036      shared_info_(shared_info),
1037      bytecode_array_(shared_info.GetBytecodeArray()),
1038      feedback_cell_(feedback_cell),
1039      feedback_vector_(feedback_cell.feedback_vector().value()),
1040      invocation_frequency_(invocation_frequency),
1041      type_hint_lowering_(
1042          broker, jsgraph, feedback_vector_,
1043          (flags & BytecodeGraphBuilderFlag::kBailoutOnUninitialized)
1044              ? JSTypeHintLowering::kBailoutOnUninitialized
1045              : JSTypeHintLowering::kNoFlags),
1046      frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
1047          FrameStateType::kUnoptimizedFunction,
1048          bytecode_array().parameter_count(), bytecode_array().register_count(),
1049          shared_info.object())),
1050      source_position_iterator_(std::make_unique<SourcePositionTableIterator>(
1051          bytecode_array().SourcePositionTable())),
1052      bytecode_iterator_(bytecode_array().object()),
1053      bytecode_analysis_(
1054          bytecode_array().object(), local_zone, osr_offset,
1055          flags & BytecodeGraphBuilderFlag::kAnalyzeEnvironmentLiveness),
1056      environment_(nullptr),
1057      osr_(!osr_offset.IsNone()),
1058      currently_peeled_loop_offset_(-1),
1059      skip_first_stack_and_tierup_check_(
1060          flags & BytecodeGraphBuilderFlag::kSkipFirstStackAndTierupCheck),
1061      merge_environments_(local_zone),
1062      generator_merge_environments_(local_zone),
1063      cached_parameters_(local_zone),
1064      exception_handlers_(local_zone),
1065      current_exception_handler_(0),
1066      input_buffer_size_(0),
1067      input_buffer_(nullptr),
1068      code_kind_(code_kind),
1069      feedback_vector_node_(nullptr),
1070      native_context_node_(nullptr),
1071      needs_eager_checkpoint_(true),
1072      exit_controls_(local_zone),
1073      state_values_cache_(jsgraph),
1074      source_positions_(source_positions),
1075      start_position_(shared_info.StartPosition(), inlining_id),
1076      tick_counter_(tick_counter),
1077      observe_node_info_(observe_node_info) {}
1078
1079Node* BytecodeGraphBuilder::GetFunctionClosure() {
1080  if (!function_closure_.is_set()) {
1081    int index = Linkage::kJSCallClosureParamIndex;
1082    Node* node = GetParameter(index, "%closure");
1083    function_closure_.set(node);
1084  }
1085  return function_closure_.get();
1086}
1087
1088Node* BytecodeGraphBuilder::GetParameter(int parameter_index,
1089                                         const char* debug_name_hint) {
1090  // We use negative indices for some parameters.
1091  DCHECK_LE(ParameterInfo::kMinIndex, parameter_index);
1092  const size_t index =
1093      static_cast<size_t>(parameter_index - ParameterInfo::kMinIndex);
1094
1095  if (cached_parameters_.size() <= index) {
1096    cached_parameters_.resize(index + 1, nullptr);
1097  }
1098
1099  if (cached_parameters_[index] == nullptr) {
1100    cached_parameters_[index] =
1101        NewNode(common()->Parameter(parameter_index, debug_name_hint),
1102                graph()->start());
1103  }
1104
1105  return cached_parameters_[index];
1106}
1107
1108void BytecodeGraphBuilder::CreateFeedbackVectorNode() {
1109  DCHECK_NULL(feedback_vector_node_);
1110  feedback_vector_node_ = jsgraph()->Constant(feedback_vector());
1111}
1112
1113Node* BytecodeGraphBuilder::BuildLoadFeedbackCell(int index) {
1114  return jsgraph()->Constant(feedback_vector().GetClosureFeedbackCell(index));
1115}
1116
1117void BytecodeGraphBuilder::CreateNativeContextNode() {
1118  DCHECK_NULL(native_context_node_);
1119  native_context_node_ = jsgraph()->Constant(native_context());
1120}
1121
1122Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
1123  Node* result = NewNode(javascript()->LoadContext(0, index, true));
1124  NodeProperties::ReplaceContextInput(result, native_context_node());
1125  return result;
1126}
1127
1128FeedbackSource BytecodeGraphBuilder::CreateFeedbackSource(int slot_id) {
1129  return CreateFeedbackSource(FeedbackVector::ToSlot(slot_id));
1130}
1131
1132FeedbackSource BytecodeGraphBuilder::CreateFeedbackSource(FeedbackSlot slot) {
1133  return FeedbackSource(feedback_vector(), slot);
1134}
1135
1136void BytecodeGraphBuilder::CreateGraph() {
1137  SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
1138
1139  // Set up the basic structure of the graph. Outputs for {Start} are the formal
1140  // parameters (including the receiver) plus new target, number of arguments,
1141  // context and closure.
1142  int start_output_arity = StartNode::OutputArityForFormalParameterCount(
1143      bytecode_array().parameter_count());
1144  graph()->SetStart(graph()->NewNode(common()->Start(start_output_arity)));
1145
1146  Environment env(this, bytecode_array().register_count(),
1147                  bytecode_array().parameter_count(),
1148                  bytecode_array().incoming_new_target_or_generator_register(),
1149                  graph()->start());
1150  set_environment(&env);
1151
1152  CreateFeedbackVectorNode();
1153  CreateNativeContextNode();
1154
1155  VisitBytecodes();
1156
1157  // Finish the basic structure of the graph.
1158  DCHECK_NE(0u, exit_controls_.size());
1159  int const input_count = static_cast<int>(exit_controls_.size());
1160  Node** const inputs = &exit_controls_.front();
1161  Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
1162  graph()->SetEnd(end);
1163}
1164
1165void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
1166  if (needs_eager_checkpoint()) {
1167    // Create an explicit checkpoint node for before the operation. This only
1168    // needs to happen if we aren't effect-dominated by a {Checkpoint} already.
1169    mark_as_needing_eager_checkpoint(false);
1170    Node* node = NewNode(common()->Checkpoint());
1171    DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
1172    DCHECK_EQ(IrOpcode::kDead,
1173              NodeProperties::GetFrameStateInput(node)->opcode());
1174    BytecodeOffset bailout_id(bytecode_iterator().current_offset());
1175
1176    const BytecodeLivenessState* liveness_before =
1177        bytecode_analysis().GetInLivenessFor(
1178            bytecode_iterator().current_offset());
1179
1180    Node* frame_state_before = environment()->Checkpoint(
1181        bailout_id, OutputFrameStateCombine::Ignore(), liveness_before);
1182    NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
1183#ifdef DEBUG
1184  } else {
1185    // In case we skipped checkpoint creation above, we must be able to find an
1186    // existing checkpoint that effect-dominates the nodes about to be created.
1187    // Starting a search from the current effect-dependency has to succeed.
1188    Node* effect = environment()->GetEffectDependency();
1189    while (effect->opcode() != IrOpcode::kCheckpoint) {
1190      DCHECK(effect->op()->HasProperty(Operator::kNoWrite));
1191      DCHECK_EQ(1, effect->op()->EffectInputCount());
1192      effect = NodeProperties::GetEffectInput(effect);
1193    }
1194  }
1195#else
1196  }
1197#endif  // DEBUG
1198}
1199
1200void BytecodeGraphBuilder::PrepareFrameState(
1201    Node* node, OutputFrameStateCombine combine, BytecodeOffset bailout_id,
1202    const BytecodeLivenessState* liveness) {
1203  if (OperatorProperties::HasFrameStateInput(node->op())) {
1204    // Add the frame state for after the operation. The node in question has
1205    // already been created and had a {Dead} frame state input up until now.
1206    DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
1207    DCHECK_EQ(IrOpcode::kDead,
1208              NodeProperties::GetFrameStateInput(node)->opcode());
1209
1210    Node* frame_state_after =
1211        environment()->Checkpoint(bailout_id, combine, liveness);
1212    NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
1213  }
1214}
1215
1216void BytecodeGraphBuilder::AdvanceIteratorsTo(int bytecode_offset) {
1217  for (; bytecode_iterator().current_offset() != bytecode_offset;
1218       bytecode_iterator().Advance()) {
1219    UpdateSourcePosition(bytecode_iterator().current_offset());
1220  }
1221}
1222
1223// Stores the state of the SourcePosition iterator, and the index to the
1224// current exception handlers stack. We need, during the OSR graph generation,
1225// to backup the states of these iterators at the LoopHeader offset of each
1226// outer loop which contains the OSR loop. The iterators are then restored when
1227// peeling the loops, so that both exception handling and synchronisation with
1228// the source position can be achieved.
1229class BytecodeGraphBuilder::OsrIteratorState {
1230 public:
1231  explicit OsrIteratorState(BytecodeGraphBuilder* graph_builder)
1232      : graph_builder_(graph_builder),
1233        saved_states_(graph_builder->local_zone()) {}
1234
1235  void ProcessOsrPrelude() {
1236    ZoneVector<int> outer_loop_offsets(graph_builder_->local_zone());
1237    int osr_entry = graph_builder_->bytecode_analysis().osr_entry_point();
1238
1239    // We find here the outermost loop which contains the OSR loop.
1240    int outermost_loop_offset = osr_entry;
1241    while ((outermost_loop_offset = graph_builder_->bytecode_analysis()
1242                                        .GetLoopInfoFor(outermost_loop_offset)
1243                                        .parent_offset()) != -1) {
1244      outer_loop_offsets.push_back(outermost_loop_offset);
1245    }
1246    outermost_loop_offset =
1247        outer_loop_offsets.empty() ? osr_entry : outer_loop_offsets.back();
1248    graph_builder_->AdvanceIteratorsTo(outermost_loop_offset);
1249
1250    // We save some iterators states at the offsets of the loop headers of the
1251    // outer loops (the ones containing the OSR loop). They will be used for
1252    // jumping back in the bytecode.
1253    for (ZoneVector<int>::const_reverse_iterator it =
1254             outer_loop_offsets.crbegin();
1255         it != outer_loop_offsets.crend(); ++it) {
1256      graph_builder_->AdvanceIteratorsTo(*it);
1257      graph_builder_->ExitThenEnterExceptionHandlers(
1258          graph_builder_->bytecode_iterator().current_offset());
1259      saved_states_.push(IteratorsStates(
1260          graph_builder_->current_exception_handler(),
1261          graph_builder_->source_position_iterator().GetState()));
1262    }
1263
1264    // Finishing by advancing to the OSR entry
1265    graph_builder_->AdvanceIteratorsTo(osr_entry);
1266
1267    // Enters all remaining exception handler which end before the OSR loop
1268    // so that on next call of VisitSingleBytecode they will get popped from
1269    // the exception handlers stack.
1270    graph_builder_->ExitThenEnterExceptionHandlers(osr_entry);
1271    graph_builder_->set_currently_peeled_loop_offset(
1272        graph_builder_->bytecode_analysis()
1273            .GetLoopInfoFor(osr_entry)
1274            .parent_offset());
1275  }
1276
1277  void RestoreState(int target_offset, int new_parent_offset) {
1278    graph_builder_->bytecode_iterator().SetOffset(target_offset);
1279    // In case of a return, we must not build loop exits for
1280    // not-yet-built outer loops.
1281    graph_builder_->set_currently_peeled_loop_offset(new_parent_offset);
1282    IteratorsStates saved_state = saved_states_.top();
1283    graph_builder_->source_position_iterator().RestoreState(
1284        saved_state.source_iterator_state_);
1285    graph_builder_->set_current_exception_handler(
1286        saved_state.exception_handler_index_);
1287    saved_states_.pop();
1288  }
1289
1290 private:
1291  struct IteratorsStates {
1292    int exception_handler_index_;
1293    SourcePositionTableIterator::IndexAndPositionState source_iterator_state_;
1294
1295    IteratorsStates(int exception_handler_index,
1296                    SourcePositionTableIterator::IndexAndPositionState
1297                        source_iterator_state)
1298        : exception_handler_index_(exception_handler_index),
1299          source_iterator_state_(source_iterator_state) {}
1300  };
1301
1302  BytecodeGraphBuilder* graph_builder_;
1303  ZoneStack<IteratorsStates> saved_states_;
1304};
1305
1306void BytecodeGraphBuilder::RemoveMergeEnvironmentsBeforeOffset(
1307    int limit_offset) {
1308  if (!merge_environments_.empty()) {
1309    ZoneMap<int, Environment*>::iterator it = merge_environments_.begin();
1310    ZoneMap<int, Environment*>::iterator stop_it = merge_environments_.end();
1311    while (it != stop_it && it->first <= limit_offset) {
1312      it = merge_environments_.erase(it);
1313    }
1314  }
1315}
1316
1317void BytecodeGraphBuilder::BuildFunctionEntryStackCheck() {
1318  if (!skip_first_stack_check()) {
1319    DCHECK(exception_handlers_.empty());
1320    Node* node =
1321        NewNode(javascript()->StackCheck(StackCheckKind::kJSFunctionEntry));
1322    PrepareFrameStateForFunctionEntryStackCheck(node);
1323  }
1324}
1325
1326void BytecodeGraphBuilder::BuildIterationBodyStackCheck() {
1327  Node* node =
1328      NewNode(javascript()->StackCheck(StackCheckKind::kJSIterationBody));
1329  environment()->RecordAfterState(node, Environment::kAttachFrameState);
1330}
1331
1332void BytecodeGraphBuilder::BuildOSREntryStackCheck() {
1333  DCHECK(exception_handlers_.empty());
1334  Node* node =
1335      NewNode(javascript()->StackCheck(StackCheckKind::kJSFunctionEntry));
1336  PrepareFrameStateForOSREntryStackCheck(node);
1337}
1338
1339// We will iterate through the OSR loop, then its parent, and so on
1340// until we have reached the outmost loop containing the OSR loop. We do
1341// not generate nodes for anything before the outermost loop.
1342void BytecodeGraphBuilder::AdvanceToOsrEntryAndPeelLoops() {
1343  environment()->FillWithOsrValues();
1344
1345  // The entry stack check has to happen *before* initialising the OSR prelude;
1346  // it has to happen before setting up exception handlers, so that the
1347  // optimized code can't accidentally catch a failingstack with a OSR-ed loop
1348  // inside a try-catch, e.g.
1349  //
1350  //   try {
1351  //     loop { OSR(); }
1352  //   } catch {
1353  //     // Ignore failed stack check.
1354  //   }
1355  BuildOSREntryStackCheck();
1356
1357  OsrIteratorState iterator_states(this);
1358  iterator_states.ProcessOsrPrelude();
1359  int osr_entry = bytecode_analysis().osr_entry_point();
1360  DCHECK_EQ(bytecode_iterator().current_offset(), osr_entry);
1361
1362  // Suppose we have n nested loops, loop_0 being the outermost one, and
1363  // loop_n being the OSR loop. We start iterating the bytecode at the header
1364  // of loop_n (the OSR loop), and then we peel the part of the the body of
1365  // loop_{n-1} following the end of loop_n. We then rewind the iterator to
1366  // the header of loop_{n-1}, and so on until we have partly peeled loop 0.
1367  // The full loop_0 body will be generating with the rest of the function,
1368  // outside the OSR generation.
1369
1370  // To do so, if we are visiting a loop, we continue to visit what's left
1371  // of its parent, and then when reaching the parent's JumpLoop, we do not
1372  // create any jump for that but rewind the bytecode iterator to visit the
1373  // parent loop entirely, and so on.
1374
1375  int current_parent_offset =
1376      bytecode_analysis().GetLoopInfoFor(osr_entry).parent_offset();
1377  while (current_parent_offset != -1) {
1378    const LoopInfo& current_parent_loop =
1379        bytecode_analysis().GetLoopInfoFor(current_parent_offset);
1380    // We iterate until the back edge of the parent loop, which we detect by
1381    // the offset that the JumpLoop targets.
1382    for (; !bytecode_iterator().done(); bytecode_iterator().Advance()) {
1383      if (bytecode_iterator().current_bytecode() ==
1384              interpreter::Bytecode::kJumpLoop &&
1385          bytecode_iterator().GetJumpTargetOffset() == current_parent_offset) {
1386        // Reached the end of the current parent loop.
1387        break;
1388      }
1389      VisitSingleBytecode();
1390    }
1391    DCHECK(!bytecode_iterator()
1392                .done());  // Should have found the loop's jump target.
1393
1394    // We also need to take care of the merge environments and exceptions
1395    // handlers here because the omitted JumpLoop bytecode can still be the
1396    // target of jumps or the first bytecode after a try block.
1397    ExitThenEnterExceptionHandlers(bytecode_iterator().current_offset());
1398    SwitchToMergeEnvironment(bytecode_iterator().current_offset());
1399
1400    // This jump is the jump of our parent loop, which is not yet created.
1401    // So we do not build the jump nodes, but restore the bytecode and the
1402    // SourcePosition iterators to the values they had when we were visiting
1403    // the offset pointed at by the JumpLoop we've just reached.
1404    // We have already built nodes for inner loops, but now we will
1405    // iterate again over them and build new nodes corresponding to the same
1406    // bytecode offsets. Any jump or reference to this inner loops must now
1407    // point to the new nodes we will build, hence we clear the relevant part
1408    // of the environment.
1409    // Completely clearing the environment is not possible because merge
1410    // environments for forward jumps out of the loop need to be preserved
1411    // (e.g. a return or a labeled break in the middle of a loop).
1412    RemoveMergeEnvironmentsBeforeOffset(bytecode_iterator().current_offset());
1413    iterator_states.RestoreState(current_parent_offset,
1414                                 current_parent_loop.parent_offset());
1415    current_parent_offset = current_parent_loop.parent_offset();
1416  }
1417}
1418
1419void BytecodeGraphBuilder::VisitSingleBytecode() {
1420  tick_counter_->TickAndMaybeEnterSafepoint();
1421  int current_offset = bytecode_iterator().current_offset();
1422  UpdateSourcePosition(current_offset);
1423  ExitThenEnterExceptionHandlers(current_offset);
1424  DCHECK_GE(exception_handlers_.empty() ? current_offset
1425                                        : exception_handlers_.top().end_offset_,
1426            current_offset);
1427  SwitchToMergeEnvironment(current_offset);
1428
1429  if (environment() != nullptr) {
1430    BuildLoopHeaderEnvironment(current_offset);
1431
1432    switch (bytecode_iterator().current_bytecode()) {
1433#define BYTECODE_CASE(name, ...)       \
1434  case interpreter::Bytecode::k##name: \
1435    Visit##name();                     \
1436    break;
1437      BYTECODE_LIST(BYTECODE_CASE)
1438#undef BYTECODE_CASE
1439    }
1440  }
1441}
1442
1443void BytecodeGraphBuilder::VisitBytecodes() {
1444  if (!bytecode_analysis().resume_jump_targets().empty()) {
1445    environment()->BindGeneratorState(
1446        jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
1447  }
1448
1449  if (osr_) {
1450    // We peel the OSR loop and any outer loop containing it except that we
1451    // leave the nodes corresponding to the whole outermost loop (including
1452    // the last copies of the loops it contains) to be generated by the normal
1453    // bytecode iteration below.
1454    AdvanceToOsrEntryAndPeelLoops();
1455  } else {
1456    BuildFunctionEntryStackCheck();
1457  }
1458
1459  for (; !bytecode_iterator().done(); bytecode_iterator().Advance()) {
1460    VisitSingleBytecode();
1461  }
1462
1463  DCHECK(exception_handlers_.empty());
1464}
1465
1466void BytecodeGraphBuilder::VisitLdaZero() {
1467  Node* node = jsgraph()->ZeroConstant();
1468  environment()->BindAccumulator(node);
1469}
1470
1471void BytecodeGraphBuilder::VisitLdaSmi() {
1472  Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
1473  environment()->BindAccumulator(node);
1474}
1475
1476void BytecodeGraphBuilder::VisitLdaConstant() {
1477  ObjectRef object = MakeRefForConstantForIndexOperand(0);
1478  Node* node = jsgraph()->Constant(object);
1479  environment()->BindAccumulator(node);
1480}
1481
1482void BytecodeGraphBuilder::VisitLdaUndefined() {
1483  Node* node = jsgraph()->UndefinedConstant();
1484  environment()->BindAccumulator(node);
1485}
1486
1487void BytecodeGraphBuilder::VisitLdaNull() {
1488  Node* node = jsgraph()->NullConstant();
1489  environment()->BindAccumulator(node);
1490}
1491
1492void BytecodeGraphBuilder::VisitLdaTheHole() {
1493  Node* node = jsgraph()->TheHoleConstant();
1494  environment()->BindAccumulator(node);
1495}
1496
1497void BytecodeGraphBuilder::VisitLdaTrue() {
1498  Node* node = jsgraph()->TrueConstant();
1499  environment()->BindAccumulator(node);
1500}
1501
1502void BytecodeGraphBuilder::VisitLdaFalse() {
1503  Node* node = jsgraph()->FalseConstant();
1504  environment()->BindAccumulator(node);
1505}
1506
1507void BytecodeGraphBuilder::VisitLdar() {
1508  Node* value =
1509      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1510  environment()->BindAccumulator(value);
1511}
1512
1513void BytecodeGraphBuilder::VisitStar() {
1514  Node* value = environment()->LookupAccumulator();
1515  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
1516}
1517
1518#define SHORT_STAR_VISITOR(Name, ...)                                         \
1519  void BytecodeGraphBuilder::Visit##Name() {                                  \
1520    Node* value = environment()->LookupAccumulator();                         \
1521    environment()->BindRegister(                                              \
1522        interpreter::Register::FromShortStar(interpreter::Bytecode::k##Name), \
1523        value);                                                               \
1524  }
1525SHORT_STAR_BYTECODE_LIST(SHORT_STAR_VISITOR)
1526#undef SHORT_STAR_VISITOR
1527
1528void BytecodeGraphBuilder::VisitMov() {
1529  Node* value =
1530      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1531  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
1532}
1533
1534Node* BytecodeGraphBuilder::BuildLoadGlobal(NameRef name,
1535                                            uint32_t feedback_slot_index,
1536                                            TypeofMode typeof_mode) {
1537  FeedbackSource feedback = CreateFeedbackSource(feedback_slot_index);
1538  DCHECK(IsLoadGlobalICKind(broker()->GetFeedbackSlotKind(feedback)));
1539  const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
1540  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1541  return NewNode(op, feedback_vector_node());
1542}
1543
1544void BytecodeGraphBuilder::VisitLdaGlobal() {
1545  PrepareEagerCheckpoint();
1546  NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
1547  uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
1548  Node* node =
1549      BuildLoadGlobal(name, feedback_slot_index, TypeofMode::kNotInside);
1550  environment()->BindAccumulator(node, Environment::kAttachFrameState);
1551}
1552
1553void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
1554  PrepareEagerCheckpoint();
1555  NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
1556  uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
1557  Node* node = BuildLoadGlobal(name, feedback_slot_index, TypeofMode::kInside);
1558  environment()->BindAccumulator(node, Environment::kAttachFrameState);
1559}
1560
1561void BytecodeGraphBuilder::VisitStaGlobal() {
1562  PrepareEagerCheckpoint();
1563  NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
1564  FeedbackSource feedback =
1565      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
1566  Node* value = environment()->LookupAccumulator();
1567
1568  LanguageMode language_mode =
1569      GetLanguageModeFromSlotKind(broker()->GetFeedbackSlotKind(feedback));
1570  const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
1571  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1572  Node* node = NewNode(op, value, feedback_vector_node());
1573  environment()->RecordAfterState(node, Environment::kAttachFrameState);
1574}
1575
1576void BytecodeGraphBuilder::VisitStaInArrayLiteral() {
1577  PrepareEagerCheckpoint();
1578  Node* value = environment()->LookupAccumulator();
1579  Node* array =
1580      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1581  Node* index =
1582      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1583  FeedbackSource feedback =
1584      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
1585  const Operator* op = javascript()->StoreInArrayLiteral(feedback);
1586
1587  JSTypeHintLowering::LoweringResult lowering =
1588      TryBuildSimplifiedStoreKeyed(op, array, index, value, feedback.slot);
1589  if (lowering.IsExit()) return;
1590
1591  Node* node = nullptr;
1592  if (lowering.IsSideEffectFree()) {
1593    node = lowering.value();
1594  } else {
1595    DCHECK(!lowering.Changed());
1596    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1597    node = NewNode(op, array, index, value, feedback_vector_node());
1598  }
1599
1600  environment()->RecordAfterState(node, Environment::kAttachFrameState);
1601}
1602
1603void BytecodeGraphBuilder::VisitDefineKeyedOwnPropertyInLiteral() {
1604  PrepareEagerCheckpoint();
1605
1606  Node* object =
1607      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1608  Node* name =
1609      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1610  Node* value = environment()->LookupAccumulator();
1611  int flags = bytecode_iterator().GetFlagOperand(2);
1612  FeedbackSource feedback =
1613      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(3));
1614  const Operator* op = javascript()->DefineKeyedOwnPropertyInLiteral(feedback);
1615
1616  JSTypeHintLowering::LoweringResult lowering =
1617      TryBuildSimplifiedStoreKeyed(op, object, name, value, feedback.slot);
1618  if (lowering.IsExit()) return;
1619
1620  Node* node = nullptr;
1621  if (lowering.IsSideEffectFree()) {
1622    node = lowering.value();
1623  } else {
1624    DCHECK(!lowering.Changed());
1625    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1626    node = NewNode(op, object, name, value, jsgraph()->Constant(flags),
1627                   feedback_vector_node());
1628  }
1629
1630  environment()->RecordAfterState(node, Environment::kAttachFrameState);
1631}
1632
1633void BytecodeGraphBuilder::VisitCollectTypeProfile() {
1634  PrepareEagerCheckpoint();
1635
1636  Node* position =
1637      jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
1638  Node* value = environment()->LookupAccumulator();
1639  Node* vector = jsgraph()->Constant(feedback_vector());
1640
1641  const Operator* op = javascript()->CallRuntime(Runtime::kCollectTypeProfile);
1642
1643  Node* node = NewNode(op, position, value, vector);
1644  environment()->RecordAfterState(node, Environment::kAttachFrameState);
1645}
1646
1647void BytecodeGraphBuilder::VisitLdaContextSlot() {
1648  const Operator* op = javascript()->LoadContext(
1649      bytecode_iterator().GetUnsignedImmediateOperand(2),
1650      bytecode_iterator().GetIndexOperand(1), false);
1651  Node* node = NewNode(op);
1652  Node* context =
1653      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1654  NodeProperties::ReplaceContextInput(node, context);
1655  environment()->BindAccumulator(node);
1656}
1657
1658void BytecodeGraphBuilder::VisitLdaImmutableContextSlot() {
1659  const Operator* op = javascript()->LoadContext(
1660      bytecode_iterator().GetUnsignedImmediateOperand(2),
1661      bytecode_iterator().GetIndexOperand(1), true);
1662  Node* node = NewNode(op);
1663  Node* context =
1664      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1665  NodeProperties::ReplaceContextInput(node, context);
1666  environment()->BindAccumulator(node);
1667}
1668
1669void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
1670  const Operator* op = javascript()->LoadContext(
1671      0, bytecode_iterator().GetIndexOperand(0), false);
1672  Node* node = NewNode(op);
1673  environment()->BindAccumulator(node);
1674}
1675
1676void BytecodeGraphBuilder::VisitLdaImmutableCurrentContextSlot() {
1677  const Operator* op = javascript()->LoadContext(
1678      0, bytecode_iterator().GetIndexOperand(0), true);
1679  Node* node = NewNode(op);
1680  environment()->BindAccumulator(node);
1681}
1682
1683void BytecodeGraphBuilder::VisitStaContextSlot() {
1684  const Operator* op = javascript()->StoreContext(
1685      bytecode_iterator().GetUnsignedImmediateOperand(2),
1686      bytecode_iterator().GetIndexOperand(1));
1687  Node* value = environment()->LookupAccumulator();
1688  Node* node = NewNode(op, value);
1689  Node* context =
1690      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1691  NodeProperties::ReplaceContextInput(node, context);
1692}
1693
1694void BytecodeGraphBuilder::VisitStaCurrentContextSlot() {
1695  const Operator* op =
1696      javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0));
1697  Node* value = environment()->LookupAccumulator();
1698  NewNode(op, value);
1699}
1700
1701void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
1702  PrepareEagerCheckpoint();
1703  Node* name = jsgraph()->Constant(MakeRefForConstantForIndexOperand(0));
1704  const Operator* op =
1705      javascript()->CallRuntime(typeof_mode == TypeofMode::kNotInside
1706                                    ? Runtime::kLoadLookupSlot
1707                                    : Runtime::kLoadLookupSlotInsideTypeof);
1708  Node* value = NewNode(op, name);
1709  environment()->BindAccumulator(value, Environment::kAttachFrameState);
1710}
1711
1712void BytecodeGraphBuilder::VisitLdaLookupSlot() {
1713  BuildLdaLookupSlot(TypeofMode::kNotInside);
1714}
1715
1716void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
1717  BuildLdaLookupSlot(TypeofMode::kInside);
1718}
1719
1720BytecodeGraphBuilder::Environment*
1721BytecodeGraphBuilder::CheckContextExtensionAtDepth(
1722    Environment* slow_environment, uint32_t depth) {
1723  Node* extension_slot = NewNode(
1724      javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false));
1725  Node* check_no_extension =
1726      NewNode(simplified()->ReferenceEqual(), extension_slot,
1727              jsgraph()->UndefinedConstant());
1728  NewBranch(check_no_extension);
1729  {
1730    SubEnvironment sub_environment(this);
1731    NewIfFalse();
1732    // If there is an extension, merge into the slow path.
1733    if (slow_environment == nullptr) {
1734      slow_environment = environment();
1735      NewMerge();
1736    } else {
1737      slow_environment->Merge(environment(),
1738                              bytecode_analysis().GetInLivenessFor(
1739                                  bytecode_iterator().current_offset()));
1740    }
1741  }
1742  NewIfTrue();
1743  // Do nothing on if there is no extension, eventually falling through to
1744  // the fast path.
1745  DCHECK_NOT_NULL(slow_environment);
1746  return slow_environment;
1747}
1748
1749base::Optional<ScopeInfoRef> BytecodeGraphBuilder::TryGetScopeInfo() {
1750  Node* context = environment()->Context();
1751  switch (context->opcode()) {
1752    case IrOpcode::kJSCreateFunctionContext:
1753      return CreateFunctionContextParametersOf(context->op())
1754          .scope_info(broker());
1755    case IrOpcode::kJSCreateBlockContext:
1756    case IrOpcode::kJSCreateCatchContext:
1757    case IrOpcode::kJSCreateWithContext:
1758      return ScopeInfoOf(broker(), context->op());
1759    case IrOpcode::kParameter: {
1760      ScopeInfoRef scope_info = shared_info_.scope_info();
1761      if (scope_info.HasOuterScopeInfo()) {
1762        scope_info = scope_info.OuterScopeInfo();
1763      }
1764      return scope_info;
1765    }
1766    default:
1767      return base::nullopt;
1768  }
1769}
1770
1771BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
1772    uint32_t depth) {
1773  base::Optional<ScopeInfoRef> maybe_scope_info = TryGetScopeInfo();
1774  if (!maybe_scope_info.has_value()) {
1775    return CheckContextExtensionsSlowPath(depth);
1776  }
1777
1778  ScopeInfoRef scope_info = maybe_scope_info.value();
1779  // We only need to check up to the last-but-one depth, because an eval
1780  // in the same scope as the variable itself has no way of shadowing it.
1781  Environment* slow_environment = nullptr;
1782  for (uint32_t d = 0; d < depth; d++) {
1783    if (scope_info.HasContextExtensionSlot()) {
1784      slow_environment = CheckContextExtensionAtDepth(slow_environment, d);
1785    }
1786    DCHECK_IMPLIES(!scope_info.HasOuterScopeInfo(), d + 1 == depth);
1787    if (scope_info.HasOuterScopeInfo()) {
1788      scope_info = scope_info.OuterScopeInfo();
1789    }
1790  }
1791
1792  // The depth can be zero, in which case no slow-path checks are built, and
1793  // the slow path environment can be null.
1794  DCHECK_IMPLIES(slow_environment == nullptr, depth == 0);
1795  return slow_environment;
1796}
1797
1798BytecodeGraphBuilder::Environment*
1799BytecodeGraphBuilder::CheckContextExtensionsSlowPath(uint32_t depth) {
1800  // Output environment where the context has an extension
1801  Environment* slow_environment = nullptr;
1802
1803  // We only need to check up to the last-but-one depth, because an eval
1804  // in the same scope as the variable itself has no way of shadowing it.
1805  for (uint32_t d = 0; d < depth; d++) {
1806    Node* has_extension = NewNode(javascript()->HasContextExtension(d));
1807
1808    Environment* undefined_extension_env;
1809    NewBranch(has_extension);
1810    {
1811      SubEnvironment sub_environment(this);
1812      NewIfTrue();
1813      slow_environment = CheckContextExtensionAtDepth(slow_environment, d);
1814      undefined_extension_env = environment();
1815    }
1816    NewIfFalse();
1817    environment()->Merge(undefined_extension_env,
1818                         bytecode_analysis().GetInLivenessFor(
1819                             bytecode_iterator().current_offset()));
1820    mark_as_needing_eager_checkpoint(true);
1821    // Do nothing on if there is no extension, eventually falling through to
1822    // the fast path.
1823  }
1824
1825  // The depth can be zero, in which case no slow-path checks are built, and
1826  // the slow path environment can be null.
1827  DCHECK_IMPLIES(slow_environment == nullptr, depth == 0);
1828  return slow_environment;
1829}
1830
1831void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
1832  uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
1833
1834  // Check if any context in the depth has an extension.
1835  Environment* slow_environment = CheckContextExtensions(depth);
1836
1837  // Fast path, do a context load.
1838  {
1839    uint32_t slot_index = bytecode_iterator().GetIndexOperand(1);
1840
1841    const Operator* op = javascript()->LoadContext(depth, slot_index, false);
1842    environment()->BindAccumulator(NewNode(op));
1843  }
1844
1845  // Only build the slow path if there were any slow-path checks.
1846  if (slow_environment != nullptr) {
1847    // Add a merge to the fast environment.
1848    NewMerge();
1849    Environment* fast_environment = environment();
1850
1851    // Slow path, do a runtime load lookup.
1852    set_environment(slow_environment);
1853    {
1854      Node* name = jsgraph()->Constant(MakeRefForConstantForIndexOperand(0));
1855
1856      const Operator* op =
1857          javascript()->CallRuntime(typeof_mode == TypeofMode::kNotInside
1858                                        ? Runtime::kLoadLookupSlot
1859                                        : Runtime::kLoadLookupSlotInsideTypeof);
1860      Node* value = NewNode(op, name);
1861      environment()->BindAccumulator(value, Environment::kAttachFrameState);
1862    }
1863
1864    fast_environment->Merge(environment(),
1865                            bytecode_analysis().GetOutLivenessFor(
1866                                bytecode_iterator().current_offset()));
1867    set_environment(fast_environment);
1868    mark_as_needing_eager_checkpoint(true);
1869  }
1870}
1871
1872void BytecodeGraphBuilder::VisitLdaLookupContextSlot() {
1873  BuildLdaLookupContextSlot(TypeofMode::kNotInside);
1874}
1875
1876void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() {
1877  BuildLdaLookupContextSlot(TypeofMode::kInside);
1878}
1879
1880void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
1881  uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
1882
1883  // Check if any context in the depth has an extension.
1884  Environment* slow_environment = CheckContextExtensions(depth);
1885
1886  // Fast path, do a global load.
1887  {
1888    PrepareEagerCheckpoint();
1889    NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
1890    uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
1891    Node* node = BuildLoadGlobal(name, feedback_slot_index, typeof_mode);
1892    environment()->BindAccumulator(node, Environment::kAttachFrameState);
1893  }
1894
1895  // Only build the slow path if there were any slow-path checks.
1896  if (slow_environment != nullptr) {
1897    // Add a merge to the fast environment.
1898    NewMerge();
1899    Environment* fast_environment = environment();
1900
1901    // Slow path, do a runtime load lookup.
1902    set_environment(slow_environment);
1903    {
1904      Node* name =
1905          jsgraph()->Constant(MakeRefForConstantForIndexOperand<Name>(0));
1906
1907      const Operator* op =
1908          javascript()->CallRuntime(typeof_mode == TypeofMode::kNotInside
1909                                        ? Runtime::kLoadLookupSlot
1910                                        : Runtime::kLoadLookupSlotInsideTypeof);
1911      Node* value = NewNode(op, name);
1912      environment()->BindAccumulator(value, Environment::kAttachFrameState);
1913    }
1914
1915    fast_environment->Merge(environment(),
1916                            bytecode_analysis().GetOutLivenessFor(
1917                                bytecode_iterator().current_offset()));
1918    set_environment(fast_environment);
1919    mark_as_needing_eager_checkpoint(true);
1920  }
1921}
1922
1923void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() {
1924  BuildLdaLookupGlobalSlot(TypeofMode::kNotInside);
1925}
1926
1927void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
1928  BuildLdaLookupGlobalSlot(TypeofMode::kInside);
1929}
1930
1931void BytecodeGraphBuilder::VisitStaLookupSlot() {
1932  PrepareEagerCheckpoint();
1933  Node* value = environment()->LookupAccumulator();
1934  Node* name = jsgraph()->Constant(MakeRefForConstantForIndexOperand(0));
1935  int bytecode_flags = bytecode_iterator().GetFlagOperand(1);
1936  LanguageMode language_mode = static_cast<LanguageMode>(
1937      interpreter::StoreLookupSlotFlags::LanguageModeBit::decode(
1938          bytecode_flags));
1939  LookupHoistingMode lookup_hoisting_mode = static_cast<LookupHoistingMode>(
1940      interpreter::StoreLookupSlotFlags::LookupHoistingModeBit::decode(
1941          bytecode_flags));
1942  DCHECK_IMPLIES(lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy,
1943                 is_sloppy(language_mode));
1944  const Operator* op = javascript()->CallRuntime(
1945      is_strict(language_mode)
1946          ? Runtime::kStoreLookupSlot_Strict
1947          : lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy
1948                ? Runtime::kStoreLookupSlot_SloppyHoisting
1949                : Runtime::kStoreLookupSlot_Sloppy);
1950  Node* store = NewNode(op, name, value);
1951  environment()->BindAccumulator(store, Environment::kAttachFrameState);
1952}
1953
1954void BytecodeGraphBuilder::VisitGetNamedProperty() {
1955  PrepareEagerCheckpoint();
1956  Node* object =
1957      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1958  NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
1959  FeedbackSource feedback =
1960      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
1961  const Operator* op = javascript()->LoadNamed(name, feedback);
1962
1963  JSTypeHintLowering::LoweringResult lowering =
1964      TryBuildSimplifiedLoadNamed(op, feedback.slot);
1965  if (lowering.IsExit()) return;
1966
1967  Node* node = nullptr;
1968  if (lowering.IsSideEffectFree()) {
1969    node = lowering.value();
1970  } else {
1971    DCHECK(!lowering.Changed());
1972    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1973    node = NewNode(op, object, feedback_vector_node());
1974  }
1975  environment()->BindAccumulator(node, Environment::kAttachFrameState);
1976}
1977
1978void BytecodeGraphBuilder::VisitGetNamedPropertyFromSuper() {
1979  PrepareEagerCheckpoint();
1980  Node* receiver =
1981      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1982  Node* home_object = environment()->LookupAccumulator();
1983  NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
1984
1985  FeedbackSource feedback =
1986      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
1987  const Operator* op = javascript()->LoadNamedFromSuper(name, feedback);
1988
1989  JSTypeHintLowering::LoweringResult lowering =
1990      TryBuildSimplifiedLoadNamed(op, feedback.slot);
1991  if (lowering.IsExit()) return;
1992
1993  Node* node = nullptr;
1994  if (lowering.IsSideEffectFree()) {
1995    node = lowering.value();
1996  } else {
1997    DCHECK(!lowering.Changed());
1998    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1999    node = NewNode(op, receiver, home_object, feedback_vector_node());
2000  }
2001  environment()->BindAccumulator(node, Environment::kAttachFrameState);
2002}
2003
2004void BytecodeGraphBuilder::VisitGetKeyedProperty() {
2005  PrepareEagerCheckpoint();
2006  Node* key = environment()->LookupAccumulator();
2007  Node* object =
2008      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2009  FeedbackSource feedback =
2010      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
2011  const Operator* op = javascript()->LoadProperty(feedback);
2012
2013  JSTypeHintLowering::LoweringResult lowering =
2014      TryBuildSimplifiedLoadKeyed(op, object, key, feedback.slot);
2015  if (lowering.IsExit()) return;
2016
2017  Node* node = nullptr;
2018  if (lowering.IsSideEffectFree()) {
2019    node = lowering.value();
2020  } else {
2021    DCHECK(!lowering.Changed());
2022    STATIC_ASSERT(JSLoadPropertyNode::ObjectIndex() == 0);
2023    STATIC_ASSERT(JSLoadPropertyNode::KeyIndex() == 1);
2024    STATIC_ASSERT(JSLoadPropertyNode::FeedbackVectorIndex() == 2);
2025    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2026    node = NewNode(op, object, key, feedback_vector_node());
2027  }
2028  environment()->BindAccumulator(node, Environment::kAttachFrameState);
2029}
2030
2031void BytecodeGraphBuilder::BuildNamedStore(NamedStoreMode store_mode) {
2032  PrepareEagerCheckpoint();
2033  Node* value = environment()->LookupAccumulator();
2034  Node* object =
2035      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2036  NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
2037  FeedbackSource feedback =
2038      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
2039
2040  const Operator* op;
2041  if (store_mode == NamedStoreMode::kDefineOwn) {
2042    DCHECK_EQ(FeedbackSlotKind::kDefineNamedOwn,
2043              broker()->GetFeedbackSlotKind(feedback));
2044
2045    op = javascript()->DefineNamedOwnProperty(name, feedback);
2046  } else {
2047    DCHECK_EQ(NamedStoreMode::kSet, store_mode);
2048    LanguageMode language_mode =
2049        GetLanguageModeFromSlotKind(broker()->GetFeedbackSlotKind(feedback));
2050    op = javascript()->SetNamedProperty(language_mode, name, feedback);
2051  }
2052
2053  JSTypeHintLowering::LoweringResult lowering =
2054      TryBuildSimplifiedStoreNamed(op, object, value, feedback.slot);
2055  if (lowering.IsExit()) return;
2056
2057  Node* node = nullptr;
2058  if (lowering.IsSideEffectFree()) {
2059    node = lowering.value();
2060  } else {
2061    DCHECK(!lowering.Changed());
2062    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2063    node = NewNode(op, object, value, feedback_vector_node());
2064  }
2065  environment()->RecordAfterState(node, Environment::kAttachFrameState);
2066}
2067
2068void BytecodeGraphBuilder::VisitSetNamedProperty() {
2069  BuildNamedStore(NamedStoreMode::kSet);
2070}
2071
2072void BytecodeGraphBuilder::VisitDefineNamedOwnProperty() {
2073  BuildNamedStore(NamedStoreMode::kDefineOwn);
2074}
2075
2076void BytecodeGraphBuilder::VisitSetKeyedProperty() {
2077  PrepareEagerCheckpoint();
2078  Node* value = environment()->LookupAccumulator();
2079  Node* object =
2080      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2081  Node* key =
2082      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2083  FeedbackSource source =
2084      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
2085  LanguageMode language_mode =
2086      GetLanguageModeFromSlotKind(broker()->GetFeedbackSlotKind(source));
2087  const Operator* op = javascript()->SetKeyedProperty(language_mode, source);
2088
2089  JSTypeHintLowering::LoweringResult lowering =
2090      TryBuildSimplifiedStoreKeyed(op, object, key, value, source.slot);
2091  if (lowering.IsExit()) return;
2092
2093  Node* node = nullptr;
2094  if (lowering.IsSideEffectFree()) {
2095    node = lowering.value();
2096  } else {
2097    DCHECK(!lowering.Changed());
2098    STATIC_ASSERT(JSSetKeyedPropertyNode::ObjectIndex() == 0);
2099    STATIC_ASSERT(JSSetKeyedPropertyNode::KeyIndex() == 1);
2100    STATIC_ASSERT(JSSetKeyedPropertyNode::ValueIndex() == 2);
2101    STATIC_ASSERT(JSSetKeyedPropertyNode::FeedbackVectorIndex() == 3);
2102    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2103    node = NewNode(op, object, key, value, feedback_vector_node());
2104  }
2105
2106  environment()->RecordAfterState(node, Environment::kAttachFrameState);
2107}
2108
2109void BytecodeGraphBuilder::VisitDefineKeyedOwnProperty() {
2110  PrepareEagerCheckpoint();
2111  Node* value = environment()->LookupAccumulator();
2112  Node* object =
2113      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2114  Node* key =
2115      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2116  FeedbackSource source =
2117      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
2118  LanguageMode language_mode =
2119      GetLanguageModeFromSlotKind(broker()->GetFeedbackSlotKind(source));
2120
2121  const Operator* op =
2122      javascript()->DefineKeyedOwnProperty(language_mode, source);
2123
2124  JSTypeHintLowering::LoweringResult lowering =
2125      TryBuildSimplifiedStoreKeyed(op, object, key, value, source.slot);
2126  if (lowering.IsExit()) return;
2127
2128  Node* node = nullptr;
2129  if (lowering.IsSideEffectFree()) {
2130    node = lowering.value();
2131  } else {
2132    DCHECK(!lowering.Changed());
2133    STATIC_ASSERT(JSDefineKeyedOwnPropertyNode::ObjectIndex() == 0);
2134    STATIC_ASSERT(JSDefineKeyedOwnPropertyNode::KeyIndex() == 1);
2135    STATIC_ASSERT(JSDefineKeyedOwnPropertyNode::ValueIndex() == 2);
2136    STATIC_ASSERT(JSDefineKeyedOwnPropertyNode::FeedbackVectorIndex() == 3);
2137    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2138    node = NewNode(op, object, key, value, feedback_vector_node());
2139  }
2140
2141  environment()->RecordAfterState(node, Environment::kAttachFrameState);
2142}
2143
2144void BytecodeGraphBuilder::VisitLdaModuleVariable() {
2145  int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
2146  uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
2147  Node* module =
2148      NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
2149  Node* value = NewNode(javascript()->LoadModule(cell_index), module);
2150  environment()->BindAccumulator(value);
2151}
2152
2153void BytecodeGraphBuilder::VisitStaModuleVariable() {
2154  int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
2155  uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
2156  Node* module =
2157      NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
2158  Node* value = environment()->LookupAccumulator();
2159  NewNode(javascript()->StoreModule(cell_index), module, value);
2160}
2161
2162void BytecodeGraphBuilder::VisitPushContext() {
2163  Node* new_context = environment()->LookupAccumulator();
2164  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
2165                              environment()->Context());
2166  environment()->SetContext(new_context);
2167}
2168
2169void BytecodeGraphBuilder::VisitPopContext() {
2170  Node* context =
2171      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2172  environment()->SetContext(context);
2173}
2174
2175void BytecodeGraphBuilder::VisitCreateClosure() {
2176  SharedFunctionInfoRef shared_info =
2177      MakeRefForConstantForIndexOperand<SharedFunctionInfo>(0);
2178  AllocationType allocation =
2179      interpreter::CreateClosureFlags::PretenuredBit::decode(
2180          bytecode_iterator().GetFlagOperand(2))
2181          ? AllocationType::kOld
2182          : AllocationType::kYoung;
2183  CodeTRef compile_lazy =
2184      MakeRef(broker(), *BUILTIN_CODE(jsgraph()->isolate(), CompileLazy));
2185  const Operator* op =
2186      javascript()->CreateClosure(shared_info, compile_lazy, allocation);
2187  Node* closure = NewNode(
2188      op, BuildLoadFeedbackCell(bytecode_iterator().GetIndexOperand(1)));
2189  environment()->BindAccumulator(closure);
2190}
2191
2192void BytecodeGraphBuilder::VisitCreateBlockContext() {
2193  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
2194  const Operator* op = javascript()->CreateBlockContext(scope_info);
2195  Node* context = NewNode(op);
2196  environment()->BindAccumulator(context);
2197}
2198
2199void BytecodeGraphBuilder::VisitCreateFunctionContext() {
2200  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
2201  uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
2202  const Operator* op =
2203      javascript()->CreateFunctionContext(scope_info, slots, FUNCTION_SCOPE);
2204  Node* context = NewNode(op);
2205  environment()->BindAccumulator(context);
2206}
2207
2208void BytecodeGraphBuilder::VisitCreateEvalContext() {
2209  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
2210  uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
2211  const Operator* op =
2212      javascript()->CreateFunctionContext(scope_info, slots, EVAL_SCOPE);
2213  Node* context = NewNode(op);
2214  environment()->BindAccumulator(context);
2215}
2216
2217void BytecodeGraphBuilder::VisitCreateCatchContext() {
2218  interpreter::Register reg = bytecode_iterator().GetRegisterOperand(0);
2219  Node* exception = environment()->LookupRegister(reg);
2220  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(1);
2221
2222  const Operator* op = javascript()->CreateCatchContext(scope_info);
2223  Node* context = NewNode(op, exception);
2224  environment()->BindAccumulator(context);
2225}
2226
2227void BytecodeGraphBuilder::VisitCreateWithContext() {
2228  Node* object =
2229      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2230  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(1);
2231
2232  const Operator* op = javascript()->CreateWithContext(scope_info);
2233  Node* context = NewNode(op, object);
2234  environment()->BindAccumulator(context);
2235}
2236
2237void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
2238  const Operator* op = javascript()->CreateArguments(type);
2239  Node* object = NewNode(op, GetFunctionClosure());
2240  environment()->BindAccumulator(object, Environment::kAttachFrameState);
2241}
2242
2243void BytecodeGraphBuilder::VisitCreateMappedArguments() {
2244  BuildCreateArguments(CreateArgumentsType::kMappedArguments);
2245}
2246
2247void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
2248  BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
2249}
2250
2251void BytecodeGraphBuilder::VisitCreateRestParameter() {
2252  BuildCreateArguments(CreateArgumentsType::kRestParameter);
2253}
2254
2255void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
2256  StringRef constant_pattern = MakeRefForConstantForIndexOperand<String>(0);
2257  int const slot_id = bytecode_iterator().GetIndexOperand(1);
2258  FeedbackSource pair = CreateFeedbackSource(slot_id);
2259  int literal_flags = bytecode_iterator().GetFlagOperand(2);
2260  STATIC_ASSERT(JSCreateLiteralRegExpNode::FeedbackVectorIndex() == 0);
2261  const Operator* op =
2262      javascript()->CreateLiteralRegExp(constant_pattern, pair, literal_flags);
2263  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2264  Node* literal = NewNode(op, feedback_vector_node());
2265  environment()->BindAccumulator(literal, Environment::kAttachFrameState);
2266}
2267
2268void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
2269  ArrayBoilerplateDescriptionRef array_boilerplate_description =
2270      MakeRefForConstantForIndexOperand<ArrayBoilerplateDescription>(0);
2271  int const slot_id = bytecode_iterator().GetIndexOperand(1);
2272  FeedbackSource pair = CreateFeedbackSource(slot_id);
2273  int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
2274  int literal_flags =
2275      interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
2276  // Disable allocation site mementos. Only unoptimized code will collect
2277  // feedback about allocation site. Once the code is optimized we expect the
2278  // data to converge. So, we disable allocation site mementos in optimized
2279  // code. We can revisit this when we have data to the contrary.
2280  literal_flags |= ArrayLiteral::kDisableMementos;
2281  int number_of_elements =
2282      array_boilerplate_description.constants_elements_length();
2283  STATIC_ASSERT(JSCreateLiteralArrayNode::FeedbackVectorIndex() == 0);
2284  const Operator* op = javascript()->CreateLiteralArray(
2285      array_boilerplate_description, pair, literal_flags, number_of_elements);
2286  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2287  Node* literal = NewNode(op, feedback_vector_node());
2288  environment()->BindAccumulator(literal, Environment::kAttachFrameState);
2289}
2290
2291void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
2292  int const slot_id = bytecode_iterator().GetIndexOperand(0);
2293  FeedbackSource pair = CreateFeedbackSource(slot_id);
2294  const Operator* op = javascript()->CreateEmptyLiteralArray(pair);
2295  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2296  Node* literal = NewNode(op, feedback_vector_node());
2297  environment()->BindAccumulator(literal);
2298}
2299
2300void BytecodeGraphBuilder::VisitCreateArrayFromIterable() {
2301  Node* iterable = NewNode(javascript()->CreateArrayFromIterable(),
2302                           environment()->LookupAccumulator());
2303  environment()->BindAccumulator(iterable, Environment::kAttachFrameState);
2304}
2305
2306void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
2307  ObjectBoilerplateDescriptionRef constant_properties =
2308      MakeRefForConstantForIndexOperand<ObjectBoilerplateDescription>(0);
2309  int const slot_id = bytecode_iterator().GetIndexOperand(1);
2310  FeedbackSource pair = CreateFeedbackSource(slot_id);
2311  int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
2312  int literal_flags =
2313      interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
2314  int number_of_properties = constant_properties.size();
2315  STATIC_ASSERT(JSCreateLiteralObjectNode::FeedbackVectorIndex() == 0);
2316  const Operator* op = javascript()->CreateLiteralObject(
2317      constant_properties, pair, literal_flags, number_of_properties);
2318  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2319  Node* literal = NewNode(op, feedback_vector_node());
2320  environment()->BindAccumulator(literal, Environment::kAttachFrameState);
2321}
2322
2323void BytecodeGraphBuilder::VisitCreateEmptyObjectLiteral() {
2324  Node* literal = NewNode(javascript()->CreateEmptyLiteralObject());
2325  environment()->BindAccumulator(literal);
2326}
2327
2328void BytecodeGraphBuilder::VisitCloneObject() {
2329  PrepareEagerCheckpoint();
2330  Node* source =
2331      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2332  int flags = bytecode_iterator().GetFlagOperand(1);
2333  int slot = bytecode_iterator().GetIndexOperand(2);
2334  const Operator* op =
2335      javascript()->CloneObject(CreateFeedbackSource(slot), flags);
2336  STATIC_ASSERT(JSCloneObjectNode::SourceIndex() == 0);
2337  STATIC_ASSERT(JSCloneObjectNode::FeedbackVectorIndex() == 1);
2338  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2339  Node* value = NewNode(op, source, feedback_vector_node());
2340  environment()->BindAccumulator(value, Environment::kAttachFrameState);
2341}
2342
2343void BytecodeGraphBuilder::VisitGetTemplateObject() {
2344  FeedbackSource source =
2345      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
2346  TemplateObjectDescriptionRef description =
2347      MakeRefForConstantForIndexOperand<TemplateObjectDescription>(0);
2348  STATIC_ASSERT(JSGetTemplateObjectNode::FeedbackVectorIndex() == 0);
2349  const Operator* op =
2350      javascript()->GetTemplateObject(description, shared_info(), source);
2351  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2352  Node* template_object = NewNode(op, feedback_vector_node());
2353  environment()->BindAccumulator(template_object);
2354}
2355
2356Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
2357    Node* callee, Node* receiver, interpreter::Register first_arg,
2358    int arg_count) {
2359  const int arity = JSCallNode::ArityForArgc(arg_count);
2360  Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
2361  int cursor = 0;
2362
2363  STATIC_ASSERT(JSCallNode::TargetIndex() == 0);
2364  STATIC_ASSERT(JSCallNode::ReceiverIndex() == 1);
2365  STATIC_ASSERT(JSCallNode::FirstArgumentIndex() == 2);
2366  STATIC_ASSERT(JSCallNode::kFeedbackVectorIsLastInput);
2367
2368  all[cursor++] = callee;
2369  all[cursor++] = receiver;
2370
2371  // The function arguments are in consecutive registers.
2372  const int arg_base = first_arg.index();
2373  for (int i = 0; i < arg_count; ++i) {
2374    all[cursor++] =
2375        environment()->LookupRegister(interpreter::Register(arg_base + i));
2376  }
2377
2378  all[cursor++] = feedback_vector_node();
2379
2380  DCHECK_EQ(cursor, arity);
2381  return all;
2382}
2383
2384void BytecodeGraphBuilder::BuildCall(ConvertReceiverMode receiver_mode,
2385                                     Node* const* args, size_t arg_count,
2386                                     int slot_id) {
2387  DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
2388                bytecode_iterator().current_bytecode()),
2389            receiver_mode);
2390  PrepareEagerCheckpoint();
2391
2392  FeedbackSource feedback = CreateFeedbackSource(slot_id);
2393  CallFrequency frequency = ComputeCallFrequency(slot_id);
2394  SpeculationMode speculation_mode = GetSpeculationMode(slot_id);
2395  CallFeedbackRelation call_feedback_relation =
2396      ComputeCallFeedbackRelation(slot_id);
2397  const Operator* op =
2398      javascript()->Call(arg_count, frequency, feedback, receiver_mode,
2399                         speculation_mode, call_feedback_relation);
2400  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2401
2402  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
2403      op, args, static_cast<int>(arg_count), feedback.slot);
2404  if (lowering.IsExit()) return;
2405
2406  Node* node = nullptr;
2407  if (lowering.IsSideEffectFree()) {
2408    node = lowering.value();
2409  } else {
2410    DCHECK(!lowering.Changed());
2411    node = MakeNode(op, static_cast<int>(arg_count), args);
2412  }
2413  environment()->BindAccumulator(node, Environment::kAttachFrameState);
2414}
2415
2416Node* const* BytecodeGraphBuilder::ProcessCallVarArgs(
2417    ConvertReceiverMode receiver_mode, Node* callee,
2418    interpreter::Register first_reg, int arg_count) {
2419  DCHECK_GE(arg_count, 0);
2420  Node* receiver_node;
2421  interpreter::Register first_arg;
2422
2423  if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
2424    // The receiver is implicit (and undefined), the arguments are in
2425    // consecutive registers.
2426    receiver_node = jsgraph()->UndefinedConstant();
2427    first_arg = first_reg;
2428  } else {
2429    // The receiver is the first register, followed by the arguments in the
2430    // consecutive registers.
2431    receiver_node = environment()->LookupRegister(first_reg);
2432    first_arg = interpreter::Register(first_reg.index() + 1);
2433  }
2434
2435  Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
2436                                                         first_arg, arg_count);
2437  return call_args;
2438}
2439
2440void BytecodeGraphBuilder::BuildCallVarArgs(ConvertReceiverMode receiver_mode) {
2441  DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
2442                bytecode_iterator().current_bytecode()),
2443            receiver_mode);
2444  Node* callee =
2445      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2446  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2447  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2448  int const slot_id = bytecode_iterator().GetIndexOperand(3);
2449
2450  int arg_count = receiver_mode == ConvertReceiverMode::kNullOrUndefined
2451                      ? static_cast<int>(reg_count)
2452                      : static_cast<int>(reg_count) - 1;
2453  Node* const* call_args =
2454      ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count);
2455  BuildCall(receiver_mode, call_args, JSCallNode::ArityForArgc(arg_count),
2456            slot_id);
2457}
2458
2459void BytecodeGraphBuilder::VisitCallAnyReceiver() {
2460  BuildCallVarArgs(ConvertReceiverMode::kAny);
2461}
2462
2463void BytecodeGraphBuilder::VisitCallProperty() {
2464  BuildCallVarArgs(ConvertReceiverMode::kNotNullOrUndefined);
2465}
2466
2467void BytecodeGraphBuilder::VisitCallProperty0() {
2468  Node* callee =
2469      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2470  Node* receiver =
2471      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2472  int const slot_id = bytecode_iterator().GetIndexOperand(2);
2473  BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
2474            {callee, receiver, feedback_vector_node()}, slot_id);
2475}
2476
2477void BytecodeGraphBuilder::VisitCallProperty1() {
2478  Node* callee =
2479      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2480  Node* receiver =
2481      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2482  Node* arg0 =
2483      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
2484  int const slot_id = bytecode_iterator().GetIndexOperand(3);
2485  BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
2486            {callee, receiver, arg0, feedback_vector_node()}, slot_id);
2487}
2488
2489void BytecodeGraphBuilder::VisitCallProperty2() {
2490  Node* callee =
2491      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2492  Node* receiver =
2493      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2494  Node* arg0 =
2495      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
2496  Node* arg1 =
2497      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
2498  int const slot_id = bytecode_iterator().GetIndexOperand(4);
2499  BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
2500            {callee, receiver, arg0, arg1, feedback_vector_node()}, slot_id);
2501}
2502
2503void BytecodeGraphBuilder::VisitCallUndefinedReceiver() {
2504  BuildCallVarArgs(ConvertReceiverMode::kNullOrUndefined);
2505}
2506
2507void BytecodeGraphBuilder::VisitCallUndefinedReceiver0() {
2508  Node* callee =
2509      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2510  Node* receiver = jsgraph()->UndefinedConstant();
2511  int const slot_id = bytecode_iterator().GetIndexOperand(1);
2512  BuildCall(ConvertReceiverMode::kNullOrUndefined,
2513            {callee, receiver, feedback_vector_node()}, slot_id);
2514}
2515
2516void BytecodeGraphBuilder::VisitCallUndefinedReceiver1() {
2517  Node* callee =
2518      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2519  Node* receiver = jsgraph()->UndefinedConstant();
2520  Node* arg0 =
2521      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2522  int const slot_id = bytecode_iterator().GetIndexOperand(2);
2523  BuildCall(ConvertReceiverMode::kNullOrUndefined,
2524            {callee, receiver, arg0, feedback_vector_node()}, slot_id);
2525}
2526
2527void BytecodeGraphBuilder::VisitCallUndefinedReceiver2() {
2528  Node* callee =
2529      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2530  Node* receiver = jsgraph()->UndefinedConstant();
2531  Node* arg0 =
2532      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2533  Node* arg1 =
2534      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
2535  int const slot_id = bytecode_iterator().GetIndexOperand(3);
2536  BuildCall(ConvertReceiverMode::kNullOrUndefined,
2537            {callee, receiver, arg0, arg1, feedback_vector_node()}, slot_id);
2538}
2539
2540void BytecodeGraphBuilder::VisitCallWithSpread() {
2541  PrepareEagerCheckpoint();
2542  Node* callee =
2543      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2544  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
2545  Node* receiver_node = environment()->LookupRegister(receiver);
2546  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2547  interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
2548  int arg_count = static_cast<int>(reg_count) - 1;
2549  Node* const* args = GetCallArgumentsFromRegisters(callee, receiver_node,
2550                                                    first_arg, arg_count);
2551  int const slot_id = bytecode_iterator().GetIndexOperand(3);
2552  FeedbackSource feedback = CreateFeedbackSource(slot_id);
2553  CallFrequency frequency = ComputeCallFrequency(slot_id);
2554  SpeculationMode speculation_mode = GetSpeculationMode(slot_id);
2555  const Operator* op = javascript()->CallWithSpread(
2556      JSCallWithSpreadNode::ArityForArgc(arg_count), frequency, feedback,
2557      speculation_mode);
2558  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2559
2560  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
2561      op, args, static_cast<int>(arg_count), feedback.slot);
2562  if (lowering.IsExit()) return;
2563
2564  Node* node = nullptr;
2565  if (lowering.IsSideEffectFree()) {
2566    node = lowering.value();
2567  } else {
2568    DCHECK(!lowering.Changed());
2569    node = MakeNode(op, JSCallWithSpreadNode::ArityForArgc(arg_count), args);
2570  }
2571  environment()->BindAccumulator(node, Environment::kAttachFrameState);
2572}
2573
2574void BytecodeGraphBuilder::VisitCallJSRuntime() {
2575  PrepareEagerCheckpoint();
2576  Node* callee = BuildLoadNativeContextField(
2577      bytecode_iterator().GetNativeContextIndexOperand(0));
2578  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2579  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2580  int arg_count = static_cast<int>(reg_count);
2581  int arity = JSCallNode::ArityForArgc(arg_count);
2582
2583  const Operator* call = javascript()->Call(arity);
2584  Node* const* call_args = ProcessCallVarArgs(
2585      ConvertReceiverMode::kNullOrUndefined, callee, first_reg, arg_count);
2586  Node* value = MakeNode(call, arity, call_args);
2587  environment()->BindAccumulator(value, Environment::kAttachFrameState);
2588}
2589
2590Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
2591    const Operator* call_runtime_op, interpreter::Register receiver,
2592    size_t reg_count) {
2593  int arg_count = static_cast<int>(reg_count);
2594  // arity is args.
2595  int arity = arg_count;
2596  Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
2597  int first_arg_index = receiver.index();
2598  for (int i = 0; i < static_cast<int>(reg_count); ++i) {
2599    all[i] = environment()->LookupRegister(
2600        interpreter::Register(first_arg_index + i));
2601  }
2602  Node* value = MakeNode(call_runtime_op, arity, all);
2603  return value;
2604}
2605
2606void BytecodeGraphBuilder::VisitCallRuntime() {
2607  PrepareEagerCheckpoint();
2608  Runtime::FunctionId function_id = bytecode_iterator().GetRuntimeIdOperand(0);
2609  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
2610  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2611
2612  // Handle %ObserveNode here (rather than in JSIntrinsicLowering) to observe
2613  // the node as early as possible.
2614  if (function_id == Runtime::FunctionId::kObserveNode) {
2615    DCHECK_EQ(1, reg_count);
2616    Node* value = environment()->LookupRegister(receiver);
2617    observe_node_info_.StartObserving(value);
2618    environment()->BindAccumulator(value);
2619  } else {
2620    // Create node to perform the runtime call.
2621    const Operator* call = javascript()->CallRuntime(function_id, reg_count);
2622    Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
2623    environment()->BindAccumulator(value, Environment::kAttachFrameState);
2624
2625    // Connect to the end if {function_id} is non-returning.
2626    if (Runtime::IsNonReturning(function_id)) {
2627      // TODO(7099): Investigate if we need LoopExit node here.
2628      Node* control = NewNode(common()->Throw());
2629      MergeControlToLeaveFunction(control);
2630    }
2631  }
2632}
2633
2634void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
2635  PrepareEagerCheckpoint();
2636  Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
2637  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
2638  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2639  interpreter::Register first_return =
2640      bytecode_iterator().GetRegisterOperand(3);
2641
2642  // Create node to perform the runtime call.
2643  const Operator* call = javascript()->CallRuntime(functionId, reg_count);
2644  Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count);
2645  environment()->BindRegistersToProjections(first_return, return_pair,
2646                                            Environment::kAttachFrameState);
2647}
2648
2649Node* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister(
2650    Node* target, Node* new_target, interpreter::Register first_arg,
2651    int arg_count) {
2652  const int arity = JSConstructNode::ArityForArgc(arg_count);
2653  Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
2654  int cursor = 0;
2655
2656  STATIC_ASSERT(JSConstructNode::TargetIndex() == 0);
2657  STATIC_ASSERT(JSConstructNode::NewTargetIndex() == 1);
2658  STATIC_ASSERT(JSConstructNode::FirstArgumentIndex() == 2);
2659  STATIC_ASSERT(JSConstructNode::kFeedbackVectorIsLastInput);
2660
2661  all[cursor++] = target;
2662  all[cursor++] = new_target;
2663
2664  // The function arguments are in consecutive registers.
2665  int arg_base = first_arg.index();
2666  for (int i = 0; i < arg_count; ++i) {
2667    all[cursor++] =
2668        environment()->LookupRegister(interpreter::Register(arg_base + i));
2669  }
2670
2671  all[cursor++] = feedback_vector_node();
2672
2673  DCHECK_EQ(cursor, arity);
2674  return all;
2675}
2676
2677void BytecodeGraphBuilder::VisitConstruct() {
2678  PrepareEagerCheckpoint();
2679  interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
2680  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2681  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2682  int const slot_id = bytecode_iterator().GetIndexOperand(3);
2683  FeedbackSource feedback = CreateFeedbackSource(slot_id);
2684
2685  Node* new_target = environment()->LookupAccumulator();
2686  Node* callee = environment()->LookupRegister(callee_reg);
2687
2688  CallFrequency frequency = ComputeCallFrequency(slot_id);
2689  const uint32_t arg_count = static_cast<uint32_t>(reg_count);
2690  const uint32_t arity = JSConstructNode::ArityForArgc(arg_count);
2691  const Operator* op = javascript()->Construct(arity, frequency, feedback);
2692  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2693  Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
2694                                                        first_reg, arg_count);
2695  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
2696      op, args, static_cast<int>(arg_count), feedback.slot);
2697  if (lowering.IsExit()) return;
2698
2699  Node* node = nullptr;
2700  if (lowering.IsSideEffectFree()) {
2701    node = lowering.value();
2702  } else {
2703    DCHECK(!lowering.Changed());
2704    node = MakeNode(op, arity, args);
2705  }
2706  environment()->BindAccumulator(node, Environment::kAttachFrameState);
2707}
2708
2709void BytecodeGraphBuilder::VisitConstructWithSpread() {
2710  PrepareEagerCheckpoint();
2711  interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
2712  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2713  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2714  int const slot_id = bytecode_iterator().GetIndexOperand(3);
2715  FeedbackSource feedback = CreateFeedbackSource(slot_id);
2716
2717  Node* new_target = environment()->LookupAccumulator();
2718  Node* callee = environment()->LookupRegister(callee_reg);
2719
2720  CallFrequency frequency = ComputeCallFrequency(slot_id);
2721  const uint32_t arg_count = static_cast<uint32_t>(reg_count);
2722  const uint32_t arity = JSConstructNode::ArityForArgc(arg_count);
2723  const Operator* op =
2724      javascript()->ConstructWithSpread(arity, frequency, feedback);
2725  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2726  Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
2727                                                        first_reg, arg_count);
2728  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
2729      op, args, static_cast<int>(arg_count), feedback.slot);
2730  if (lowering.IsExit()) return;
2731
2732  Node* node = nullptr;
2733  if (lowering.IsSideEffectFree()) {
2734    node = lowering.value();
2735  } else {
2736    DCHECK(!lowering.Changed());
2737    node = MakeNode(op, arity, args);
2738  }
2739  environment()->BindAccumulator(node, Environment::kAttachFrameState);
2740}
2741
2742void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
2743  PrepareEagerCheckpoint();
2744  Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
2745  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
2746  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2747
2748  // Create node to perform the runtime call. Turbofan will take care of the
2749  // lowering.
2750  const Operator* call = javascript()->CallRuntime(functionId, reg_count);
2751  Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
2752  environment()->BindAccumulator(value, Environment::kAttachFrameState);
2753}
2754
2755void BytecodeGraphBuilder::VisitThrow() {
2756  BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2757      bytecode_iterator().current_offset()));
2758  Node* value = environment()->LookupAccumulator();
2759  Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
2760  environment()->BindAccumulator(call, Environment::kAttachFrameState);
2761  Node* control = NewNode(common()->Throw());
2762  MergeControlToLeaveFunction(control);
2763}
2764
2765void BytecodeGraphBuilder::VisitAbort() {
2766  BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2767      bytecode_iterator().current_offset()));
2768  AbortReason reason =
2769      static_cast<AbortReason>(bytecode_iterator().GetIndexOperand(0));
2770  NewNode(simplified()->RuntimeAbort(reason));
2771  Node* control = NewNode(common()->Throw());
2772  MergeControlToLeaveFunction(control);
2773}
2774
2775void BytecodeGraphBuilder::VisitReThrow() {
2776  BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2777      bytecode_iterator().current_offset()));
2778  Node* value = environment()->LookupAccumulator();
2779  NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
2780  Node* control = NewNode(common()->Throw());
2781  MergeControlToLeaveFunction(control);
2782}
2783
2784void BytecodeGraphBuilder::BuildHoleCheckAndThrow(
2785    Node* condition, Runtime::FunctionId runtime_id, Node* name) {
2786  Node* accumulator = environment()->LookupAccumulator();
2787  NewBranch(condition, BranchHint::kFalse);
2788  {
2789    SubEnvironment sub_environment(this);
2790
2791    NewIfTrue();
2792    BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2793        bytecode_iterator().current_offset()));
2794    Node* node;
2795    const Operator* op = javascript()->CallRuntime(runtime_id);
2796    if (runtime_id == Runtime::kThrowAccessedUninitializedVariable) {
2797      DCHECK_NOT_NULL(name);
2798      node = NewNode(op, name);
2799    } else {
2800      DCHECK(runtime_id == Runtime::kThrowSuperAlreadyCalledError ||
2801             runtime_id == Runtime::kThrowSuperNotCalled);
2802      node = NewNode(op);
2803    }
2804    environment()->RecordAfterState(node, Environment::kAttachFrameState);
2805    Node* control = NewNode(common()->Throw());
2806    MergeControlToLeaveFunction(control);
2807  }
2808  NewIfFalse();
2809  environment()->BindAccumulator(accumulator);
2810}
2811
2812void BytecodeGraphBuilder::VisitThrowReferenceErrorIfHole() {
2813  Node* accumulator = environment()->LookupAccumulator();
2814  Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2815                                 jsgraph()->TheHoleConstant());
2816  Node* name = jsgraph()->Constant(MakeRefForConstantForIndexOperand(0));
2817  BuildHoleCheckAndThrow(check_for_hole,
2818                         Runtime::kThrowAccessedUninitializedVariable, name);
2819}
2820
2821void BytecodeGraphBuilder::VisitThrowSuperNotCalledIfHole() {
2822  Node* accumulator = environment()->LookupAccumulator();
2823  Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2824                                 jsgraph()->TheHoleConstant());
2825  BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowSuperNotCalled);
2826}
2827
2828void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
2829  Node* accumulator = environment()->LookupAccumulator();
2830  Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2831                                 jsgraph()->TheHoleConstant());
2832  Node* check_for_not_hole =
2833      NewNode(simplified()->BooleanNot(), check_for_hole);
2834  BuildHoleCheckAndThrow(check_for_not_hole,
2835                         Runtime::kThrowSuperAlreadyCalledError);
2836}
2837
2838void BytecodeGraphBuilder::VisitThrowIfNotSuperConstructor() {
2839  Node* constructor =
2840      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2841  Node* check_is_constructor =
2842      NewNode(simplified()->ObjectIsConstructor(), constructor);
2843  NewBranch(check_is_constructor, BranchHint::kTrue);
2844  {
2845    SubEnvironment sub_environment(this);
2846    NewIfFalse();
2847    BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2848        bytecode_iterator().current_offset()));
2849    Node* node =
2850        NewNode(javascript()->CallRuntime(Runtime::kThrowNotSuperConstructor),
2851                constructor, GetFunctionClosure());
2852    environment()->RecordAfterState(node, Environment::kAttachFrameState);
2853    Node* control = NewNode(common()->Throw());
2854    MergeControlToLeaveFunction(control);
2855  }
2856  NewIfTrue();
2857
2858  constructor = NewNode(common()->TypeGuard(Type::Callable()), constructor);
2859  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
2860                              constructor);
2861}
2862
2863void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) {
2864  DCHECK(JSOperator::IsUnaryWithFeedback(op->opcode()));
2865  PrepareEagerCheckpoint();
2866  Node* operand = environment()->LookupAccumulator();
2867
2868  FeedbackSlot slot =
2869      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex);
2870  JSTypeHintLowering::LoweringResult lowering =
2871      TryBuildSimplifiedUnaryOp(op, operand, slot);
2872  if (lowering.IsExit()) return;
2873
2874  Node* node = nullptr;
2875  if (lowering.IsSideEffectFree()) {
2876    node = lowering.value();
2877  } else {
2878    DCHECK(!lowering.Changed());
2879    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2880    node = NewNode(op, operand, feedback_vector_node());
2881  }
2882
2883  environment()->BindAccumulator(node, Environment::kAttachFrameState);
2884}
2885
2886void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) {
2887  DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
2888  PrepareEagerCheckpoint();
2889  Node* left =
2890      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2891  Node* right = environment()->LookupAccumulator();
2892
2893  FeedbackSlot slot =
2894      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex);
2895  JSTypeHintLowering::LoweringResult lowering =
2896      TryBuildSimplifiedBinaryOp(op, left, right, slot);
2897  if (lowering.IsExit()) return;
2898
2899  Node* node = nullptr;
2900  if (lowering.IsSideEffectFree()) {
2901    node = lowering.value();
2902  } else {
2903    DCHECK(!lowering.Changed());
2904    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2905    node = NewNode(op, left, right, feedback_vector_node());
2906  }
2907
2908  environment()->BindAccumulator(node, Environment::kAttachFrameState);
2909}
2910
2911// Helper function to create for-in mode from the recorded type feedback.
2912ForInMode BytecodeGraphBuilder::GetForInMode(FeedbackSlot slot) {
2913  FeedbackSource source(feedback_vector(), slot);
2914  switch (broker()->GetFeedbackForForIn(source)) {
2915    case ForInHint::kNone:
2916    case ForInHint::kEnumCacheKeysAndIndices:
2917      return ForInMode::kUseEnumCacheKeysAndIndices;
2918    case ForInHint::kEnumCacheKeys:
2919      return ForInMode::kUseEnumCacheKeys;
2920    case ForInHint::kAny:
2921      return ForInMode::kGeneric;
2922  }
2923  UNREACHABLE();
2924}
2925
2926CallFrequency BytecodeGraphBuilder::ComputeCallFrequency(int slot_id) const {
2927  if (invocation_frequency_.IsUnknown()) return CallFrequency();
2928  FeedbackSlot slot = FeedbackVector::ToSlot(slot_id);
2929  FeedbackSource source(feedback_vector(), slot);
2930  ProcessedFeedback const& feedback = broker()->GetFeedbackForCall(source);
2931  float feedback_frequency =
2932      feedback.IsInsufficient() ? 0.0f : feedback.AsCall().frequency();
2933  if (feedback_frequency == 0.0f) {  // Prevent multiplying zero and infinity.
2934    return CallFrequency(0.0f);
2935  } else {
2936    return CallFrequency(feedback_frequency * invocation_frequency_.value());
2937  }
2938}
2939
2940SpeculationMode BytecodeGraphBuilder::GetSpeculationMode(int slot_id) const {
2941  FeedbackSlot slot = FeedbackVector::ToSlot(slot_id);
2942  FeedbackSource source(feedback_vector(), slot);
2943  ProcessedFeedback const& feedback = broker()->GetFeedbackForCall(source);
2944  return feedback.IsInsufficient() ? SpeculationMode::kDisallowSpeculation
2945                                   : feedback.AsCall().speculation_mode();
2946}
2947
2948CallFeedbackRelation BytecodeGraphBuilder::ComputeCallFeedbackRelation(
2949    int slot_id) const {
2950  FeedbackSlot slot = FeedbackVector::ToSlot(slot_id);
2951  FeedbackSource source(feedback_vector(), slot);
2952  ProcessedFeedback const& feedback = broker()->GetFeedbackForCall(source);
2953  if (feedback.IsInsufficient()) return CallFeedbackRelation::kUnrelated;
2954  CallFeedbackContent call_feedback_content =
2955      feedback.AsCall().call_feedback_content();
2956  return call_feedback_content == CallFeedbackContent::kTarget
2957             ? CallFeedbackRelation::kTarget
2958             : CallFeedbackRelation::kReceiver;
2959}
2960
2961void BytecodeGraphBuilder::VisitBitwiseNot() {
2962  FeedbackSource feedback = CreateFeedbackSource(
2963      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
2964  BuildUnaryOp(javascript()->BitwiseNot(feedback));
2965}
2966
2967void BytecodeGraphBuilder::VisitDec() {
2968  FeedbackSource feedback = CreateFeedbackSource(
2969      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
2970  BuildUnaryOp(javascript()->Decrement(feedback));
2971}
2972
2973void BytecodeGraphBuilder::VisitInc() {
2974  FeedbackSource feedback = CreateFeedbackSource(
2975      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
2976  BuildUnaryOp(javascript()->Increment(feedback));
2977}
2978
2979void BytecodeGraphBuilder::VisitNegate() {
2980  FeedbackSource feedback = CreateFeedbackSource(
2981      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
2982  BuildUnaryOp(javascript()->Negate(feedback));
2983}
2984
2985void BytecodeGraphBuilder::VisitAdd() {
2986  FeedbackSource feedback = CreateFeedbackSource(
2987      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
2988  BuildBinaryOp(javascript()->Add(feedback));
2989}
2990
2991void BytecodeGraphBuilder::VisitSub() {
2992  FeedbackSource feedback = CreateFeedbackSource(
2993      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
2994  BuildBinaryOp(javascript()->Subtract(feedback));
2995}
2996
2997void BytecodeGraphBuilder::VisitMul() {
2998  FeedbackSource feedback = CreateFeedbackSource(
2999      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3000  BuildBinaryOp(javascript()->Multiply(feedback));
3001}
3002
3003void BytecodeGraphBuilder::VisitDiv() {
3004  FeedbackSource feedback = CreateFeedbackSource(
3005      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3006  BuildBinaryOp(javascript()->Divide(feedback));
3007}
3008
3009void BytecodeGraphBuilder::VisitMod() {
3010  FeedbackSource feedback = CreateFeedbackSource(
3011      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3012  BuildBinaryOp(javascript()->Modulus(feedback));
3013}
3014
3015void BytecodeGraphBuilder::VisitExp() {
3016  FeedbackSource feedback = CreateFeedbackSource(
3017      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3018  BuildBinaryOp(javascript()->Exponentiate(feedback));
3019}
3020
3021void BytecodeGraphBuilder::VisitBitwiseOr() {
3022  FeedbackSource feedback = CreateFeedbackSource(
3023      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3024  BuildBinaryOp(javascript()->BitwiseOr(feedback));
3025}
3026
3027void BytecodeGraphBuilder::VisitBitwiseXor() {
3028  FeedbackSource feedback = CreateFeedbackSource(
3029      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3030  BuildBinaryOp(javascript()->BitwiseXor(feedback));
3031}
3032
3033void BytecodeGraphBuilder::VisitBitwiseAnd() {
3034  FeedbackSource feedback = CreateFeedbackSource(
3035      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3036  BuildBinaryOp(javascript()->BitwiseAnd(feedback));
3037}
3038
3039void BytecodeGraphBuilder::VisitShiftLeft() {
3040  FeedbackSource feedback = CreateFeedbackSource(
3041      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3042  BuildBinaryOp(javascript()->ShiftLeft(feedback));
3043}
3044
3045void BytecodeGraphBuilder::VisitShiftRight() {
3046  FeedbackSource feedback = CreateFeedbackSource(
3047      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3048  BuildBinaryOp(javascript()->ShiftRight(feedback));
3049}
3050
3051void BytecodeGraphBuilder::VisitShiftRightLogical() {
3052  FeedbackSource feedback = CreateFeedbackSource(
3053      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3054  BuildBinaryOp(javascript()->ShiftRightLogical(feedback));
3055}
3056
3057void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) {
3058  DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
3059  PrepareEagerCheckpoint();
3060  Node* left = environment()->LookupAccumulator();
3061  Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
3062
3063  FeedbackSlot slot =
3064      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex);
3065  JSTypeHintLowering::LoweringResult lowering =
3066      TryBuildSimplifiedBinaryOp(op, left, right, slot);
3067  if (lowering.IsExit()) return;
3068
3069  Node* node = nullptr;
3070  if (lowering.IsSideEffectFree()) {
3071    node = lowering.value();
3072  } else {
3073    DCHECK(!lowering.Changed());
3074    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
3075    node = NewNode(op, left, right, feedback_vector_node());
3076  }
3077  environment()->BindAccumulator(node, Environment::kAttachFrameState);
3078}
3079
3080void BytecodeGraphBuilder::VisitAddSmi() {
3081  FeedbackSource feedback = CreateFeedbackSource(
3082      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3083  BuildBinaryOpWithImmediate(javascript()->Add(feedback));
3084}
3085
3086void BytecodeGraphBuilder::VisitSubSmi() {
3087  FeedbackSource feedback = CreateFeedbackSource(
3088      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3089  BuildBinaryOpWithImmediate(javascript()->Subtract(feedback));
3090}
3091
3092void BytecodeGraphBuilder::VisitMulSmi() {
3093  FeedbackSource feedback = CreateFeedbackSource(
3094      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3095  BuildBinaryOpWithImmediate(javascript()->Multiply(feedback));
3096}
3097
3098void BytecodeGraphBuilder::VisitDivSmi() {
3099  FeedbackSource feedback = CreateFeedbackSource(
3100      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3101  BuildBinaryOpWithImmediate(javascript()->Divide(feedback));
3102}
3103
3104void BytecodeGraphBuilder::VisitModSmi() {
3105  FeedbackSource feedback = CreateFeedbackSource(
3106      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3107  BuildBinaryOpWithImmediate(javascript()->Modulus(feedback));
3108}
3109
3110void BytecodeGraphBuilder::VisitExpSmi() {
3111  FeedbackSource feedback = CreateFeedbackSource(
3112      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3113  BuildBinaryOpWithImmediate(javascript()->Exponentiate(feedback));
3114}
3115
3116void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
3117  FeedbackSource feedback = CreateFeedbackSource(
3118      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3119  BuildBinaryOpWithImmediate(javascript()->BitwiseOr(feedback));
3120}
3121
3122void BytecodeGraphBuilder::VisitBitwiseXorSmi() {
3123  FeedbackSource feedback = CreateFeedbackSource(
3124      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3125  BuildBinaryOpWithImmediate(javascript()->BitwiseXor(feedback));
3126}
3127
3128void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
3129  FeedbackSource feedback = CreateFeedbackSource(
3130      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3131  BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(feedback));
3132}
3133
3134void BytecodeGraphBuilder::VisitShiftLeftSmi() {
3135  FeedbackSource feedback = CreateFeedbackSource(
3136      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3137  BuildBinaryOpWithImmediate(javascript()->ShiftLeft(feedback));
3138}
3139
3140void BytecodeGraphBuilder::VisitShiftRightSmi() {
3141  FeedbackSource feedback = CreateFeedbackSource(
3142      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3143  BuildBinaryOpWithImmediate(javascript()->ShiftRight(feedback));
3144}
3145
3146void BytecodeGraphBuilder::VisitShiftRightLogicalSmi() {
3147  FeedbackSource feedback = CreateFeedbackSource(
3148      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3149  BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical(feedback));
3150}
3151
3152void BytecodeGraphBuilder::VisitLogicalNot() {
3153  Node* value = environment()->LookupAccumulator();
3154  Node* node = NewNode(simplified()->BooleanNot(), value);
3155  environment()->BindAccumulator(node);
3156}
3157
3158void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
3159  Node* value =
3160      NewNode(simplified()->ToBoolean(), environment()->LookupAccumulator());
3161  Node* node = NewNode(simplified()->BooleanNot(), value);
3162  environment()->BindAccumulator(node);
3163}
3164
3165void BytecodeGraphBuilder::VisitTypeOf() {
3166  Node* node =
3167      NewNode(simplified()->TypeOf(), environment()->LookupAccumulator());
3168  environment()->BindAccumulator(node);
3169}
3170
3171void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
3172  PrepareEagerCheckpoint();
3173  Node* key = environment()->LookupAccumulator();
3174  Node* object =
3175      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3176  Node* mode = jsgraph()->Constant(static_cast<int32_t>(language_mode));
3177  Node* node = NewNode(javascript()->DeleteProperty(), object, key, mode);
3178  environment()->BindAccumulator(node, Environment::kAttachFrameState);
3179}
3180
3181void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
3182  BuildDelete(LanguageMode::kStrict);
3183}
3184
3185void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
3186  BuildDelete(LanguageMode::kSloppy);
3187}
3188
3189void BytecodeGraphBuilder::VisitGetSuperConstructor() {
3190  Node* node = NewNode(javascript()->GetSuperConstructor(),
3191                       environment()->LookupAccumulator());
3192  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
3193                              Environment::kAttachFrameState);
3194}
3195
3196void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) {
3197  DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
3198  PrepareEagerCheckpoint();
3199  Node* left =
3200      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3201  Node* right = environment()->LookupAccumulator();
3202
3203  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
3204  JSTypeHintLowering::LoweringResult lowering =
3205      TryBuildSimplifiedBinaryOp(op, left, right, slot);
3206  if (lowering.IsExit()) return;
3207
3208  Node* node = nullptr;
3209  if (lowering.IsSideEffectFree()) {
3210    node = lowering.value();
3211  } else {
3212    DCHECK(!lowering.Changed());
3213    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
3214    node = NewNode(op, left, right, feedback_vector_node());
3215  }
3216  environment()->BindAccumulator(node, Environment::kAttachFrameState);
3217}
3218
3219void BytecodeGraphBuilder::VisitTestEqual() {
3220  FeedbackSource feedback = CreateFeedbackSource(
3221      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3222  BuildCompareOp(javascript()->Equal(feedback));
3223}
3224
3225void BytecodeGraphBuilder::VisitTestEqualStrict() {
3226  FeedbackSource feedback = CreateFeedbackSource(
3227      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3228  BuildCompareOp(javascript()->StrictEqual(feedback));
3229}
3230
3231void BytecodeGraphBuilder::VisitTestLessThan() {
3232  FeedbackSource feedback = CreateFeedbackSource(
3233      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3234  BuildCompareOp(javascript()->LessThan(feedback));
3235}
3236
3237void BytecodeGraphBuilder::VisitTestGreaterThan() {
3238  FeedbackSource feedback = CreateFeedbackSource(
3239      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3240  BuildCompareOp(javascript()->GreaterThan(feedback));
3241}
3242
3243void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
3244  FeedbackSource feedback = CreateFeedbackSource(
3245      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3246  BuildCompareOp(javascript()->LessThanOrEqual(feedback));
3247}
3248
3249void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
3250  FeedbackSource feedback = CreateFeedbackSource(
3251      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3252  BuildCompareOp(javascript()->GreaterThanOrEqual(feedback));
3253}
3254
3255void BytecodeGraphBuilder::VisitTestReferenceEqual() {
3256  Node* left =
3257      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3258  Node* right = environment()->LookupAccumulator();
3259  Node* result = NewNode(simplified()->ReferenceEqual(), left, right);
3260  environment()->BindAccumulator(result);
3261}
3262
3263void BytecodeGraphBuilder::VisitTestIn() {
3264  PrepareEagerCheckpoint();
3265  Node* object = environment()->LookupAccumulator();
3266  Node* key =
3267      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3268  FeedbackSource feedback =
3269      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
3270  STATIC_ASSERT(JSHasPropertyNode::ObjectIndex() == 0);
3271  STATIC_ASSERT(JSHasPropertyNode::KeyIndex() == 1);
3272  STATIC_ASSERT(JSHasPropertyNode::FeedbackVectorIndex() == 2);
3273  const Operator* op = javascript()->HasProperty(feedback);
3274  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
3275  Node* node = NewNode(op, object, key, feedback_vector_node());
3276  environment()->BindAccumulator(node, Environment::kAttachFrameState);
3277}
3278
3279void BytecodeGraphBuilder::VisitTestInstanceOf() {
3280  FeedbackSource feedback = CreateFeedbackSource(
3281      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3282  BuildCompareOp(javascript()->InstanceOf(feedback));
3283}
3284
3285void BytecodeGraphBuilder::VisitTestUndetectable() {
3286  Node* object = environment()->LookupAccumulator();
3287  Node* node = NewNode(jsgraph()->simplified()->ObjectIsUndetectable(), object);
3288  environment()->BindAccumulator(node);
3289}
3290
3291void BytecodeGraphBuilder::VisitTestNull() {
3292  Node* object = environment()->LookupAccumulator();
3293  Node* result = NewNode(simplified()->ReferenceEqual(), object,
3294                         jsgraph()->NullConstant());
3295  environment()->BindAccumulator(result);
3296}
3297
3298void BytecodeGraphBuilder::VisitTestUndefined() {
3299  Node* object = environment()->LookupAccumulator();
3300  Node* result = NewNode(simplified()->ReferenceEqual(), object,
3301                         jsgraph()->UndefinedConstant());
3302  environment()->BindAccumulator(result);
3303}
3304
3305void BytecodeGraphBuilder::VisitTestTypeOf() {
3306  Node* object = environment()->LookupAccumulator();
3307  auto literal_flag = interpreter::TestTypeOfFlags::Decode(
3308      bytecode_iterator().GetFlagOperand(0));
3309  Node* result;
3310  switch (literal_flag) {
3311    case interpreter::TestTypeOfFlags::LiteralFlag::kNumber:
3312      result = NewNode(simplified()->ObjectIsNumber(), object);
3313      break;
3314    case interpreter::TestTypeOfFlags::LiteralFlag::kString:
3315      result = NewNode(simplified()->ObjectIsString(), object);
3316      break;
3317    case interpreter::TestTypeOfFlags::LiteralFlag::kSymbol:
3318      result = NewNode(simplified()->ObjectIsSymbol(), object);
3319      break;
3320    case interpreter::TestTypeOfFlags::LiteralFlag::kBigInt:
3321      result = NewNode(simplified()->ObjectIsBigInt(), object);
3322      break;
3323    case interpreter::TestTypeOfFlags::LiteralFlag::kBoolean:
3324      result = NewNode(common()->Select(MachineRepresentation::kTagged),
3325                       NewNode(simplified()->ReferenceEqual(), object,
3326                               jsgraph()->TrueConstant()),
3327                       jsgraph()->TrueConstant(),
3328                       NewNode(simplified()->ReferenceEqual(), object,
3329                               jsgraph()->FalseConstant()));
3330      break;
3331    case interpreter::TestTypeOfFlags::LiteralFlag::kUndefined:
3332      result = graph()->NewNode(
3333          common()->Select(MachineRepresentation::kTagged),
3334          graph()->NewNode(simplified()->ReferenceEqual(), object,
3335                           jsgraph()->NullConstant()),
3336          jsgraph()->FalseConstant(),
3337          graph()->NewNode(simplified()->ObjectIsUndetectable(), object));
3338      break;
3339    case interpreter::TestTypeOfFlags::LiteralFlag::kFunction:
3340      result =
3341          graph()->NewNode(simplified()->ObjectIsDetectableCallable(), object);
3342      break;
3343    case interpreter::TestTypeOfFlags::LiteralFlag::kObject:
3344      result = graph()->NewNode(
3345          common()->Select(MachineRepresentation::kTagged),
3346          graph()->NewNode(simplified()->ObjectIsNonCallable(), object),
3347          jsgraph()->TrueConstant(),
3348          graph()->NewNode(simplified()->ReferenceEqual(), object,
3349                           jsgraph()->NullConstant()));
3350      break;
3351    case interpreter::TestTypeOfFlags::LiteralFlag::kOther:
3352      UNREACHABLE();  // Should never be emitted.
3353  }
3354  environment()->BindAccumulator(result);
3355}
3356
3357void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
3358  Node* value = NewNode(js_op, environment()->LookupAccumulator());
3359  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
3360                              Environment::kAttachFrameState);
3361}
3362
3363void BytecodeGraphBuilder::VisitToName() {
3364  BuildCastOperator(javascript()->ToName());
3365}
3366
3367void BytecodeGraphBuilder::VisitToObject() {
3368  BuildCastOperator(javascript()->ToObject());
3369}
3370
3371void BytecodeGraphBuilder::VisitToString() {
3372  Node* value =
3373      NewNode(javascript()->ToString(), environment()->LookupAccumulator());
3374  environment()->BindAccumulator(value, Environment::kAttachFrameState);
3375}
3376
3377void BytecodeGraphBuilder::VisitToNumber() {
3378  PrepareEagerCheckpoint();
3379  Node* object = environment()->LookupAccumulator();
3380
3381  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
3382  JSTypeHintLowering::LoweringResult lowering =
3383      TryBuildSimplifiedToNumber(object, slot);
3384
3385  Node* node = nullptr;
3386  if (lowering.IsSideEffectFree()) {
3387    node = lowering.value();
3388  } else {
3389    DCHECK(!lowering.Changed());
3390    node = NewNode(javascript()->ToNumber(), object);
3391  }
3392
3393  environment()->BindAccumulator(node, Environment::kAttachFrameState);
3394}
3395
3396void BytecodeGraphBuilder::VisitToNumeric() {
3397  PrepareEagerCheckpoint();
3398  Node* object = environment()->LookupAccumulator();
3399
3400  // If we have some kind of Number feedback, we do the same lowering as for
3401  // ToNumber.
3402  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
3403  JSTypeHintLowering::LoweringResult lowering =
3404      TryBuildSimplifiedToNumber(object, slot);
3405
3406  Node* node = nullptr;
3407  if (lowering.IsSideEffectFree()) {
3408    node = lowering.value();
3409  } else {
3410    DCHECK(!lowering.Changed());
3411    node = NewNode(javascript()->ToNumeric(), object);
3412  }
3413
3414  environment()->BindAccumulator(node, Environment::kAttachFrameState);
3415}
3416
3417void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
3418
3419void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
3420
3421void BytecodeGraphBuilder::VisitJumpIfTrue() { BuildJumpIfTrue(); }
3422
3423void BytecodeGraphBuilder::VisitJumpIfTrueConstant() { BuildJumpIfTrue(); }
3424
3425void BytecodeGraphBuilder::VisitJumpIfFalse() { BuildJumpIfFalse(); }
3426
3427void BytecodeGraphBuilder::VisitJumpIfFalseConstant() { BuildJumpIfFalse(); }
3428
3429void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
3430  BuildJumpIfToBooleanTrue();
3431}
3432
3433void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
3434  BuildJumpIfToBooleanTrue();
3435}
3436
3437void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
3438  BuildJumpIfToBooleanFalse();
3439}
3440
3441void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
3442  BuildJumpIfToBooleanFalse();
3443}
3444
3445void BytecodeGraphBuilder::VisitJumpIfJSReceiver() { BuildJumpIfJSReceiver(); }
3446
3447void BytecodeGraphBuilder::VisitJumpIfJSReceiverConstant() {
3448  BuildJumpIfJSReceiver();
3449}
3450
3451void BytecodeGraphBuilder::VisitJumpIfNull() {
3452  BuildJumpIfEqual(jsgraph()->NullConstant());
3453}
3454
3455void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
3456  BuildJumpIfEqual(jsgraph()->NullConstant());
3457}
3458
3459void BytecodeGraphBuilder::VisitJumpIfNotNull() {
3460  BuildJumpIfNotEqual(jsgraph()->NullConstant());
3461}
3462
3463void BytecodeGraphBuilder::VisitJumpIfNotNullConstant() {
3464  BuildJumpIfNotEqual(jsgraph()->NullConstant());
3465}
3466
3467void BytecodeGraphBuilder::VisitJumpIfUndefined() {
3468  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
3469}
3470
3471void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
3472  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
3473}
3474
3475void BytecodeGraphBuilder::VisitJumpIfNotUndefined() {
3476  BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
3477}
3478
3479void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
3480  BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
3481}
3482
3483void BytecodeGraphBuilder::VisitJumpIfUndefinedOrNull() {
3484  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
3485  BuildJumpIfEqual(jsgraph()->NullConstant());
3486}
3487
3488void BytecodeGraphBuilder::VisitJumpIfUndefinedOrNullConstant() {
3489  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
3490  BuildJumpIfEqual(jsgraph()->NullConstant());
3491}
3492
3493void BytecodeGraphBuilder::VisitJumpLoop() {
3494  BuildIterationBodyStackCheck();
3495  BuildJump();
3496}
3497
3498void BytecodeGraphBuilder::BuildSwitchOnSmi(Node* condition) {
3499  interpreter::JumpTableTargetOffsets offsets =
3500      bytecode_iterator().GetJumpTableTargetOffsets();
3501
3502  NewSwitch(condition, offsets.size() + 1);
3503  for (interpreter::JumpTableTargetOffset entry : offsets) {
3504    SubEnvironment sub_environment(this);
3505    NewIfValue(entry.case_value);
3506    MergeIntoSuccessorEnvironment(entry.target_offset);
3507  }
3508  NewIfDefault();
3509}
3510
3511void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
3512  PrepareEagerCheckpoint();
3513
3514  Node* acc = environment()->LookupAccumulator();
3515  Node* acc_smi = NewNode(simplified()->CheckSmi(FeedbackSource()), acc);
3516  BuildSwitchOnSmi(acc_smi);
3517}
3518
3519void BytecodeGraphBuilder::VisitSetPendingMessage() {
3520  Node* previous_message = NewNode(javascript()->LoadMessage());
3521  NewNode(javascript()->StoreMessage(), environment()->LookupAccumulator());
3522  environment()->BindAccumulator(previous_message);
3523}
3524
3525void BytecodeGraphBuilder::BuildReturn(const BytecodeLivenessState* liveness) {
3526  BuildLoopExitsForFunctionExit(liveness);
3527  Node* pop_node = jsgraph()->ZeroConstant();
3528  Node* control =
3529      NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
3530  MergeControlToLeaveFunction(control);
3531}
3532
3533void BytecodeGraphBuilder::VisitReturn() {
3534  BuildReturn(bytecode_analysis().GetInLivenessFor(
3535      bytecode_iterator().current_offset()));
3536}
3537
3538void BytecodeGraphBuilder::VisitDebugger() {
3539  PrepareEagerCheckpoint();
3540  Node* call = NewNode(javascript()->Debugger());
3541  environment()->RecordAfterState(call, Environment::kAttachFrameState);
3542}
3543
3544// We cannot create a graph from the debugger copy of the bytecode array.
3545#define DEBUG_BREAK(Name, ...) \
3546  void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
3547DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK)
3548#undef DEBUG_BREAK
3549
3550void BytecodeGraphBuilder::VisitIncBlockCounter() {
3551  Node* closure = GetFunctionClosure();
3552  Node* coverage_array_slot =
3553      jsgraph()->Constant(bytecode_iterator().GetIndexOperand(0));
3554
3555  // Lowered by js-intrinsic-lowering to call Builtin::kIncBlockCounter.
3556  const Operator* op =
3557      javascript()->CallRuntime(Runtime::kInlineIncBlockCounter);
3558
3559  NewNode(op, closure, coverage_array_slot);
3560}
3561
3562void BytecodeGraphBuilder::VisitForInEnumerate() {
3563  Node* receiver =
3564      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3565  Node* enumerator = NewNode(javascript()->ForInEnumerate(), receiver);
3566  environment()->BindAccumulator(enumerator, Environment::kAttachFrameState);
3567}
3568
3569void BytecodeGraphBuilder::VisitForInPrepare() {
3570  PrepareEagerCheckpoint();
3571  Node* enumerator = environment()->LookupAccumulator();
3572
3573  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
3574  JSTypeHintLowering::LoweringResult lowering =
3575      TryBuildSimplifiedForInPrepare(enumerator, slot);
3576  if (lowering.IsExit()) return;
3577  DCHECK(!lowering.Changed());
3578  FeedbackSource feedback = CreateFeedbackSource(slot);
3579  Node* node = NewNode(javascript()->ForInPrepare(GetForInMode(slot), feedback),
3580                       enumerator, feedback_vector_node());
3581  environment()->BindRegistersToProjections(
3582      bytecode_iterator().GetRegisterOperand(0), node);
3583}
3584
3585void BytecodeGraphBuilder::VisitForInContinue() {
3586  PrepareEagerCheckpoint();
3587  Node* index =
3588      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3589  Node* cache_length =
3590      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
3591  Node* exit_cond = NewNode(simplified()->SpeculativeNumberLessThan(
3592                                NumberOperationHint::kSignedSmall),
3593                            index, cache_length);
3594  environment()->BindAccumulator(exit_cond);
3595}
3596
3597void BytecodeGraphBuilder::VisitForInNext() {
3598  PrepareEagerCheckpoint();
3599  Node* receiver =
3600      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3601  Node* index =
3602      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
3603  int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
3604  Node* cache_type = environment()->LookupRegister(
3605      interpreter::Register(catch_reg_pair_index));
3606  Node* cache_array = environment()->LookupRegister(
3607      interpreter::Register(catch_reg_pair_index + 1));
3608
3609  // We need to rename the {index} here, as in case of OSR we lose the
3610  // information that the {index} is always a valid unsigned Smi value.
3611  index = NewNode(common()->TypeGuard(Type::UnsignedSmall()), index);
3612
3613  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(3);
3614  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedForInNext(
3615      receiver, cache_array, cache_type, index, slot);
3616  if (lowering.IsExit()) return;
3617
3618  DCHECK(!lowering.Changed());
3619  FeedbackSource feedback = CreateFeedbackSource(slot);
3620  Node* node =
3621      NewNode(javascript()->ForInNext(GetForInMode(slot), feedback), receiver,
3622              cache_array, cache_type, index, feedback_vector_node());
3623  environment()->BindAccumulator(node, Environment::kAttachFrameState);
3624}
3625
3626void BytecodeGraphBuilder::VisitForInStep() {
3627  PrepareEagerCheckpoint();
3628  Node* index =
3629      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3630  index = NewNode(simplified()->SpeculativeSafeIntegerAdd(
3631                      NumberOperationHint::kSignedSmall),
3632                  index, jsgraph()->OneConstant());
3633  environment()->BindAccumulator(index, Environment::kAttachFrameState);
3634}
3635
3636void BytecodeGraphBuilder::VisitGetIterator() {
3637  PrepareEagerCheckpoint();
3638  Node* receiver =
3639      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3640  FeedbackSource load_feedback =
3641      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
3642  FeedbackSource call_feedback =
3643      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
3644  const Operator* op = javascript()->GetIterator(load_feedback, call_feedback);
3645
3646  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedGetIterator(
3647      op, receiver, load_feedback.slot, call_feedback.slot);
3648  if (lowering.IsExit()) return;
3649
3650  DCHECK(!lowering.Changed());
3651  STATIC_ASSERT(JSGetIteratorNode::ReceiverIndex() == 0);
3652  STATIC_ASSERT(JSGetIteratorNode::FeedbackVectorIndex() == 1);
3653  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
3654  Node* iterator = NewNode(op, receiver, feedback_vector_node());
3655  environment()->BindAccumulator(iterator, Environment::kAttachFrameState);
3656}
3657
3658void BytecodeGraphBuilder::VisitSuspendGenerator() {
3659  Node* generator = environment()->LookupRegister(
3660      bytecode_iterator().GetRegisterOperand(0));
3661  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
3662  // We assume we are storing a range starting from index 0.
3663  CHECK_EQ(0, first_reg.index());
3664  int register_count =
3665      static_cast<int>(bytecode_iterator().GetRegisterCountOperand(2));
3666  int parameter_count_without_receiver = bytecode_array().parameter_count() - 1;
3667
3668  Node* suspend_id = jsgraph()->SmiConstant(
3669      bytecode_iterator().GetUnsignedImmediateOperand(3));
3670
3671  // The offsets used by the bytecode iterator are relative to a different base
3672  // than what is used in the interpreter, hence the addition.
3673  Node* offset =
3674      jsgraph()->Constant(bytecode_iterator().current_offset() +
3675                          (BytecodeArray::kHeaderSize - kHeapObjectTag));
3676
3677  const BytecodeLivenessState* liveness = bytecode_analysis().GetInLivenessFor(
3678      bytecode_iterator().current_offset());
3679
3680  // Maybe overallocate the value list since we don't know how many registers
3681  // are live.
3682  // TODO(leszeks): We could get this count from liveness rather than the
3683  // register list.
3684  int value_input_count = 3 + parameter_count_without_receiver + register_count;
3685
3686  Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
3687  value_inputs[0] = generator;
3688  value_inputs[1] = suspend_id;
3689  value_inputs[2] = offset;
3690
3691  int count_written = 0;
3692  // Store the parameters.
3693  for (int i = 0; i < parameter_count_without_receiver; i++) {
3694    value_inputs[3 + count_written++] =
3695        environment()->LookupRegister(bytecode_iterator().GetParameter(i));
3696  }
3697
3698  // Store the registers.
3699  for (int i = 0; i < register_count; ++i) {
3700    if (liveness == nullptr || liveness->RegisterIsLive(i)) {
3701      int index_in_parameters_and_registers =
3702          parameter_count_without_receiver + i;
3703      while (count_written < index_in_parameters_and_registers) {
3704        value_inputs[3 + count_written++] = jsgraph()->OptimizedOutConstant();
3705      }
3706      value_inputs[3 + count_written++] =
3707          environment()->LookupRegister(interpreter::Register(i));
3708      DCHECK_EQ(count_written, index_in_parameters_and_registers + 1);
3709    }
3710  }
3711
3712  // Use the actual written count rather than the register count to create the
3713  // node.
3714  MakeNode(javascript()->GeneratorStore(count_written), 3 + count_written,
3715           value_inputs, false);
3716
3717  // TODO(leszeks): This over-approximates the liveness at exit, only the
3718  // accumulator should be live by this point.
3719  BuildReturn(bytecode_analysis().GetInLivenessFor(
3720      bytecode_iterator().current_offset()));
3721}
3722
3723void BytecodeGraphBuilder::BuildSwitchOnGeneratorState(
3724    const ZoneVector<ResumeJumpTarget>& resume_jump_targets,
3725    bool allow_fallthrough_on_executing) {
3726  Node* generator_state = environment()->LookupGeneratorState();
3727
3728  int extra_cases = allow_fallthrough_on_executing ? 2 : 1;
3729  NewSwitch(generator_state,
3730            static_cast<int>(resume_jump_targets.size() + extra_cases));
3731  for (const ResumeJumpTarget& target : resume_jump_targets) {
3732    SubEnvironment sub_environment(this);
3733    NewIfValue(target.suspend_id());
3734    if (target.is_leaf()) {
3735      // Mark that we are resuming executing.
3736      environment()->BindGeneratorState(
3737          jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
3738    }
3739    // Jump to the target offset, whether it's a loop header or the resume.
3740    MergeIntoSuccessorEnvironment(target.target_offset());
3741  }
3742
3743  {
3744    SubEnvironment sub_environment(this);
3745    // We should never hit the default case (assuming generator state cannot be
3746    // corrupted), so abort if we do.
3747    // TODO(leszeks): Maybe only check this in debug mode, and otherwise use
3748    // the default to represent one of the cases above/fallthrough below?
3749    NewIfDefault();
3750    NewNode(simplified()->RuntimeAbort(AbortReason::kInvalidJumpTableIndex));
3751    // TODO(7099): Investigate if we need LoopExit here.
3752    Node* control = NewNode(common()->Throw());
3753    MergeControlToLeaveFunction(control);
3754  }
3755
3756  if (allow_fallthrough_on_executing) {
3757    // If we are executing (rather than resuming), and we allow it, just fall
3758    // through to the actual loop body.
3759    NewIfValue(JSGeneratorObject::kGeneratorExecuting);
3760  } else {
3761    // Otherwise, this environment is dead.
3762    set_environment(nullptr);
3763  }
3764}
3765
3766void BytecodeGraphBuilder::VisitSwitchOnGeneratorState() {
3767  Node* generator =
3768      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3769
3770  Node* generator_is_undefined =
3771      NewNode(simplified()->ReferenceEqual(), generator,
3772              jsgraph()->UndefinedConstant());
3773
3774  NewBranch(generator_is_undefined);
3775  {
3776    SubEnvironment resume_env(this);
3777    NewIfFalse();
3778
3779    Node* generator_state =
3780        NewNode(javascript()->GeneratorRestoreContinuation(), generator);
3781    environment()->BindGeneratorState(generator_state);
3782
3783    Node* generator_context =
3784        NewNode(javascript()->GeneratorRestoreContext(), generator);
3785    environment()->SetContext(generator_context);
3786
3787    BuildSwitchOnGeneratorState(bytecode_analysis().resume_jump_targets(),
3788                                false);
3789  }
3790
3791  // Fallthrough for the first-call case.
3792  NewIfTrue();
3793}
3794
3795void BytecodeGraphBuilder::VisitResumeGenerator() {
3796  Node* generator =
3797      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3798  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
3799  // We assume we are restoring registers starting fromm index 0.
3800  CHECK_EQ(0, first_reg.index());
3801
3802  const BytecodeLivenessState* liveness = bytecode_analysis().GetOutLivenessFor(
3803      bytecode_iterator().current_offset());
3804
3805  int parameter_count_without_receiver = bytecode_array().parameter_count() - 1;
3806
3807  // Mapping between registers and array indices must match that used in
3808  // InterpreterAssembler::ExportParametersAndRegisterFile.
3809  for (int i = 0; i < environment()->register_count(); ++i) {
3810    if (liveness == nullptr || liveness->RegisterIsLive(i)) {
3811      Node* value = NewNode(javascript()->GeneratorRestoreRegister(
3812                                parameter_count_without_receiver + i),
3813                            generator);
3814      environment()->BindRegister(interpreter::Register(i), value);
3815    }
3816  }
3817
3818  // Update the accumulator with the generator's input_or_debug_pos.
3819  Node* input_or_debug_pos =
3820      NewNode(javascript()->GeneratorRestoreInputOrDebugPos(), generator);
3821  environment()->BindAccumulator(input_or_debug_pos);
3822}
3823
3824void BytecodeGraphBuilder::VisitWide() {
3825  // Consumed by the BytecodeArrayIterator.
3826  UNREACHABLE();
3827}
3828
3829void BytecodeGraphBuilder::VisitExtraWide() {
3830  // Consumed by the BytecodeArrayIterator.
3831  UNREACHABLE();
3832}
3833
3834void BytecodeGraphBuilder::VisitIllegal() {
3835  // Not emitted in valid bytecode.
3836  UNREACHABLE();
3837}
3838
3839void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
3840  auto it = merge_environments_.find(current_offset);
3841  if (it != merge_environments_.end()) {
3842    mark_as_needing_eager_checkpoint(true);
3843    if (environment() != nullptr) {
3844      it->second->Merge(environment(),
3845                        bytecode_analysis().GetInLivenessFor(current_offset));
3846    }
3847    set_environment(it->second);
3848  }
3849}
3850
3851void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
3852  if (bytecode_analysis().IsLoopHeader(current_offset)) {
3853    mark_as_needing_eager_checkpoint(true);
3854    const LoopInfo& loop_info =
3855        bytecode_analysis().GetLoopInfoFor(current_offset);
3856    const BytecodeLivenessState* liveness =
3857        bytecode_analysis().GetInLivenessFor(current_offset);
3858
3859    const auto& resume_jump_targets = loop_info.resume_jump_targets();
3860    bool generate_suspend_switch = !resume_jump_targets.empty();
3861
3862    // Add loop header.
3863    environment()->PrepareForLoop(loop_info.assignments(), liveness);
3864
3865    // Store a copy of the environment so we can connect merged back edge inputs
3866    // to the loop header.
3867    merge_environments_[current_offset] = environment()->Copy();
3868
3869    // If this loop contains resumes, create a new switch just after the loop
3870    // for those resumes.
3871    if (generate_suspend_switch) {
3872      BuildSwitchOnGeneratorState(loop_info.resume_jump_targets(), true);
3873
3874      // TODO(leszeks): At this point we know we are executing rather than
3875      // resuming, so we should be able to prune off the phis in the environment
3876      // related to the resume path.
3877
3878      // Set the generator state to a known constant.
3879      environment()->BindGeneratorState(
3880          jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
3881    }
3882  }
3883}
3884
3885void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
3886  BuildLoopExitsForBranch(target_offset);
3887  Environment*& merge_environment = merge_environments_[target_offset];
3888
3889  if (merge_environment == nullptr) {
3890    // Append merge nodes to the environment. We may merge here with another
3891    // environment. So add a place holder for merge nodes. We may add redundant
3892    // but will be eliminated in a later pass.
3893    NewMerge();
3894    merge_environment = environment();
3895  } else {
3896    // Merge any values which are live coming into the successor.
3897    merge_environment->Merge(
3898        environment(), bytecode_analysis().GetInLivenessFor(target_offset));
3899  }
3900  set_environment(nullptr);
3901}
3902
3903void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
3904  exit_controls_.push_back(exit);
3905  set_environment(nullptr);
3906}
3907
3908void BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
3909  int origin_offset = bytecode_iterator().current_offset();
3910  // Only build loop exits for forward edges.
3911  if (target_offset > origin_offset) {
3912    BuildLoopExitsUntilLoop(
3913        bytecode_analysis().GetLoopOffsetFor(target_offset),
3914        bytecode_analysis().GetInLivenessFor(target_offset));
3915  }
3916}
3917
3918void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(
3919    int loop_offset, const BytecodeLivenessState* liveness) {
3920  int origin_offset = bytecode_iterator().current_offset();
3921  int current_loop = bytecode_analysis().GetLoopOffsetFor(origin_offset);
3922  // The limit_offset is the stop offset for building loop exists, used for OSR.
3923  // It prevents the creations of loopexits for loops which do not exist.
3924  loop_offset = std::max(loop_offset, currently_peeled_loop_offset_);
3925
3926  while (loop_offset < current_loop) {
3927    Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
3928    const LoopInfo& loop_info =
3929        bytecode_analysis().GetLoopInfoFor(current_loop);
3930    environment()->PrepareForLoopExit(loop_node, loop_info.assignments(),
3931                                      liveness);
3932    current_loop = loop_info.parent_offset();
3933  }
3934}
3935
3936void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit(
3937    const BytecodeLivenessState* liveness) {
3938  BuildLoopExitsUntilLoop(-1, liveness);
3939}
3940
3941void BytecodeGraphBuilder::BuildJump() {
3942  MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3943}
3944
3945void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
3946  NewBranch(condition, BranchHint::kNone);
3947  {
3948    SubEnvironment sub_environment(this);
3949    NewIfTrue();
3950    MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3951  }
3952  NewIfFalse();
3953}
3954
3955void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
3956  NewBranch(condition, BranchHint::kNone);
3957  {
3958    SubEnvironment sub_environment(this);
3959    NewIfFalse();
3960    MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3961  }
3962  NewIfTrue();
3963}
3964
3965void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
3966  Node* accumulator = environment()->LookupAccumulator();
3967  Node* condition =
3968      NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
3969  BuildJumpIf(condition);
3970}
3971
3972void BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
3973  Node* accumulator = environment()->LookupAccumulator();
3974  Node* condition =
3975      NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
3976  BuildJumpIfNot(condition);
3977}
3978
3979void BytecodeGraphBuilder::BuildJumpIfFalse() {
3980  NewBranch(environment()->LookupAccumulator(), BranchHint::kNone);
3981  {
3982    SubEnvironment sub_environment(this);
3983    NewIfFalse();
3984    environment()->BindAccumulator(jsgraph()->FalseConstant());
3985    MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3986  }
3987  NewIfTrue();
3988  environment()->BindAccumulator(jsgraph()->TrueConstant());
3989}
3990
3991void BytecodeGraphBuilder::BuildJumpIfTrue() {
3992  NewBranch(environment()->LookupAccumulator(), BranchHint::kNone);
3993  {
3994    SubEnvironment sub_environment(this);
3995    NewIfTrue();
3996    environment()->BindAccumulator(jsgraph()->TrueConstant());
3997    MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3998  }
3999  NewIfFalse();
4000  environment()->BindAccumulator(jsgraph()->FalseConstant());
4001}
4002
4003void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
4004  Node* accumulator = environment()->LookupAccumulator();
4005  Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
4006  BuildJumpIf(condition);
4007}
4008
4009void BytecodeGraphBuilder::BuildJumpIfToBooleanFalse() {
4010  Node* accumulator = environment()->LookupAccumulator();
4011  Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
4012  BuildJumpIfNot(condition);
4013}
4014
4015void BytecodeGraphBuilder::BuildJumpIfNotHole() {
4016  Node* accumulator = environment()->LookupAccumulator();
4017  Node* condition = NewNode(simplified()->ReferenceEqual(), accumulator,
4018                            jsgraph()->TheHoleConstant());
4019  BuildJumpIfNot(condition);
4020}
4021
4022void BytecodeGraphBuilder::BuildJumpIfJSReceiver() {
4023  Node* accumulator = environment()->LookupAccumulator();
4024  Node* condition = NewNode(simplified()->ObjectIsReceiver(), accumulator);
4025  BuildJumpIf(condition);
4026}
4027
4028JSTypeHintLowering::LoweringResult
4029BytecodeGraphBuilder::TryBuildSimplifiedUnaryOp(const Operator* op,
4030                                                Node* operand,
4031                                                FeedbackSlot slot) {
4032  Node* effect = environment()->GetEffectDependency();
4033  Node* control = environment()->GetControlDependency();
4034  JSTypeHintLowering::LoweringResult result =
4035      type_hint_lowering().ReduceUnaryOperation(op, operand, effect, control,
4036                                                slot);
4037  ApplyEarlyReduction(result);
4038  return result;
4039}
4040
4041JSTypeHintLowering::LoweringResult
4042BytecodeGraphBuilder::TryBuildSimplifiedBinaryOp(const Operator* op, Node* left,
4043                                                 Node* right,
4044                                                 FeedbackSlot slot) {
4045  Node* effect = environment()->GetEffectDependency();
4046  Node* control = environment()->GetControlDependency();
4047  JSTypeHintLowering::LoweringResult result =
4048      type_hint_lowering().ReduceBinaryOperation(op, left, right, effect,
4049                                                 control, slot);
4050  ApplyEarlyReduction(result);
4051  return result;
4052}
4053
4054JSTypeHintLowering::LoweringResult
4055BytecodeGraphBuilder::TryBuildSimplifiedForInNext(Node* receiver,
4056                                                  Node* cache_array,
4057                                                  Node* cache_type, Node* index,
4058                                                  FeedbackSlot slot) {
4059  Node* effect = environment()->GetEffectDependency();
4060  Node* control = environment()->GetControlDependency();
4061  JSTypeHintLowering::LoweringResult result =
4062      type_hint_lowering().ReduceForInNextOperation(
4063          receiver, cache_array, cache_type, index, effect, control, slot);
4064  ApplyEarlyReduction(result);
4065  return result;
4066}
4067
4068JSTypeHintLowering::LoweringResult
4069BytecodeGraphBuilder::TryBuildSimplifiedForInPrepare(Node* enumerator,
4070                                                     FeedbackSlot slot) {
4071  Node* effect = environment()->GetEffectDependency();
4072  Node* control = environment()->GetControlDependency();
4073  JSTypeHintLowering::LoweringResult result =
4074      type_hint_lowering().ReduceForInPrepareOperation(enumerator, effect,
4075                                                       control, slot);
4076  ApplyEarlyReduction(result);
4077  return result;
4078}
4079
4080JSTypeHintLowering::LoweringResult
4081BytecodeGraphBuilder::TryBuildSimplifiedToNumber(Node* value,
4082                                                 FeedbackSlot slot) {
4083  Node* effect = environment()->GetEffectDependency();
4084  Node* control = environment()->GetControlDependency();
4085  JSTypeHintLowering::LoweringResult result =
4086      type_hint_lowering().ReduceToNumberOperation(value, effect, control,
4087                                                   slot);
4088  ApplyEarlyReduction(result);
4089  return result;
4090}
4091
4092JSTypeHintLowering::LoweringResult BytecodeGraphBuilder::TryBuildSimplifiedCall(
4093    const Operator* op, Node* const* args, int arg_count, FeedbackSlot slot) {
4094  Node* effect = environment()->GetEffectDependency();
4095  Node* control = environment()->GetControlDependency();
4096  JSTypeHintLowering::LoweringResult result =
4097      type_hint_lowering().ReduceCallOperation(op, args, arg_count, effect,
4098                                               control, slot);
4099  ApplyEarlyReduction(result);
4100  return result;
4101}
4102
4103JSTypeHintLowering::LoweringResult
4104BytecodeGraphBuilder::TryBuildSimplifiedConstruct(const Operator* op,
4105                                                  Node* const* args,
4106                                                  int arg_count,
4107                                                  FeedbackSlot slot) {
4108  Node* effect = environment()->GetEffectDependency();
4109  Node* control = environment()->GetControlDependency();
4110  JSTypeHintLowering::LoweringResult result =
4111      type_hint_lowering().ReduceConstructOperation(op, args, arg_count, effect,
4112                                                    control, slot);
4113  ApplyEarlyReduction(result);
4114  return result;
4115}
4116
4117JSTypeHintLowering::LoweringResult
4118BytecodeGraphBuilder::TryBuildSimplifiedGetIterator(const Operator* op,
4119                                                    Node* receiver,
4120                                                    FeedbackSlot load_slot,
4121                                                    FeedbackSlot call_slot) {
4122  Node* effect = environment()->GetEffectDependency();
4123  Node* control = environment()->GetControlDependency();
4124  JSTypeHintLowering::LoweringResult early_reduction =
4125      type_hint_lowering().ReduceGetIteratorOperation(
4126          op, receiver, effect, control, load_slot, call_slot);
4127  ApplyEarlyReduction(early_reduction);
4128  return early_reduction;
4129}
4130
4131JSTypeHintLowering::LoweringResult
4132BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op,
4133                                                  FeedbackSlot slot) {
4134  Node* effect = environment()->GetEffectDependency();
4135  Node* control = environment()->GetControlDependency();
4136  JSTypeHintLowering::LoweringResult early_reduction =
4137      type_hint_lowering().ReduceLoadNamedOperation(op, effect, control, slot);
4138  ApplyEarlyReduction(early_reduction);
4139  return early_reduction;
4140}
4141
4142JSTypeHintLowering::LoweringResult
4143BytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(const Operator* op,
4144                                                  Node* receiver, Node* key,
4145                                                  FeedbackSlot slot) {
4146  Node* effect = environment()->GetEffectDependency();
4147  Node* control = environment()->GetControlDependency();
4148  JSTypeHintLowering::LoweringResult result =
4149      type_hint_lowering().ReduceLoadKeyedOperation(op, receiver, key, effect,
4150                                                    control, slot);
4151  ApplyEarlyReduction(result);
4152  return result;
4153}
4154
4155JSTypeHintLowering::LoweringResult
4156BytecodeGraphBuilder::TryBuildSimplifiedStoreNamed(const Operator* op,
4157                                                   Node* receiver, Node* value,
4158                                                   FeedbackSlot slot) {
4159  Node* effect = environment()->GetEffectDependency();
4160  Node* control = environment()->GetControlDependency();
4161  JSTypeHintLowering::LoweringResult result =
4162      type_hint_lowering().ReduceStoreNamedOperation(op, receiver, value,
4163                                                     effect, control, slot);
4164  ApplyEarlyReduction(result);
4165  return result;
4166}
4167
4168JSTypeHintLowering::LoweringResult
4169BytecodeGraphBuilder::TryBuildSimplifiedStoreKeyed(const Operator* op,
4170                                                   Node* receiver, Node* key,
4171                                                   Node* value,
4172                                                   FeedbackSlot slot) {
4173  Node* effect = environment()->GetEffectDependency();
4174  Node* control = environment()->GetControlDependency();
4175  JSTypeHintLowering::LoweringResult result =
4176      type_hint_lowering().ReduceStoreKeyedOperation(op, receiver, key, value,
4177                                                     effect, control, slot);
4178  ApplyEarlyReduction(result);
4179  return result;
4180}
4181
4182void BytecodeGraphBuilder::ApplyEarlyReduction(
4183    JSTypeHintLowering::LoweringResult reduction) {
4184  if (reduction.IsExit()) {
4185    MergeControlToLeaveFunction(reduction.control());
4186  } else if (reduction.IsSideEffectFree()) {
4187    environment()->UpdateEffectDependency(reduction.effect());
4188    environment()->UpdateControlDependency(reduction.control());
4189  } else {
4190    DCHECK(!reduction.Changed());
4191    // At the moment, we assume side-effect free reduction. To support
4192    // side-effects, we would have to invalidate the eager checkpoint,
4193    // so that deoptimization does not repeat the side effect.
4194  }
4195}
4196
4197Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
4198  if (size > input_buffer_size_) {
4199    size = size + kInputBufferSizeIncrement + input_buffer_size_;
4200    input_buffer_ = local_zone()->NewArray<Node*>(size);
4201    input_buffer_size_ = size;
4202  }
4203  return input_buffer_;
4204}
4205
4206void BytecodeGraphBuilder::ExitThenEnterExceptionHandlers(int current_offset) {
4207  DisallowGarbageCollection no_gc;
4208  HandlerTable table(bytecode_array().handler_table_address(),
4209                     bytecode_array().handler_table_size(),
4210                     HandlerTable::kRangeBasedEncoding);
4211
4212  // Potentially exit exception handlers.
4213  while (!exception_handlers_.empty()) {
4214    int current_end = exception_handlers_.top().end_offset_;
4215    if (current_offset < current_end) break;  // Still covered by range.
4216    exception_handlers_.pop();
4217  }
4218
4219  // Potentially enter exception handlers.
4220  int num_entries = table.NumberOfRangeEntries();
4221  while (current_exception_handler_ < num_entries) {
4222    int next_start = table.GetRangeStart(current_exception_handler_);
4223    if (current_offset < next_start) break;  // Not yet covered by range.
4224    int next_end = table.GetRangeEnd(current_exception_handler_);
4225    int next_handler = table.GetRangeHandler(current_exception_handler_);
4226    int context_register = table.GetRangeData(current_exception_handler_);
4227    exception_handlers_.push(
4228        {next_start, next_end, next_handler, context_register});
4229    current_exception_handler_++;
4230  }
4231}
4232
4233Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
4234                                     Node* const* value_inputs,
4235                                     bool incomplete) {
4236  DCHECK_EQ(op->ValueInputCount(), value_input_count);
4237  // Parameter nodes must be created through GetParameter.
4238  DCHECK_IMPLIES(
4239      op->opcode() == IrOpcode::kParameter,
4240      (nullptr == cached_parameters_[static_cast<std::size_t>(
4241                      ParameterIndexOf(op) - ParameterInfo::kMinIndex)]));
4242
4243  bool has_context = OperatorProperties::HasContextInput(op);
4244  bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
4245  bool has_control = op->ControlInputCount() == 1;
4246  bool has_effect = op->EffectInputCount() == 1;
4247
4248  DCHECK_LT(op->ControlInputCount(), 2);
4249  DCHECK_LT(op->EffectInputCount(), 2);
4250
4251  Node* result = nullptr;
4252  if (!has_context && !has_frame_state && !has_control && !has_effect) {
4253    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
4254  } else {
4255    bool inside_handler = !exception_handlers_.empty();
4256    int input_count_with_deps = value_input_count;
4257    if (has_context) ++input_count_with_deps;
4258    if (has_frame_state) ++input_count_with_deps;
4259    if (has_control) ++input_count_with_deps;
4260    if (has_effect) ++input_count_with_deps;
4261    Node** buffer = EnsureInputBufferSize(input_count_with_deps);
4262    if (value_input_count > 0) {
4263      memcpy(buffer, value_inputs, kSystemPointerSize * value_input_count);
4264    }
4265    Node** current_input = buffer + value_input_count;
4266    if (has_context) {
4267      *current_input++ = OperatorProperties::NeedsExactContext(op)
4268                             ? environment()->Context()
4269                             : native_context_node();
4270    }
4271    if (has_frame_state) {
4272      // The frame state will be inserted later. Here we misuse the {Dead} node
4273      // as a sentinel to be later overwritten with the real frame state by the
4274      // calls to {PrepareFrameState} within individual visitor methods.
4275      *current_input++ = jsgraph()->Dead();
4276    }
4277    if (has_effect) {
4278      *current_input++ = environment()->GetEffectDependency();
4279    }
4280    if (has_control) {
4281      *current_input++ = environment()->GetControlDependency();
4282    }
4283    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
4284    // Update the current control dependency for control-producing nodes.
4285    if (result->op()->ControlOutputCount() > 0) {
4286      environment()->UpdateControlDependency(result);
4287    }
4288    // Update the current effect dependency for effect-producing nodes.
4289    if (result->op()->EffectOutputCount() > 0) {
4290      environment()->UpdateEffectDependency(result);
4291    }
4292    // Add implicit exception continuation for throwing nodes.
4293    if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
4294      int handler_offset = exception_handlers_.top().handler_offset_;
4295      int context_index = exception_handlers_.top().context_register_;
4296      interpreter::Register context_register(context_index);
4297      Environment* success_env = environment()->Copy();
4298      const Operator* if_exception = common()->IfException();
4299      Node* effect = environment()->GetEffectDependency();
4300      Node* on_exception = graph()->NewNode(if_exception, effect, result);
4301      Node* context = environment()->LookupRegister(context_register);
4302      environment()->UpdateControlDependency(on_exception);
4303      environment()->UpdateEffectDependency(on_exception);
4304      environment()->BindAccumulator(on_exception);
4305      environment()->SetContext(context);
4306      MergeIntoSuccessorEnvironment(handler_offset);
4307      set_environment(success_env);
4308    }
4309    // Add implicit success continuation for throwing nodes.
4310    if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
4311      const Operator* if_success = common()->IfSuccess();
4312      Node* on_success = graph()->NewNode(if_success, result);
4313      environment()->UpdateControlDependency(on_success);
4314    }
4315    // Ensure checkpoints are created after operations with side-effects.
4316    if (has_effect && !result->op()->HasProperty(Operator::kNoWrite)) {
4317      mark_as_needing_eager_checkpoint(true);
4318    }
4319  }
4320
4321  return result;
4322}
4323
4324
4325Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
4326  const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
4327  Node** buffer = EnsureInputBufferSize(count + 1);
4328  MemsetPointer(buffer, input, count);
4329  buffer[count] = control;
4330  return graph()->NewNode(phi_op, count + 1, buffer, true);
4331}
4332
4333Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
4334                                         Node* control) {
4335  const Operator* phi_op = common()->EffectPhi(count);
4336  Node** buffer = EnsureInputBufferSize(count + 1);
4337  MemsetPointer(buffer, input, count);
4338  buffer[count] = control;
4339  return graph()->NewNode(phi_op, count + 1, buffer, true);
4340}
4341
4342
4343Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
4344  int inputs = control->op()->ControlInputCount() + 1;
4345  if (control->opcode() == IrOpcode::kLoop) {
4346    // Control node for loop exists, add input.
4347    const Operator* op = common()->Loop(inputs);
4348    control->AppendInput(graph_zone(), other);
4349    NodeProperties::ChangeOp(control, op);
4350  } else if (control->opcode() == IrOpcode::kMerge) {
4351    // Control node for merge exists, add input.
4352    const Operator* op = common()->Merge(inputs);
4353    control->AppendInput(graph_zone(), other);
4354    NodeProperties::ChangeOp(control, op);
4355  } else {
4356    // Control node is a singleton, introduce a merge.
4357    const Operator* op = common()->Merge(inputs);
4358    Node* merge_inputs[] = {control, other};
4359    control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
4360  }
4361  return control;
4362}
4363
4364Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
4365                                        Node* control) {
4366  int inputs = control->op()->ControlInputCount();
4367  if (value->opcode() == IrOpcode::kEffectPhi &&
4368      NodeProperties::GetControlInput(value) == control) {
4369    // Phi already exists, add input.
4370    value->InsertInput(graph_zone(), inputs - 1, other);
4371    NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
4372  } else if (value != other) {
4373    // Phi does not exist yet, introduce one.
4374    value = NewEffectPhi(inputs, value, control);
4375    value->ReplaceInput(inputs - 1, other);
4376  }
4377  return value;
4378}
4379
4380Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
4381                                       Node* control) {
4382  int inputs = control->op()->ControlInputCount();
4383  if (value->opcode() == IrOpcode::kPhi &&
4384      NodeProperties::GetControlInput(value) == control) {
4385    // Phi already exists, add input.
4386    value->InsertInput(graph_zone(), inputs - 1, other);
4387    NodeProperties::ChangeOp(
4388        value, common()->Phi(MachineRepresentation::kTagged, inputs));
4389  } else if (value != other) {
4390    // Phi does not exist yet, introduce one.
4391    value = NewPhi(inputs, value, control);
4392    value->ReplaceInput(inputs - 1, other);
4393  }
4394  return value;
4395}
4396
4397void BytecodeGraphBuilder::UpdateSourcePosition(int offset) {
4398  if (source_position_iterator().done()) return;
4399  if (source_position_iterator().code_offset() == offset) {
4400    source_positions_->SetCurrentPosition(SourcePosition(
4401        source_position_iterator().source_position().ScriptOffset(),
4402        start_position_.InliningId()));
4403    source_position_iterator().Advance();
4404  } else {
4405    DCHECK_GT(source_position_iterator().code_offset(), offset);
4406  }
4407}
4408
4409void BuildGraphFromBytecode(JSHeapBroker* broker, Zone* local_zone,
4410                            SharedFunctionInfoRef const& shared_info,
4411                            FeedbackCellRef const& feedback_cell,
4412                            BytecodeOffset osr_offset, JSGraph* jsgraph,
4413                            CallFrequency const& invocation_frequency,
4414                            SourcePositionTable* source_positions,
4415                            int inlining_id, CodeKind code_kind,
4416                            BytecodeGraphBuilderFlags flags,
4417                            TickCounter* tick_counter,
4418                            ObserveNodeInfo const& observe_node_info) {
4419  BytecodeGraphBuilder builder(
4420      broker, local_zone, broker->target_native_context(), shared_info,
4421      feedback_cell, osr_offset, jsgraph, invocation_frequency,
4422      source_positions, inlining_id, code_kind, flags, tick_counter,
4423      observe_node_info);
4424  builder.CreateGraph();
4425}
4426
4427}  // namespace compiler
4428}  // namespace internal
4429}  // namespace v8
4430