11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/compiler/bytecode-graph-builder.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/ast/ast.h"
81cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
91cb0ef41Sopenharmony_ci#include "src/codegen/source-position-table.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/tick-counter.h"
111cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h"
121cb0ef41Sopenharmony_ci#include "src/compiler/access-builder.h"
131cb0ef41Sopenharmony_ci#include "src/compiler/bytecode-analysis.h"
141cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h"
151cb0ef41Sopenharmony_ci#include "src/compiler/compiler-source-position-table.h"
161cb0ef41Sopenharmony_ci#include "src/compiler/js-heap-broker.h"
171cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h"
181cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h"
191cb0ef41Sopenharmony_ci#include "src/compiler/node-observer.h"
201cb0ef41Sopenharmony_ci#include "src/compiler/operator-properties.h"
211cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h"
221cb0ef41Sopenharmony_ci#include "src/compiler/state-values-utils.h"
231cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-array-iterator.h"
241cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-flags.h"
251cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h"
261cb0ef41Sopenharmony_ci#include "src/objects/js-array-inl.h"
271cb0ef41Sopenharmony_ci#include "src/objects/js-generator.h"
281cb0ef41Sopenharmony_ci#include "src/objects/literal-objects-inl.h"
291cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
301cb0ef41Sopenharmony_ci#include "src/objects/smi.h"
311cb0ef41Sopenharmony_ci#include "src/objects/template-objects-inl.h"
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cinamespace v8 {
341cb0ef41Sopenharmony_cinamespace internal {
351cb0ef41Sopenharmony_cinamespace compiler {
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ciclass BytecodeGraphBuilder {
381cb0ef41Sopenharmony_ci public:
391cb0ef41Sopenharmony_ci  BytecodeGraphBuilder(JSHeapBroker* broker, Zone* local_zone,
401cb0ef41Sopenharmony_ci                       NativeContextRef const& native_context,
411cb0ef41Sopenharmony_ci                       SharedFunctionInfoRef const& shared_info,
421cb0ef41Sopenharmony_ci                       FeedbackCellRef const& feedback_cell,
431cb0ef41Sopenharmony_ci                       BytecodeOffset osr_offset, JSGraph* jsgraph,
441cb0ef41Sopenharmony_ci                       CallFrequency const& invocation_frequency,
451cb0ef41Sopenharmony_ci                       SourcePositionTable* source_positions, int inlining_id,
461cb0ef41Sopenharmony_ci                       CodeKind code_kind, BytecodeGraphBuilderFlags flags,
471cb0ef41Sopenharmony_ci                       TickCounter* tick_counter,
481cb0ef41Sopenharmony_ci                       ObserveNodeInfo const& observe_node_info);
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  BytecodeGraphBuilder(const BytecodeGraphBuilder&) = delete;
511cb0ef41Sopenharmony_ci  BytecodeGraphBuilder& operator=(const BytecodeGraphBuilder&) = delete;
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  // Creates a graph by visiting bytecodes.
541cb0ef41Sopenharmony_ci  void CreateGraph();
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci private:
571cb0ef41Sopenharmony_ci  class Environment;
581cb0ef41Sopenharmony_ci  class OsrIteratorState;
591cb0ef41Sopenharmony_ci  struct SubEnvironment;
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  void RemoveMergeEnvironmentsBeforeOffset(int limit_offset);
621cb0ef41Sopenharmony_ci  void AdvanceToOsrEntryAndPeelLoops();
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  // Advance {bytecode_iterator} to the given offset. If possible, also advance
651cb0ef41Sopenharmony_ci  // {source_position_iterator} while updating the source position table.
661cb0ef41Sopenharmony_ci  void AdvanceIteratorsTo(int bytecode_offset);
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  void VisitSingleBytecode();
691cb0ef41Sopenharmony_ci  void VisitBytecodes();
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  // Get or create the node that represents the outer function closure.
721cb0ef41Sopenharmony_ci  Node* GetFunctionClosure();
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  // Get or create the node for this parameter index. If such a node is
751cb0ef41Sopenharmony_ci  // already cached, it is returned directly and the {debug_name_hint} is
761cb0ef41Sopenharmony_ci  // ignored.
771cb0ef41Sopenharmony_ci  Node* GetParameter(int index, const char* debug_name_hint = nullptr);
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  CodeKind code_kind() const { return code_kind_; }
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  // The node representing the current feedback vector is generated once prior
821cb0ef41Sopenharmony_ci  // to visiting bytecodes, and is later passed as input to other nodes that
831cb0ef41Sopenharmony_ci  // may need it.
841cb0ef41Sopenharmony_ci  // TODO(jgruber): Remove feedback_vector() and rename feedback_vector_node()
851cb0ef41Sopenharmony_ci  // to feedback_vector() once all uses of the direct heap object reference
861cb0ef41Sopenharmony_ci  // have been replaced with a Node* reference.
871cb0ef41Sopenharmony_ci  void CreateFeedbackVectorNode();
881cb0ef41Sopenharmony_ci  Node* feedback_vector_node() const {
891cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(feedback_vector_node_);
901cb0ef41Sopenharmony_ci    return feedback_vector_node_;
911cb0ef41Sopenharmony_ci  }
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  // Same as above for the feedback vector node.
941cb0ef41Sopenharmony_ci  void CreateNativeContextNode();
951cb0ef41Sopenharmony_ci  Node* native_context_node() const {
961cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(native_context_node_);
971cb0ef41Sopenharmony_ci    return native_context_node_;
981cb0ef41Sopenharmony_ci  }
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  Node* BuildLoadFeedbackCell(int index);
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  // Builder for loading a native context field.
1031cb0ef41Sopenharmony_ci  Node* BuildLoadNativeContextField(int index);
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  // Helper function for creating a feedback source containing type feedback
1061cb0ef41Sopenharmony_ci  // vector and a feedback slot.
1071cb0ef41Sopenharmony_ci  FeedbackSource CreateFeedbackSource(int slot_id);
1081cb0ef41Sopenharmony_ci  FeedbackSource CreateFeedbackSource(FeedbackSlot slot);
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  void set_environment(Environment* env) { environment_ = env; }
1111cb0ef41Sopenharmony_ci  const Environment* environment() const { return environment_; }
1121cb0ef41Sopenharmony_ci  Environment* environment() { return environment_; }
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  // Node creation helpers
1151cb0ef41Sopenharmony_ci  Node* NewNode(const Operator* op, bool incomplete = false) {
1161cb0ef41Sopenharmony_ci    return MakeNode(op, 0, static_cast<Node**>(nullptr), incomplete);
1171cb0ef41Sopenharmony_ci  }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  template <class... Args>
1201cb0ef41Sopenharmony_ci  Node* NewNode(const Operator* op, Node* n0, Args... nodes) {
1211cb0ef41Sopenharmony_ci    Node* buffer[] = {n0, nodes...};
1221cb0ef41Sopenharmony_ci    return MakeNode(op, arraysize(buffer), buffer);
1231cb0ef41Sopenharmony_ci  }
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  // Helpers to create new control nodes.
1261cb0ef41Sopenharmony_ci  Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
1271cb0ef41Sopenharmony_ci  Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
1281cb0ef41Sopenharmony_ci  Node* NewIfValue(int32_t value) { return NewNode(common()->IfValue(value)); }
1291cb0ef41Sopenharmony_ci  Node* NewIfDefault() { return NewNode(common()->IfDefault()); }
1301cb0ef41Sopenharmony_ci  Node* NewMerge() { return NewNode(common()->Merge(1), true); }
1311cb0ef41Sopenharmony_ci  Node* NewLoop() { return NewNode(common()->Loop(1), true); }
1321cb0ef41Sopenharmony_ci  Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
1331cb0ef41Sopenharmony_ci    return NewNode(common()->Branch(hint), condition);
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci  Node* NewSwitch(Node* condition, int control_output_count) {
1361cb0ef41Sopenharmony_ci    return NewNode(common()->Switch(control_output_count), condition);
1371cb0ef41Sopenharmony_ci  }
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci  // Creates a new Phi node having {count} input values.
1401cb0ef41Sopenharmony_ci  Node* NewPhi(int count, Node* input, Node* control);
1411cb0ef41Sopenharmony_ci  Node* NewEffectPhi(int count, Node* input, Node* control);
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  // Helpers for merging control, effect or value dependencies.
1441cb0ef41Sopenharmony_ci  Node* MergeControl(Node* control, Node* other);
1451cb0ef41Sopenharmony_ci  Node* MergeEffect(Node* effect, Node* other_effect, Node* control);
1461cb0ef41Sopenharmony_ci  Node* MergeValue(Node* value, Node* other_value, Node* control);
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  // The main node creation chokepoint. Adds context, frame state, effect,
1491cb0ef41Sopenharmony_ci  // and control dependencies depending on the operator.
1501cb0ef41Sopenharmony_ci  Node* MakeNode(const Operator* op, int value_input_count,
1511cb0ef41Sopenharmony_ci                 Node* const* value_inputs, bool incomplete = false);
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  Node** EnsureInputBufferSize(int size);
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci  Node* const* GetCallArgumentsFromRegisters(Node* callee, Node* receiver,
1561cb0ef41Sopenharmony_ci                                              interpreter::Register first_arg,
1571cb0ef41Sopenharmony_ci                                              int arg_count);
1581cb0ef41Sopenharmony_ci  Node* const* ProcessCallVarArgs(ConvertReceiverMode receiver_mode,
1591cb0ef41Sopenharmony_ci                                  Node* callee, interpreter::Register first_reg,
1601cb0ef41Sopenharmony_ci                                  int arg_count);
1611cb0ef41Sopenharmony_ci  Node* const* GetConstructArgumentsFromRegister(
1621cb0ef41Sopenharmony_ci      Node* target, Node* new_target, interpreter::Register first_arg,
1631cb0ef41Sopenharmony_ci      int arg_count);
1641cb0ef41Sopenharmony_ci  Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op,
1651cb0ef41Sopenharmony_ci                                    interpreter::Register receiver,
1661cb0ef41Sopenharmony_ci                                    size_t reg_count);
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  // Prepare information for eager deoptimization. This information is carried
1691cb0ef41Sopenharmony_ci  // by dedicated {Checkpoint} nodes that are wired into the effect chain.
1701cb0ef41Sopenharmony_ci  // Conceptually this frame state is "before" a given operation.
1711cb0ef41Sopenharmony_ci  void PrepareEagerCheckpoint();
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci  // Prepare information for lazy deoptimization. This information is attached
1741cb0ef41Sopenharmony_ci  // to the given node and the output value produced by the node is combined.
1751cb0ef41Sopenharmony_ci  //
1761cb0ef41Sopenharmony_ci  // The low-level chokepoint - use the variants below instead.
1771cb0ef41Sopenharmony_ci  void PrepareFrameState(Node* node, OutputFrameStateCombine combine,
1781cb0ef41Sopenharmony_ci                         BytecodeOffset bailout_id,
1791cb0ef41Sopenharmony_ci                         const BytecodeLivenessState* liveness);
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  // In the common case, frame states are conceptually "after" a given
1821cb0ef41Sopenharmony_ci  // operation and at the current bytecode offset.
1831cb0ef41Sopenharmony_ci  void PrepareFrameState(Node* node, OutputFrameStateCombine combine) {
1841cb0ef41Sopenharmony_ci    if (!OperatorProperties::HasFrameStateInput(node->op())) return;
1851cb0ef41Sopenharmony_ci    const int offset = bytecode_iterator().current_offset();
1861cb0ef41Sopenharmony_ci    return PrepareFrameState(node, combine, BytecodeOffset(offset),
1871cb0ef41Sopenharmony_ci                             bytecode_analysis().GetOutLivenessFor(offset));
1881cb0ef41Sopenharmony_ci  }
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  // For function-entry stack checks, they're conceptually "before" the first
1911cb0ef41Sopenharmony_ci  // bytecode and at a special marker bytecode offset.
1921cb0ef41Sopenharmony_ci  // In the case of FE stack checks, the current bytecode is also the first
1931cb0ef41Sopenharmony_ci  // bytecode, so we use a special marker bytecode offset to signify a virtual
1941cb0ef41Sopenharmony_ci  // bytecode before the first physical bytecode.
1951cb0ef41Sopenharmony_ci  void PrepareFrameStateForFunctionEntryStackCheck(Node* node) {
1961cb0ef41Sopenharmony_ci    DCHECK_EQ(bytecode_iterator().current_offset(), 0);
1971cb0ef41Sopenharmony_ci    DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
1981cb0ef41Sopenharmony_ci    DCHECK(node->opcode() == IrOpcode::kJSStackCheck);
1991cb0ef41Sopenharmony_ci    return PrepareFrameState(node, OutputFrameStateCombine::Ignore(),
2001cb0ef41Sopenharmony_ci                             BytecodeOffset(kFunctionEntryBytecodeOffset),
2011cb0ef41Sopenharmony_ci                             bytecode_analysis().GetInLivenessFor(0));
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci  // For OSR-entry stack checks, they're conceptually "before" the first
2051cb0ef41Sopenharmony_ci  // bytecode of the current loop. We implement this in a similar manner to
2061cb0ef41Sopenharmony_ci  // function-entry (FE) stack checks above, i.e. we deopt at the predecessor
2071cb0ef41Sopenharmony_ci  // of the current bytecode.
2081cb0ef41Sopenharmony_ci  // In the case of OSR-entry stack checks, a physical predecessor bytecode
2091cb0ef41Sopenharmony_ci  // exists: the JumpLoop bytecode. We attach to JumpLoop by using
2101cb0ef41Sopenharmony_ci  // `bytecode_analysis().osr_bailout_id()` instead of current_offset (the
2111cb0ef41Sopenharmony_ci  // former points at JumpLoop, the latter at the loop header, i.e. the target
2121cb0ef41Sopenharmony_ci  // of JumpLoop).
2131cb0ef41Sopenharmony_ci  void PrepareFrameStateForOSREntryStackCheck(Node* node) {
2141cb0ef41Sopenharmony_ci    DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
2151cb0ef41Sopenharmony_ci    DCHECK(node->opcode() == IrOpcode::kJSStackCheck);
2161cb0ef41Sopenharmony_ci    const int offset = bytecode_analysis().osr_bailout_id().ToInt();
2171cb0ef41Sopenharmony_ci    return PrepareFrameState(node, OutputFrameStateCombine::Ignore(),
2181cb0ef41Sopenharmony_ci                             BytecodeOffset(offset),
2191cb0ef41Sopenharmony_ci                             bytecode_analysis().GetOutLivenessFor(offset));
2201cb0ef41Sopenharmony_ci  }
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci  void BuildCreateArguments(CreateArgumentsType type);
2231cb0ef41Sopenharmony_ci  Node* BuildLoadGlobal(NameRef name, uint32_t feedback_slot_index,
2241cb0ef41Sopenharmony_ci                        TypeofMode typeof_mode);
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci  enum class NamedStoreMode {
2271cb0ef41Sopenharmony_ci    // Check the prototype chain before storing.
2281cb0ef41Sopenharmony_ci    kSet,
2291cb0ef41Sopenharmony_ci    // Define value to the receiver without checking the prototype chain.
2301cb0ef41Sopenharmony_ci    kDefineOwn,
2311cb0ef41Sopenharmony_ci  };
2321cb0ef41Sopenharmony_ci  void BuildNamedStore(NamedStoreMode store_mode);
2331cb0ef41Sopenharmony_ci  void BuildLdaLookupSlot(TypeofMode typeof_mode);
2341cb0ef41Sopenharmony_ci  void BuildLdaLookupContextSlot(TypeofMode typeof_mode);
2351cb0ef41Sopenharmony_ci  void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode);
2361cb0ef41Sopenharmony_ci  void BuildCallVarArgs(ConvertReceiverMode receiver_mode);
2371cb0ef41Sopenharmony_ci  void BuildCall(ConvertReceiverMode receiver_mode, Node* const* args,
2381cb0ef41Sopenharmony_ci                 size_t arg_count, int slot_id);
2391cb0ef41Sopenharmony_ci  void BuildCall(ConvertReceiverMode receiver_mode,
2401cb0ef41Sopenharmony_ci                 std::initializer_list<Node*> args, int slot_id) {
2411cb0ef41Sopenharmony_ci    BuildCall(receiver_mode, args.begin(), args.size(), slot_id);
2421cb0ef41Sopenharmony_ci  }
2431cb0ef41Sopenharmony_ci  void BuildUnaryOp(const Operator* op);
2441cb0ef41Sopenharmony_ci  void BuildBinaryOp(const Operator* op);
2451cb0ef41Sopenharmony_ci  void BuildBinaryOpWithImmediate(const Operator* op);
2461cb0ef41Sopenharmony_ci  void BuildCompareOp(const Operator* op);
2471cb0ef41Sopenharmony_ci  void BuildDelete(LanguageMode language_mode);
2481cb0ef41Sopenharmony_ci  void BuildCastOperator(const Operator* op);
2491cb0ef41Sopenharmony_ci  void BuildHoleCheckAndThrow(Node* condition, Runtime::FunctionId runtime_id,
2501cb0ef41Sopenharmony_ci                              Node* name = nullptr);
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  // Optional early lowering to the simplified operator level.  Note that
2531cb0ef41Sopenharmony_ci  // the result has already been wired into the environment just like
2541cb0ef41Sopenharmony_ci  // any other invocation of {NewNode} would do.
2551cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedUnaryOp(
2561cb0ef41Sopenharmony_ci      const Operator* op, Node* operand, FeedbackSlot slot);
2571cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedBinaryOp(
2581cb0ef41Sopenharmony_ci      const Operator* op, Node* left, Node* right, FeedbackSlot slot);
2591cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedForInNext(
2601cb0ef41Sopenharmony_ci      Node* receiver, Node* cache_array, Node* cache_type, Node* index,
2611cb0ef41Sopenharmony_ci      FeedbackSlot slot);
2621cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedForInPrepare(
2631cb0ef41Sopenharmony_ci      Node* receiver, FeedbackSlot slot);
2641cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedToNumber(
2651cb0ef41Sopenharmony_ci      Node* input, FeedbackSlot slot);
2661cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedCall(const Operator* op,
2671cb0ef41Sopenharmony_ci                                                            Node* const* args,
2681cb0ef41Sopenharmony_ci                                                            int arg_count,
2691cb0ef41Sopenharmony_ci                                                            FeedbackSlot slot);
2701cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedConstruct(
2711cb0ef41Sopenharmony_ci      const Operator* op, Node* const* args, int arg_count, FeedbackSlot slot);
2721cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedGetIterator(
2731cb0ef41Sopenharmony_ci      const Operator* op, Node* receiver, FeedbackSlot load_slot,
2741cb0ef41Sopenharmony_ci      FeedbackSlot call_slot);
2751cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedLoadNamed(
2761cb0ef41Sopenharmony_ci      const Operator* op, FeedbackSlot slot);
2771cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedLoadKeyed(
2781cb0ef41Sopenharmony_ci      const Operator* op, Node* receiver, Node* key, FeedbackSlot slot);
2791cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedStoreNamed(
2801cb0ef41Sopenharmony_ci      const Operator* op, Node* receiver, Node* value, FeedbackSlot slot);
2811cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult TryBuildSimplifiedStoreKeyed(
2821cb0ef41Sopenharmony_ci      const Operator* op, Node* receiver, Node* key, Node* value,
2831cb0ef41Sopenharmony_ci      FeedbackSlot slot);
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci  // Applies the given early reduction onto the current environment.
2861cb0ef41Sopenharmony_ci  void ApplyEarlyReduction(JSTypeHintLowering::LoweringResult reduction);
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_ci  // Check the context chain for extensions, for lookup fast paths.
2891cb0ef41Sopenharmony_ci  Environment* CheckContextExtensions(uint32_t depth);
2901cb0ef41Sopenharmony_ci  // Slow path taken when we cannot figure out the current scope info.
2911cb0ef41Sopenharmony_ci  Environment* CheckContextExtensionsSlowPath(uint32_t depth);
2921cb0ef41Sopenharmony_ci  // Helper function that tries to get the current scope info.
2931cb0ef41Sopenharmony_ci  base::Optional<ScopeInfoRef> TryGetScopeInfo();
2941cb0ef41Sopenharmony_ci  // Helper function to create a context extension check.
2951cb0ef41Sopenharmony_ci  Environment* CheckContextExtensionAtDepth(Environment* slow_environment,
2961cb0ef41Sopenharmony_ci                                            uint32_t depth);
2971cb0ef41Sopenharmony_ci
2981cb0ef41Sopenharmony_ci  // Helper function to create for-in mode from the recorded type feedback.
2991cb0ef41Sopenharmony_ci  ForInMode GetForInMode(FeedbackSlot slot);
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci  // Helper function to compute call frequency from the recorded type
3021cb0ef41Sopenharmony_ci  // feedback. Returns unknown if invocation count is unknown. Returns 0 if
3031cb0ef41Sopenharmony_ci  // feedback is insufficient.
3041cb0ef41Sopenharmony_ci  CallFrequency ComputeCallFrequency(int slot_id) const;
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci  // Helper function to extract the speculation mode from the recorded type
3071cb0ef41Sopenharmony_ci  // feedback. Returns kDisallowSpeculation if feedback is insufficient.
3081cb0ef41Sopenharmony_ci  SpeculationMode GetSpeculationMode(int slot_id) const;
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  // Helper function to determine the call feedback relation from the recorded
3111cb0ef41Sopenharmony_ci  // type feedback. Returns kUnrelated if feedback is insufficient.
3121cb0ef41Sopenharmony_ci  CallFeedbackRelation ComputeCallFeedbackRelation(int slot_id) const;
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci  // Helpers for building the implicit FunctionEntry and IterationBody
3151cb0ef41Sopenharmony_ci  // StackChecks.
3161cb0ef41Sopenharmony_ci  void BuildFunctionEntryStackCheck();
3171cb0ef41Sopenharmony_ci  void BuildIterationBodyStackCheck();
3181cb0ef41Sopenharmony_ci  void BuildOSREntryStackCheck();
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci  // Control flow plumbing.
3211cb0ef41Sopenharmony_ci  void BuildJump();
3221cb0ef41Sopenharmony_ci  void BuildJumpIf(Node* condition);
3231cb0ef41Sopenharmony_ci  void BuildJumpIfNot(Node* condition);
3241cb0ef41Sopenharmony_ci  void BuildJumpIfEqual(Node* comperand);
3251cb0ef41Sopenharmony_ci  void BuildJumpIfNotEqual(Node* comperand);
3261cb0ef41Sopenharmony_ci  void BuildJumpIfTrue();
3271cb0ef41Sopenharmony_ci  void BuildJumpIfFalse();
3281cb0ef41Sopenharmony_ci  void BuildJumpIfToBooleanTrue();
3291cb0ef41Sopenharmony_ci  void BuildJumpIfToBooleanFalse();
3301cb0ef41Sopenharmony_ci  void BuildJumpIfNotHole();
3311cb0ef41Sopenharmony_ci  void BuildJumpIfJSReceiver();
3321cb0ef41Sopenharmony_ci
3331cb0ef41Sopenharmony_ci  void BuildSwitchOnSmi(Node* condition);
3341cb0ef41Sopenharmony_ci  void BuildSwitchOnGeneratorState(
3351cb0ef41Sopenharmony_ci      const ZoneVector<ResumeJumpTarget>& resume_jump_targets,
3361cb0ef41Sopenharmony_ci      bool allow_fallthrough_on_executing);
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci  // Simulates control flow by forward-propagating environments.
3391cb0ef41Sopenharmony_ci  void MergeIntoSuccessorEnvironment(int target_offset);
3401cb0ef41Sopenharmony_ci  void BuildLoopHeaderEnvironment(int current_offset);
3411cb0ef41Sopenharmony_ci  void SwitchToMergeEnvironment(int current_offset);
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  // Simulates control flow that exits the function body.
3441cb0ef41Sopenharmony_ci  void MergeControlToLeaveFunction(Node* exit);
3451cb0ef41Sopenharmony_ci
3461cb0ef41Sopenharmony_ci  // Builds loop exit nodes for every exited loop between the current bytecode
3471cb0ef41Sopenharmony_ci  // offset and {target_offset}.
3481cb0ef41Sopenharmony_ci  void BuildLoopExitsForBranch(int target_offset);
3491cb0ef41Sopenharmony_ci  void BuildLoopExitsForFunctionExit(const BytecodeLivenessState* liveness);
3501cb0ef41Sopenharmony_ci  void BuildLoopExitsUntilLoop(int loop_offset,
3511cb0ef41Sopenharmony_ci                               const BytecodeLivenessState* liveness);
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci  // Helper for building a return (from an actual return or a suspend).
3541cb0ef41Sopenharmony_ci  void BuildReturn(const BytecodeLivenessState* liveness);
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ci  // Simulates entry and exit of exception handlers.
3571cb0ef41Sopenharmony_ci  void ExitThenEnterExceptionHandlers(int current_offset);
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_ci  // Update the current position of the {SourcePositionTable} to that of the
3601cb0ef41Sopenharmony_ci  // bytecode at {offset}, if any.
3611cb0ef41Sopenharmony_ci  void UpdateSourcePosition(int offset);
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci  // Growth increment for the temporary buffer used to construct input lists to
3641cb0ef41Sopenharmony_ci  // new nodes.
3651cb0ef41Sopenharmony_ci  static const int kInputBufferSizeIncrement = 64;
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci  // An abstract representation for an exception handler that is being
3681cb0ef41Sopenharmony_ci  // entered and exited while the graph builder is iterating over the
3691cb0ef41Sopenharmony_ci  // underlying bytecode. The exception handlers within the bytecode are
3701cb0ef41Sopenharmony_ci  // well scoped, hence will form a stack during iteration.
3711cb0ef41Sopenharmony_ci  struct ExceptionHandler {
3721cb0ef41Sopenharmony_ci    int start_offset_;      // Start offset of the handled area in the bytecode.
3731cb0ef41Sopenharmony_ci    int end_offset_;        // End offset of the handled area in the bytecode.
3741cb0ef41Sopenharmony_ci    int handler_offset_;    // Handler entry offset within the bytecode.
3751cb0ef41Sopenharmony_ci    int context_register_;  // Index of register holding handler context.
3761cb0ef41Sopenharmony_ci  };
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci  template <class T = Object>
3791cb0ef41Sopenharmony_ci  typename ref_traits<T>::ref_type MakeRefForConstantForIndexOperand(
3801cb0ef41Sopenharmony_ci      int operand_index) {
3811cb0ef41Sopenharmony_ci    // The BytecodeArray itself was fetched by using a barrier so all reads
3821cb0ef41Sopenharmony_ci    // from the constant pool are safe.
3831cb0ef41Sopenharmony_ci    return MakeRefAssumeMemoryFence(
3841cb0ef41Sopenharmony_ci        broker(), broker()->CanonicalPersistentHandle(Handle<T>::cast(
3851cb0ef41Sopenharmony_ci                      bytecode_iterator().GetConstantForIndexOperand(
3861cb0ef41Sopenharmony_ci                          operand_index, local_isolate_))));
3871cb0ef41Sopenharmony_ci  }
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_ci  Graph* graph() const { return jsgraph_->graph(); }
3901cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
3911cb0ef41Sopenharmony_ci  Zone* graph_zone() const { return graph()->zone(); }
3921cb0ef41Sopenharmony_ci  JSGraph* jsgraph() const { return jsgraph_; }
3931cb0ef41Sopenharmony_ci  Isolate* isolate() const { return jsgraph_->isolate(); }
3941cb0ef41Sopenharmony_ci  JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); }
3951cb0ef41Sopenharmony_ci  SimplifiedOperatorBuilder* simplified() const {
3961cb0ef41Sopenharmony_ci    return jsgraph_->simplified();
3971cb0ef41Sopenharmony_ci  }
3981cb0ef41Sopenharmony_ci  Zone* local_zone() const { return local_zone_; }
3991cb0ef41Sopenharmony_ci  BytecodeArrayRef bytecode_array() const { return bytecode_array_; }
4001cb0ef41Sopenharmony_ci  FeedbackVectorRef const& feedback_vector() const { return feedback_vector_; }
4011cb0ef41Sopenharmony_ci  const JSTypeHintLowering& type_hint_lowering() const {
4021cb0ef41Sopenharmony_ci    return type_hint_lowering_;
4031cb0ef41Sopenharmony_ci  }
4041cb0ef41Sopenharmony_ci  const FrameStateFunctionInfo* frame_state_function_info() const {
4051cb0ef41Sopenharmony_ci    return frame_state_function_info_;
4061cb0ef41Sopenharmony_ci  }
4071cb0ef41Sopenharmony_ci  SourcePositionTableIterator& source_position_iterator() {
4081cb0ef41Sopenharmony_ci    return *source_position_iterator_.get();
4091cb0ef41Sopenharmony_ci  }
4101cb0ef41Sopenharmony_ci  interpreter::BytecodeArrayIterator const& bytecode_iterator() const {
4111cb0ef41Sopenharmony_ci    return bytecode_iterator_;
4121cb0ef41Sopenharmony_ci  }
4131cb0ef41Sopenharmony_ci  interpreter::BytecodeArrayIterator& bytecode_iterator() {
4141cb0ef41Sopenharmony_ci    return bytecode_iterator_;
4151cb0ef41Sopenharmony_ci  }
4161cb0ef41Sopenharmony_ci  BytecodeAnalysis const& bytecode_analysis() const {
4171cb0ef41Sopenharmony_ci    return bytecode_analysis_;
4181cb0ef41Sopenharmony_ci  }
4191cb0ef41Sopenharmony_ci  int currently_peeled_loop_offset() const {
4201cb0ef41Sopenharmony_ci    return currently_peeled_loop_offset_;
4211cb0ef41Sopenharmony_ci  }
4221cb0ef41Sopenharmony_ci  void set_currently_peeled_loop_offset(int offset) {
4231cb0ef41Sopenharmony_ci    currently_peeled_loop_offset_ = offset;
4241cb0ef41Sopenharmony_ci  }
4251cb0ef41Sopenharmony_ci  bool skip_first_stack_check() const {
4261cb0ef41Sopenharmony_ci    return skip_first_stack_and_tierup_check_;
4271cb0ef41Sopenharmony_ci  }
4281cb0ef41Sopenharmony_ci  bool skip_tierup_check() const {
4291cb0ef41Sopenharmony_ci    return skip_first_stack_and_tierup_check_ || osr_;
4301cb0ef41Sopenharmony_ci  }
4311cb0ef41Sopenharmony_ci  int current_exception_handler() const { return current_exception_handler_; }
4321cb0ef41Sopenharmony_ci  void set_current_exception_handler(int index) {
4331cb0ef41Sopenharmony_ci    current_exception_handler_ = index;
4341cb0ef41Sopenharmony_ci  }
4351cb0ef41Sopenharmony_ci  bool needs_eager_checkpoint() const { return needs_eager_checkpoint_; }
4361cb0ef41Sopenharmony_ci  void mark_as_needing_eager_checkpoint(bool value) {
4371cb0ef41Sopenharmony_ci    needs_eager_checkpoint_ = value;
4381cb0ef41Sopenharmony_ci  }
4391cb0ef41Sopenharmony_ci  JSHeapBroker* broker() const { return broker_; }
4401cb0ef41Sopenharmony_ci  NativeContextRef native_context() const { return native_context_; }
4411cb0ef41Sopenharmony_ci  SharedFunctionInfoRef shared_info() const { return shared_info_; }
4421cb0ef41Sopenharmony_ci
4431cb0ef41Sopenharmony_ci#define DECLARE_VISIT_BYTECODE(name, ...) void Visit##name();
4441cb0ef41Sopenharmony_ci  BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
4451cb0ef41Sopenharmony_ci#undef DECLARE_VISIT_BYTECODE
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_ci  JSHeapBroker* const broker_;
4481cb0ef41Sopenharmony_ci  LocalIsolate* const local_isolate_;
4491cb0ef41Sopenharmony_ci  Zone* const local_zone_;
4501cb0ef41Sopenharmony_ci  JSGraph* const jsgraph_;
4511cb0ef41Sopenharmony_ci  // The native context for which we optimize.
4521cb0ef41Sopenharmony_ci  NativeContextRef const native_context_;
4531cb0ef41Sopenharmony_ci  SharedFunctionInfoRef const shared_info_;
4541cb0ef41Sopenharmony_ci  BytecodeArrayRef const bytecode_array_;
4551cb0ef41Sopenharmony_ci  FeedbackCellRef const feedback_cell_;
4561cb0ef41Sopenharmony_ci  FeedbackVectorRef const feedback_vector_;
4571cb0ef41Sopenharmony_ci  CallFrequency const invocation_frequency_;
4581cb0ef41Sopenharmony_ci  JSTypeHintLowering const type_hint_lowering_;
4591cb0ef41Sopenharmony_ci  const FrameStateFunctionInfo* const frame_state_function_info_;
4601cb0ef41Sopenharmony_ci  std::unique_ptr<SourcePositionTableIterator> source_position_iterator_;
4611cb0ef41Sopenharmony_ci  interpreter::BytecodeArrayIterator bytecode_iterator_;
4621cb0ef41Sopenharmony_ci  BytecodeAnalysis const bytecode_analysis_;
4631cb0ef41Sopenharmony_ci  Environment* environment_;
4641cb0ef41Sopenharmony_ci  bool const osr_;
4651cb0ef41Sopenharmony_ci  int currently_peeled_loop_offset_;
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_ci  const bool skip_first_stack_and_tierup_check_;
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci  // Merge environments are snapshots of the environment at points where the
4701cb0ef41Sopenharmony_ci  // control flow merges. This models a forward data flow propagation of all
4711cb0ef41Sopenharmony_ci  // values from all predecessors of the merge in question. They are indexed by
4721cb0ef41Sopenharmony_ci  // the bytecode offset
4731cb0ef41Sopenharmony_ci  ZoneMap<int, Environment*> merge_environments_;
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci  // Generator merge environments are snapshots of the current resume
4761cb0ef41Sopenharmony_ci  // environment, tracing back through loop headers to the resume switch of a
4771cb0ef41Sopenharmony_ci  // generator. They allow us to model a single resume jump as several switch
4781cb0ef41Sopenharmony_ci  // statements across loop headers, keeping those loop headers reducible,
4791cb0ef41Sopenharmony_ci  // without having to merge the "executing" environments of the generator into
4801cb0ef41Sopenharmony_ci  // the "resuming" ones. They are indexed by the suspend id of the resume.
4811cb0ef41Sopenharmony_ci  ZoneMap<int, Environment*> generator_merge_environments_;
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci  ZoneVector<Node*> cached_parameters_;
4841cb0ef41Sopenharmony_ci
4851cb0ef41Sopenharmony_ci  // Exception handlers currently entered by the iteration.
4861cb0ef41Sopenharmony_ci  ZoneStack<ExceptionHandler> exception_handlers_;
4871cb0ef41Sopenharmony_ci  int current_exception_handler_;
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  // Temporary storage for building node input lists.
4901cb0ef41Sopenharmony_ci  int input_buffer_size_;
4911cb0ef41Sopenharmony_ci  Node** input_buffer_;
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci  const CodeKind code_kind_;
4941cb0ef41Sopenharmony_ci  Node* feedback_vector_node_;
4951cb0ef41Sopenharmony_ci  Node* native_context_node_;
4961cb0ef41Sopenharmony_ci
4971cb0ef41Sopenharmony_ci  // Optimization to only create checkpoints when the current position in the
4981cb0ef41Sopenharmony_ci  // control-flow is not effect-dominated by another checkpoint already. All
4991cb0ef41Sopenharmony_ci  // operations that do not have observable side-effects can be re-evaluated.
5001cb0ef41Sopenharmony_ci  bool needs_eager_checkpoint_;
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ci  // Nodes representing values in the activation record.
5031cb0ef41Sopenharmony_ci  SetOncePointer<Node> function_closure_;
5041cb0ef41Sopenharmony_ci
5051cb0ef41Sopenharmony_ci  // Control nodes that exit the function body.
5061cb0ef41Sopenharmony_ci  ZoneVector<Node*> exit_controls_;
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ci  StateValuesCache state_values_cache_;
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ci  // The source position table, to be populated.
5111cb0ef41Sopenharmony_ci  SourcePositionTable* const source_positions_;
5121cb0ef41Sopenharmony_ci
5131cb0ef41Sopenharmony_ci  SourcePosition const start_position_;
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci  TickCounter* const tick_counter_;
5161cb0ef41Sopenharmony_ci
5171cb0ef41Sopenharmony_ci  ObserveNodeInfo const observe_node_info_;
5181cb0ef41Sopenharmony_ci
5191cb0ef41Sopenharmony_ci  static constexpr int kBinaryOperationHintIndex = 1;
5201cb0ef41Sopenharmony_ci  static constexpr int kBinaryOperationSmiHintIndex = 1;
5211cb0ef41Sopenharmony_ci  static constexpr int kCompareOperationHintIndex = 1;
5221cb0ef41Sopenharmony_ci  static constexpr int kCountOperationHintIndex = 0;
5231cb0ef41Sopenharmony_ci  static constexpr int kUnaryOperationHintIndex = 0;
5241cb0ef41Sopenharmony_ci};
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ci// The abstract execution environment simulates the content of the interpreter
5271cb0ef41Sopenharmony_ci// register file. The environment performs SSA-renaming of all tracked nodes at
5281cb0ef41Sopenharmony_ci// split and merge points in the control flow.
5291cb0ef41Sopenharmony_ciclass BytecodeGraphBuilder::Environment : public ZoneObject {
5301cb0ef41Sopenharmony_ci public:
5311cb0ef41Sopenharmony_ci  Environment(BytecodeGraphBuilder* builder, int register_count,
5321cb0ef41Sopenharmony_ci              int parameter_count,
5331cb0ef41Sopenharmony_ci              interpreter::Register incoming_new_target_or_generator,
5341cb0ef41Sopenharmony_ci              Node* control_dependency);
5351cb0ef41Sopenharmony_ci
5361cb0ef41Sopenharmony_ci  // Specifies whether environment binding methods should attach frame state
5371cb0ef41Sopenharmony_ci  // inputs to nodes representing the value being bound. This is done because
5381cb0ef41Sopenharmony_ci  // the {OutputFrameStateCombine} is closely related to the binding method.
5391cb0ef41Sopenharmony_ci  enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci  int parameter_count() const { return parameter_count_; }
5421cb0ef41Sopenharmony_ci  int register_count() const { return register_count_; }
5431cb0ef41Sopenharmony_ci
5441cb0ef41Sopenharmony_ci  Node* LookupAccumulator() const;
5451cb0ef41Sopenharmony_ci  Node* LookupRegister(interpreter::Register the_register) const;
5461cb0ef41Sopenharmony_ci  Node* LookupGeneratorState() const;
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_ci  void BindAccumulator(Node* node,
5491cb0ef41Sopenharmony_ci                       FrameStateAttachmentMode mode = kDontAttachFrameState);
5501cb0ef41Sopenharmony_ci  void BindRegister(interpreter::Register the_register, Node* node,
5511cb0ef41Sopenharmony_ci                    FrameStateAttachmentMode mode = kDontAttachFrameState);
5521cb0ef41Sopenharmony_ci  void BindRegistersToProjections(
5531cb0ef41Sopenharmony_ci      interpreter::Register first_reg, Node* node,
5541cb0ef41Sopenharmony_ci      FrameStateAttachmentMode mode = kDontAttachFrameState);
5551cb0ef41Sopenharmony_ci  void BindGeneratorState(Node* node);
5561cb0ef41Sopenharmony_ci  void RecordAfterState(Node* node,
5571cb0ef41Sopenharmony_ci                        FrameStateAttachmentMode mode = kDontAttachFrameState);
5581cb0ef41Sopenharmony_ci
5591cb0ef41Sopenharmony_ci  // Effect dependency tracked by this environment.
5601cb0ef41Sopenharmony_ci  Node* GetEffectDependency() { return effect_dependency_; }
5611cb0ef41Sopenharmony_ci  void UpdateEffectDependency(Node* dependency) {
5621cb0ef41Sopenharmony_ci    effect_dependency_ = dependency;
5631cb0ef41Sopenharmony_ci  }
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ci  // Preserve a checkpoint of the environment for the IR graph. Any
5661cb0ef41Sopenharmony_ci  // further mutation of the environment will not affect checkpoints.
5671cb0ef41Sopenharmony_ci  Node* Checkpoint(BytecodeOffset bytecode_offset,
5681cb0ef41Sopenharmony_ci                   OutputFrameStateCombine combine,
5691cb0ef41Sopenharmony_ci                   const BytecodeLivenessState* liveness);
5701cb0ef41Sopenharmony_ci
5711cb0ef41Sopenharmony_ci  // Control dependency tracked by this environment.
5721cb0ef41Sopenharmony_ci  Node* GetControlDependency() const { return control_dependency_; }
5731cb0ef41Sopenharmony_ci  void UpdateControlDependency(Node* dependency) {
5741cb0ef41Sopenharmony_ci    control_dependency_ = dependency;
5751cb0ef41Sopenharmony_ci  }
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci  Node* Context() const { return context_; }
5781cb0ef41Sopenharmony_ci  void SetContext(Node* new_context) { context_ = new_context; }
5791cb0ef41Sopenharmony_ci
5801cb0ef41Sopenharmony_ci  Environment* Copy();
5811cb0ef41Sopenharmony_ci  void Merge(Environment* other, const BytecodeLivenessState* liveness);
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci  void FillWithOsrValues();
5841cb0ef41Sopenharmony_ci  void PrepareForLoop(const BytecodeLoopAssignments& assignments,
5851cb0ef41Sopenharmony_ci                      const BytecodeLivenessState* liveness);
5861cb0ef41Sopenharmony_ci  void PrepareForLoopExit(Node* loop,
5871cb0ef41Sopenharmony_ci                          const BytecodeLoopAssignments& assignments,
5881cb0ef41Sopenharmony_ci                          const BytecodeLivenessState* liveness);
5891cb0ef41Sopenharmony_ci
5901cb0ef41Sopenharmony_ci private:
5911cb0ef41Sopenharmony_ci  friend Zone;
5921cb0ef41Sopenharmony_ci
5931cb0ef41Sopenharmony_ci  explicit Environment(const Environment* copy);
5941cb0ef41Sopenharmony_ci
5951cb0ef41Sopenharmony_ci  bool StateValuesRequireUpdate(Node** state_values, Node** values, int count);
5961cb0ef41Sopenharmony_ci  void UpdateStateValues(Node** state_values, Node** values, int count);
5971cb0ef41Sopenharmony_ci  Node* GetStateValuesFromCache(Node** values, int count,
5981cb0ef41Sopenharmony_ci                                const BytecodeLivenessState* liveness);
5991cb0ef41Sopenharmony_ci
6001cb0ef41Sopenharmony_ci  int RegisterToValuesIndex(interpreter::Register the_register) const;
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ci  Zone* zone() const { return builder_->local_zone(); }
6031cb0ef41Sopenharmony_ci  Graph* graph() const { return builder_->graph(); }
6041cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common() const { return builder_->common(); }
6051cb0ef41Sopenharmony_ci  BytecodeGraphBuilder* builder() const { return builder_; }
6061cb0ef41Sopenharmony_ci  const NodeVector* values() const { return &values_; }
6071cb0ef41Sopenharmony_ci  NodeVector* values() { return &values_; }
6081cb0ef41Sopenharmony_ci  int register_base() const { return register_base_; }
6091cb0ef41Sopenharmony_ci  int accumulator_base() const { return accumulator_base_; }
6101cb0ef41Sopenharmony_ci
6111cb0ef41Sopenharmony_ci  BytecodeGraphBuilder* builder_;
6121cb0ef41Sopenharmony_ci  int register_count_;
6131cb0ef41Sopenharmony_ci  int parameter_count_;
6141cb0ef41Sopenharmony_ci  Node* context_;
6151cb0ef41Sopenharmony_ci  Node* control_dependency_;
6161cb0ef41Sopenharmony_ci  Node* effect_dependency_;
6171cb0ef41Sopenharmony_ci  NodeVector values_;
6181cb0ef41Sopenharmony_ci  Node* parameters_state_values_;
6191cb0ef41Sopenharmony_ci  Node* generator_state_;
6201cb0ef41Sopenharmony_ci  int register_base_;
6211cb0ef41Sopenharmony_ci  int accumulator_base_;
6221cb0ef41Sopenharmony_ci};
6231cb0ef41Sopenharmony_ci
6241cb0ef41Sopenharmony_ci// A helper for creating a temporary sub-environment for simple branches.
6251cb0ef41Sopenharmony_cistruct BytecodeGraphBuilder::SubEnvironment final {
6261cb0ef41Sopenharmony_ci public:
6271cb0ef41Sopenharmony_ci  explicit SubEnvironment(BytecodeGraphBuilder* builder)
6281cb0ef41Sopenharmony_ci      : builder_(builder), parent_(builder->environment()->Copy()) {}
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci  ~SubEnvironment() { builder_->set_environment(parent_); }
6311cb0ef41Sopenharmony_ci
6321cb0ef41Sopenharmony_ci private:
6331cb0ef41Sopenharmony_ci  BytecodeGraphBuilder* builder_;
6341cb0ef41Sopenharmony_ci  BytecodeGraphBuilder::Environment* parent_;
6351cb0ef41Sopenharmony_ci};
6361cb0ef41Sopenharmony_ci
6371cb0ef41Sopenharmony_ci// Issues:
6381cb0ef41Sopenharmony_ci// - Scopes - intimately tied to AST. Need to eval what is needed.
6391cb0ef41Sopenharmony_ci// - Need to resolve closure parameter treatment.
6401cb0ef41Sopenharmony_ciBytecodeGraphBuilder::Environment::Environment(
6411cb0ef41Sopenharmony_ci    BytecodeGraphBuilder* builder, int register_count, int parameter_count,
6421cb0ef41Sopenharmony_ci    interpreter::Register incoming_new_target_or_generator,
6431cb0ef41Sopenharmony_ci    Node* control_dependency)
6441cb0ef41Sopenharmony_ci    : builder_(builder),
6451cb0ef41Sopenharmony_ci      register_count_(register_count),
6461cb0ef41Sopenharmony_ci      parameter_count_(parameter_count),
6471cb0ef41Sopenharmony_ci      control_dependency_(control_dependency),
6481cb0ef41Sopenharmony_ci      effect_dependency_(control_dependency),
6491cb0ef41Sopenharmony_ci      values_(builder->local_zone()),
6501cb0ef41Sopenharmony_ci      parameters_state_values_(nullptr),
6511cb0ef41Sopenharmony_ci      generator_state_(nullptr) {
6521cb0ef41Sopenharmony_ci  // The layout of values_ is:
6531cb0ef41Sopenharmony_ci  //
6541cb0ef41Sopenharmony_ci  // [receiver] [parameters] [registers] [accumulator]
6551cb0ef41Sopenharmony_ci  //
6561cb0ef41Sopenharmony_ci  // parameter[0] is the receiver (this), parameters 1..N are the
6571cb0ef41Sopenharmony_ci  // parameters supplied to the method (arg0..argN-1). The accumulator
6581cb0ef41Sopenharmony_ci  // is stored separately.
6591cb0ef41Sopenharmony_ci
6601cb0ef41Sopenharmony_ci  // Parameters including the receiver
6611cb0ef41Sopenharmony_ci  for (int i = 0; i < parameter_count; i++) {
6621cb0ef41Sopenharmony_ci    const char* debug_name = (i == 0) ? "%this" : nullptr;
6631cb0ef41Sopenharmony_ci    Node* parameter = builder->GetParameter(i, debug_name);
6641cb0ef41Sopenharmony_ci    values()->push_back(parameter);
6651cb0ef41Sopenharmony_ci  }
6661cb0ef41Sopenharmony_ci
6671cb0ef41Sopenharmony_ci  // Registers
6681cb0ef41Sopenharmony_ci  register_base_ = static_cast<int>(values()->size());
6691cb0ef41Sopenharmony_ci  Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
6701cb0ef41Sopenharmony_ci  values()->insert(values()->end(), register_count, undefined_constant);
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci  // Accumulator
6731cb0ef41Sopenharmony_ci  accumulator_base_ = static_cast<int>(values()->size());
6741cb0ef41Sopenharmony_ci  values()->push_back(undefined_constant);
6751cb0ef41Sopenharmony_ci
6761cb0ef41Sopenharmony_ci  // Context
6771cb0ef41Sopenharmony_ci  int context_index = Linkage::GetJSCallContextParamIndex(parameter_count);
6781cb0ef41Sopenharmony_ci  context_ = builder->GetParameter(context_index, "%context");
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_ci  // Incoming new.target or generator register
6811cb0ef41Sopenharmony_ci  if (incoming_new_target_or_generator.is_valid()) {
6821cb0ef41Sopenharmony_ci    int new_target_index =
6831cb0ef41Sopenharmony_ci        Linkage::GetJSCallNewTargetParamIndex(parameter_count);
6841cb0ef41Sopenharmony_ci    Node* new_target_node =
6851cb0ef41Sopenharmony_ci        builder->GetParameter(new_target_index, "%new.target");
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci    int values_index = RegisterToValuesIndex(incoming_new_target_or_generator);
6881cb0ef41Sopenharmony_ci    values()->at(values_index) = new_target_node;
6891cb0ef41Sopenharmony_ci  }
6901cb0ef41Sopenharmony_ci}
6911cb0ef41Sopenharmony_ci
6921cb0ef41Sopenharmony_ciBytecodeGraphBuilder::Environment::Environment(
6931cb0ef41Sopenharmony_ci    const BytecodeGraphBuilder::Environment* other)
6941cb0ef41Sopenharmony_ci    : builder_(other->builder_),
6951cb0ef41Sopenharmony_ci      register_count_(other->register_count_),
6961cb0ef41Sopenharmony_ci      parameter_count_(other->parameter_count_),
6971cb0ef41Sopenharmony_ci      context_(other->context_),
6981cb0ef41Sopenharmony_ci      control_dependency_(other->control_dependency_),
6991cb0ef41Sopenharmony_ci      effect_dependency_(other->effect_dependency_),
7001cb0ef41Sopenharmony_ci      values_(other->zone()),
7011cb0ef41Sopenharmony_ci      parameters_state_values_(other->parameters_state_values_),
7021cb0ef41Sopenharmony_ci      generator_state_(other->generator_state_),
7031cb0ef41Sopenharmony_ci      register_base_(other->register_base_),
7041cb0ef41Sopenharmony_ci      accumulator_base_(other->accumulator_base_) {
7051cb0ef41Sopenharmony_ci  values_ = other->values_;
7061cb0ef41Sopenharmony_ci}
7071cb0ef41Sopenharmony_ci
7081cb0ef41Sopenharmony_ci
7091cb0ef41Sopenharmony_ciint BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
7101cb0ef41Sopenharmony_ci    interpreter::Register the_register) const {
7111cb0ef41Sopenharmony_ci  if (the_register.is_parameter()) {
7121cb0ef41Sopenharmony_ci    return the_register.ToParameterIndex();
7131cb0ef41Sopenharmony_ci  } else {
7141cb0ef41Sopenharmony_ci    return the_register.index() + register_base();
7151cb0ef41Sopenharmony_ci  }
7161cb0ef41Sopenharmony_ci}
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
7191cb0ef41Sopenharmony_ci  return values()->at(accumulator_base_);
7201cb0ef41Sopenharmony_ci}
7211cb0ef41Sopenharmony_ci
7221cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::Environment::LookupGeneratorState() const {
7231cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(generator_state_);
7241cb0ef41Sopenharmony_ci  return generator_state_;
7251cb0ef41Sopenharmony_ci}
7261cb0ef41Sopenharmony_ci
7271cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::Environment::LookupRegister(
7281cb0ef41Sopenharmony_ci    interpreter::Register the_register) const {
7291cb0ef41Sopenharmony_ci  if (the_register.is_current_context()) {
7301cb0ef41Sopenharmony_ci    return Context();
7311cb0ef41Sopenharmony_ci  } else if (the_register.is_function_closure()) {
7321cb0ef41Sopenharmony_ci    return builder()->GetFunctionClosure();
7331cb0ef41Sopenharmony_ci  } else {
7341cb0ef41Sopenharmony_ci    int values_index = RegisterToValuesIndex(the_register);
7351cb0ef41Sopenharmony_ci    return values()->at(values_index);
7361cb0ef41Sopenharmony_ci  }
7371cb0ef41Sopenharmony_ci}
7381cb0ef41Sopenharmony_ci
7391cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::BindAccumulator(
7401cb0ef41Sopenharmony_ci    Node* node, FrameStateAttachmentMode mode) {
7411cb0ef41Sopenharmony_ci  if (mode == FrameStateAttachmentMode::kAttachFrameState) {
7421cb0ef41Sopenharmony_ci    builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
7431cb0ef41Sopenharmony_ci  }
7441cb0ef41Sopenharmony_ci  values()->at(accumulator_base_) = node;
7451cb0ef41Sopenharmony_ci}
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::BindGeneratorState(Node* node) {
7481cb0ef41Sopenharmony_ci  generator_state_ = node;
7491cb0ef41Sopenharmony_ci}
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::BindRegister(
7521cb0ef41Sopenharmony_ci    interpreter::Register the_register, Node* node,
7531cb0ef41Sopenharmony_ci    FrameStateAttachmentMode mode) {
7541cb0ef41Sopenharmony_ci  int values_index = RegisterToValuesIndex(the_register);
7551cb0ef41Sopenharmony_ci  if (mode == FrameStateAttachmentMode::kAttachFrameState) {
7561cb0ef41Sopenharmony_ci    builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
7571cb0ef41Sopenharmony_ci                                           accumulator_base_ - values_index));
7581cb0ef41Sopenharmony_ci  }
7591cb0ef41Sopenharmony_ci  values()->at(values_index) = node;
7601cb0ef41Sopenharmony_ci}
7611cb0ef41Sopenharmony_ci
7621cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::BindRegistersToProjections(
7631cb0ef41Sopenharmony_ci    interpreter::Register first_reg, Node* node,
7641cb0ef41Sopenharmony_ci    FrameStateAttachmentMode mode) {
7651cb0ef41Sopenharmony_ci  int values_index = RegisterToValuesIndex(first_reg);
7661cb0ef41Sopenharmony_ci  if (mode == FrameStateAttachmentMode::kAttachFrameState) {
7671cb0ef41Sopenharmony_ci    builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
7681cb0ef41Sopenharmony_ci                                           accumulator_base_ - values_index));
7691cb0ef41Sopenharmony_ci  }
7701cb0ef41Sopenharmony_ci  for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
7711cb0ef41Sopenharmony_ci    values()->at(values_index + i) =
7721cb0ef41Sopenharmony_ci        builder()->NewNode(common()->Projection(i), node);
7731cb0ef41Sopenharmony_ci  }
7741cb0ef41Sopenharmony_ci}
7751cb0ef41Sopenharmony_ci
7761cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::RecordAfterState(
7771cb0ef41Sopenharmony_ci    Node* node, FrameStateAttachmentMode mode) {
7781cb0ef41Sopenharmony_ci  if (mode == FrameStateAttachmentMode::kAttachFrameState) {
7791cb0ef41Sopenharmony_ci    builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
7801cb0ef41Sopenharmony_ci  }
7811cb0ef41Sopenharmony_ci}
7821cb0ef41Sopenharmony_ci
7831cb0ef41Sopenharmony_ciBytecodeGraphBuilder::Environment* BytecodeGraphBuilder::Environment::Copy() {
7841cb0ef41Sopenharmony_ci  return zone()->New<Environment>(this);
7851cb0ef41Sopenharmony_ci}
7861cb0ef41Sopenharmony_ci
7871cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::Merge(
7881cb0ef41Sopenharmony_ci    BytecodeGraphBuilder::Environment* other,
7891cb0ef41Sopenharmony_ci    const BytecodeLivenessState* liveness) {
7901cb0ef41Sopenharmony_ci  // Create a merge of the control dependencies of both environments and update
7911cb0ef41Sopenharmony_ci  // the current environment's control dependency accordingly.
7921cb0ef41Sopenharmony_ci  Node* control = builder()->MergeControl(GetControlDependency(),
7931cb0ef41Sopenharmony_ci                                          other->GetControlDependency());
7941cb0ef41Sopenharmony_ci  UpdateControlDependency(control);
7951cb0ef41Sopenharmony_ci
7961cb0ef41Sopenharmony_ci  // Create a merge of the effect dependencies of both environments and update
7971cb0ef41Sopenharmony_ci  // the current environment's effect dependency accordingly.
7981cb0ef41Sopenharmony_ci  Node* effect = builder()->MergeEffect(GetEffectDependency(),
7991cb0ef41Sopenharmony_ci                                        other->GetEffectDependency(), control);
8001cb0ef41Sopenharmony_ci  UpdateEffectDependency(effect);
8011cb0ef41Sopenharmony_ci
8021cb0ef41Sopenharmony_ci  // Introduce Phi nodes for values that are live and have differing inputs at
8031cb0ef41Sopenharmony_ci  // the merge point, potentially extending an existing Phi node if possible.
8041cb0ef41Sopenharmony_ci  context_ = builder()->MergeValue(context_, other->context_, control);
8051cb0ef41Sopenharmony_ci  for (int i = 0; i < parameter_count(); i++) {
8061cb0ef41Sopenharmony_ci    values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
8071cb0ef41Sopenharmony_ci  }
8081cb0ef41Sopenharmony_ci  for (int i = 0; i < register_count(); i++) {
8091cb0ef41Sopenharmony_ci    int index = register_base() + i;
8101cb0ef41Sopenharmony_ci    if (liveness == nullptr || liveness->RegisterIsLive(i)) {
8111cb0ef41Sopenharmony_ci#if DEBUG
8121cb0ef41Sopenharmony_ci      // We only do these DCHECKs when we are not in the resume path of a
8131cb0ef41Sopenharmony_ci      // generator -- this is, when either there is no generator state at all,
8141cb0ef41Sopenharmony_ci      // or the generator state is not the constant "executing" value.
8151cb0ef41Sopenharmony_ci      if (generator_state_ == nullptr ||
8161cb0ef41Sopenharmony_ci          NumberMatcher(generator_state_)
8171cb0ef41Sopenharmony_ci              .Is(JSGeneratorObject::kGeneratorExecuting)) {
8181cb0ef41Sopenharmony_ci        DCHECK_NE(values_[index], builder()->jsgraph()->OptimizedOutConstant());
8191cb0ef41Sopenharmony_ci        DCHECK_NE(other->values_[index],
8201cb0ef41Sopenharmony_ci                  builder()->jsgraph()->OptimizedOutConstant());
8211cb0ef41Sopenharmony_ci      }
8221cb0ef41Sopenharmony_ci#endif
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_ci      values_[index] =
8251cb0ef41Sopenharmony_ci          builder()->MergeValue(values_[index], other->values_[index], control);
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_ci    } else {
8281cb0ef41Sopenharmony_ci      values_[index] = builder()->jsgraph()->OptimizedOutConstant();
8291cb0ef41Sopenharmony_ci    }
8301cb0ef41Sopenharmony_ci  }
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_ci  if (liveness == nullptr || liveness->AccumulatorIsLive()) {
8331cb0ef41Sopenharmony_ci    DCHECK_NE(values_[accumulator_base()],
8341cb0ef41Sopenharmony_ci              builder()->jsgraph()->OptimizedOutConstant());
8351cb0ef41Sopenharmony_ci    DCHECK_NE(other->values_[accumulator_base()],
8361cb0ef41Sopenharmony_ci              builder()->jsgraph()->OptimizedOutConstant());
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ci    values_[accumulator_base()] =
8391cb0ef41Sopenharmony_ci        builder()->MergeValue(values_[accumulator_base()],
8401cb0ef41Sopenharmony_ci                              other->values_[accumulator_base()], control);
8411cb0ef41Sopenharmony_ci  } else {
8421cb0ef41Sopenharmony_ci    values_[accumulator_base()] = builder()->jsgraph()->OptimizedOutConstant();
8431cb0ef41Sopenharmony_ci  }
8441cb0ef41Sopenharmony_ci
8451cb0ef41Sopenharmony_ci  if (generator_state_ != nullptr) {
8461cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(other->generator_state_);
8471cb0ef41Sopenharmony_ci    generator_state_ = builder()->MergeValue(generator_state_,
8481cb0ef41Sopenharmony_ci                                             other->generator_state_, control);
8491cb0ef41Sopenharmony_ci  }
8501cb0ef41Sopenharmony_ci}
8511cb0ef41Sopenharmony_ci
8521cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::PrepareForLoop(
8531cb0ef41Sopenharmony_ci    const BytecodeLoopAssignments& assignments,
8541cb0ef41Sopenharmony_ci    const BytecodeLivenessState* liveness) {
8551cb0ef41Sopenharmony_ci  // Create a control node for the loop header.
8561cb0ef41Sopenharmony_ci  Node* control = builder()->NewLoop();
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci  // Create a Phi for external effects.
8591cb0ef41Sopenharmony_ci  Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
8601cb0ef41Sopenharmony_ci  UpdateEffectDependency(effect);
8611cb0ef41Sopenharmony_ci
8621cb0ef41Sopenharmony_ci  // Create Phis for any values that are live on entry to the loop and may be
8631cb0ef41Sopenharmony_ci  // updated by the end of the loop.
8641cb0ef41Sopenharmony_ci  context_ = builder()->NewPhi(1, context_, control);
8651cb0ef41Sopenharmony_ci  for (int i = 0; i < parameter_count(); i++) {
8661cb0ef41Sopenharmony_ci    if (assignments.ContainsParameter(i)) {
8671cb0ef41Sopenharmony_ci      values_[i] = builder()->NewPhi(1, values_[i], control);
8681cb0ef41Sopenharmony_ci    }
8691cb0ef41Sopenharmony_ci  }
8701cb0ef41Sopenharmony_ci  for (int i = 0; i < register_count(); i++) {
8711cb0ef41Sopenharmony_ci    if (assignments.ContainsLocal(i) &&
8721cb0ef41Sopenharmony_ci        (liveness == nullptr || liveness->RegisterIsLive(i))) {
8731cb0ef41Sopenharmony_ci      int index = register_base() + i;
8741cb0ef41Sopenharmony_ci      values_[index] = builder()->NewPhi(1, values_[index], control);
8751cb0ef41Sopenharmony_ci    }
8761cb0ef41Sopenharmony_ci  }
8771cb0ef41Sopenharmony_ci  // The accumulator should not be live on entry.
8781cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(liveness != nullptr, !liveness->AccumulatorIsLive());
8791cb0ef41Sopenharmony_ci
8801cb0ef41Sopenharmony_ci  if (generator_state_ != nullptr) {
8811cb0ef41Sopenharmony_ci    generator_state_ = builder()->NewPhi(1, generator_state_, control);
8821cb0ef41Sopenharmony_ci  }
8831cb0ef41Sopenharmony_ci
8841cb0ef41Sopenharmony_ci  // Connect to the loop end.
8851cb0ef41Sopenharmony_ci  Node* terminate = builder()->graph()->NewNode(
8861cb0ef41Sopenharmony_ci      builder()->common()->Terminate(), effect, control);
8871cb0ef41Sopenharmony_ci  builder()->exit_controls_.push_back(terminate);
8881cb0ef41Sopenharmony_ci}
8891cb0ef41Sopenharmony_ci
8901cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::FillWithOsrValues() {
8911cb0ef41Sopenharmony_ci  Node* start = graph()->start();
8921cb0ef41Sopenharmony_ci
8931cb0ef41Sopenharmony_ci  // Create OSR values for each environment value.
8941cb0ef41Sopenharmony_ci  SetContext(graph()->NewNode(
8951cb0ef41Sopenharmony_ci      common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), start));
8961cb0ef41Sopenharmony_ci  int size = static_cast<int>(values()->size());
8971cb0ef41Sopenharmony_ci  for (int i = 0; i < size; i++) {
8981cb0ef41Sopenharmony_ci    int idx = i;  // Indexing scheme follows {StandardFrame}, adapt accordingly.
8991cb0ef41Sopenharmony_ci    if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
9001cb0ef41Sopenharmony_ci    if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
9011cb0ef41Sopenharmony_ci    values()->at(i) = graph()->NewNode(common()->OsrValue(idx), start);
9021cb0ef41Sopenharmony_ci  }
9031cb0ef41Sopenharmony_ci}
9041cb0ef41Sopenharmony_ci
9051cb0ef41Sopenharmony_cibool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
9061cb0ef41Sopenharmony_ci    Node** state_values, Node** values, int count) {
9071cb0ef41Sopenharmony_ci  if (*state_values == nullptr) {
9081cb0ef41Sopenharmony_ci    return true;
9091cb0ef41Sopenharmony_ci  }
9101cb0ef41Sopenharmony_ci  Node::Inputs inputs = (*state_values)->inputs();
9111cb0ef41Sopenharmony_ci  if (inputs.count() != count) return true;
9121cb0ef41Sopenharmony_ci  for (int i = 0; i < count; i++) {
9131cb0ef41Sopenharmony_ci    if (inputs[i] != values[i]) {
9141cb0ef41Sopenharmony_ci      return true;
9151cb0ef41Sopenharmony_ci    }
9161cb0ef41Sopenharmony_ci  }
9171cb0ef41Sopenharmony_ci  return false;
9181cb0ef41Sopenharmony_ci}
9191cb0ef41Sopenharmony_ci
9201cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::PrepareForLoopExit(
9211cb0ef41Sopenharmony_ci    Node* loop, const BytecodeLoopAssignments& assignments,
9221cb0ef41Sopenharmony_ci    const BytecodeLivenessState* liveness) {
9231cb0ef41Sopenharmony_ci  DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
9241cb0ef41Sopenharmony_ci
9251cb0ef41Sopenharmony_ci  Node* control = GetControlDependency();
9261cb0ef41Sopenharmony_ci
9271cb0ef41Sopenharmony_ci  // Create the loop exit node.
9281cb0ef41Sopenharmony_ci  Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
9291cb0ef41Sopenharmony_ci  UpdateControlDependency(loop_exit);
9301cb0ef41Sopenharmony_ci
9311cb0ef41Sopenharmony_ci  // Rename the effect.
9321cb0ef41Sopenharmony_ci  Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
9331cb0ef41Sopenharmony_ci                                         GetEffectDependency(), loop_exit);
9341cb0ef41Sopenharmony_ci  UpdateEffectDependency(effect_rename);
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_ci  // TODO(jarin) We should also rename context here. However, unconditional
9371cb0ef41Sopenharmony_ci  // renaming confuses global object and native context specialization.
9381cb0ef41Sopenharmony_ci  // We should only rename if the context is assigned in the loop.
9391cb0ef41Sopenharmony_ci
9401cb0ef41Sopenharmony_ci  // Rename the environment values if they were assigned in the loop and are
9411cb0ef41Sopenharmony_ci  // live after exiting the loop.
9421cb0ef41Sopenharmony_ci  for (int i = 0; i < parameter_count(); i++) {
9431cb0ef41Sopenharmony_ci    if (assignments.ContainsParameter(i)) {
9441cb0ef41Sopenharmony_ci      Node* rename = graph()->NewNode(
9451cb0ef41Sopenharmony_ci          common()->LoopExitValue(MachineRepresentation::kTagged), values_[i],
9461cb0ef41Sopenharmony_ci          loop_exit);
9471cb0ef41Sopenharmony_ci      values_[i] = rename;
9481cb0ef41Sopenharmony_ci    }
9491cb0ef41Sopenharmony_ci  }
9501cb0ef41Sopenharmony_ci  for (int i = 0; i < register_count(); i++) {
9511cb0ef41Sopenharmony_ci    if (assignments.ContainsLocal(i) &&
9521cb0ef41Sopenharmony_ci        (liveness == nullptr || liveness->RegisterIsLive(i))) {
9531cb0ef41Sopenharmony_ci      Node* rename = graph()->NewNode(
9541cb0ef41Sopenharmony_ci          common()->LoopExitValue(MachineRepresentation::kTagged),
9551cb0ef41Sopenharmony_ci          values_[register_base() + i], loop_exit);
9561cb0ef41Sopenharmony_ci      values_[register_base() + i] = rename;
9571cb0ef41Sopenharmony_ci    }
9581cb0ef41Sopenharmony_ci  }
9591cb0ef41Sopenharmony_ci  if (liveness == nullptr || liveness->AccumulatorIsLive()) {
9601cb0ef41Sopenharmony_ci    Node* rename = graph()->NewNode(
9611cb0ef41Sopenharmony_ci        common()->LoopExitValue(MachineRepresentation::kTagged),
9621cb0ef41Sopenharmony_ci        values_[accumulator_base()], loop_exit);
9631cb0ef41Sopenharmony_ci    values_[accumulator_base()] = rename;
9641cb0ef41Sopenharmony_ci  }
9651cb0ef41Sopenharmony_ci
9661cb0ef41Sopenharmony_ci  if (generator_state_ != nullptr) {
9671cb0ef41Sopenharmony_ci    generator_state_ = graph()->NewNode(
9681cb0ef41Sopenharmony_ci        common()->LoopExitValue(MachineRepresentation::kTagged),
9691cb0ef41Sopenharmony_ci        generator_state_, loop_exit);
9701cb0ef41Sopenharmony_ci  }
9711cb0ef41Sopenharmony_ci}
9721cb0ef41Sopenharmony_ci
9731cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
9741cb0ef41Sopenharmony_ci                                                          Node** values,
9751cb0ef41Sopenharmony_ci                                                          int count) {
9761cb0ef41Sopenharmony_ci  if (StateValuesRequireUpdate(state_values, values, count)) {
9771cb0ef41Sopenharmony_ci    const Operator* op = common()->StateValues(count, SparseInputMask::Dense());
9781cb0ef41Sopenharmony_ci    (*state_values) = graph()->NewNode(op, count, values);
9791cb0ef41Sopenharmony_ci  }
9801cb0ef41Sopenharmony_ci}
9811cb0ef41Sopenharmony_ci
9821cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::Environment::GetStateValuesFromCache(
9831cb0ef41Sopenharmony_ci    Node** values, int count, const BytecodeLivenessState* liveness) {
9841cb0ef41Sopenharmony_ci  return builder_->state_values_cache_.GetNodeForValues(
9851cb0ef41Sopenharmony_ci      values, static_cast<size_t>(count), liveness);
9861cb0ef41Sopenharmony_ci}
9871cb0ef41Sopenharmony_ci
9881cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::Environment::Checkpoint(
9891cb0ef41Sopenharmony_ci    BytecodeOffset bailout_id, OutputFrameStateCombine combine,
9901cb0ef41Sopenharmony_ci    const BytecodeLivenessState* liveness) {
9911cb0ef41Sopenharmony_ci  if (parameter_count() == register_count()) {
9921cb0ef41Sopenharmony_ci    // Re-use the state-value cache if the number of local registers happens
9931cb0ef41Sopenharmony_ci    // to match the parameter count.
9941cb0ef41Sopenharmony_ci    parameters_state_values_ =
9951cb0ef41Sopenharmony_ci        GetStateValuesFromCache(&values()->at(0), parameter_count(), nullptr);
9961cb0ef41Sopenharmony_ci  } else {
9971cb0ef41Sopenharmony_ci    UpdateStateValues(&parameters_state_values_, &values()->at(0),
9981cb0ef41Sopenharmony_ci                      parameter_count());
9991cb0ef41Sopenharmony_ci  }
10001cb0ef41Sopenharmony_ci
10011cb0ef41Sopenharmony_ci  Node* registers_state_values = GetStateValuesFromCache(
10021cb0ef41Sopenharmony_ci      &values()->at(register_base()), register_count(), liveness);
10031cb0ef41Sopenharmony_ci
10041cb0ef41Sopenharmony_ci  bool accumulator_is_live = !liveness || liveness->AccumulatorIsLive();
10051cb0ef41Sopenharmony_ci  Node* accumulator_state_value =
10061cb0ef41Sopenharmony_ci      accumulator_is_live && combine != OutputFrameStateCombine::PokeAt(0)
10071cb0ef41Sopenharmony_ci          ? values()->at(accumulator_base())
10081cb0ef41Sopenharmony_ci          : builder()->jsgraph()->OptimizedOutConstant();
10091cb0ef41Sopenharmony_ci
10101cb0ef41Sopenharmony_ci  const Operator* op = common()->FrameState(
10111cb0ef41Sopenharmony_ci      bailout_id, combine, builder()->frame_state_function_info());
10121cb0ef41Sopenharmony_ci  Node* result = graph()->NewNode(
10131cb0ef41Sopenharmony_ci      op, parameters_state_values_, registers_state_values,
10141cb0ef41Sopenharmony_ci      accumulator_state_value, Context(), builder()->GetFunctionClosure(),
10151cb0ef41Sopenharmony_ci      builder()->graph()->start());
10161cb0ef41Sopenharmony_ci
10171cb0ef41Sopenharmony_ci  return result;
10181cb0ef41Sopenharmony_ci}
10191cb0ef41Sopenharmony_ci
10201cb0ef41Sopenharmony_ciBytecodeGraphBuilder::BytecodeGraphBuilder(
10211cb0ef41Sopenharmony_ci    JSHeapBroker* broker, Zone* local_zone,
10221cb0ef41Sopenharmony_ci    NativeContextRef const& native_context,
10231cb0ef41Sopenharmony_ci    SharedFunctionInfoRef const& shared_info,
10241cb0ef41Sopenharmony_ci    FeedbackCellRef const& feedback_cell, BytecodeOffset osr_offset,
10251cb0ef41Sopenharmony_ci    JSGraph* jsgraph, CallFrequency const& invocation_frequency,
10261cb0ef41Sopenharmony_ci    SourcePositionTable* source_positions, int inlining_id, CodeKind code_kind,
10271cb0ef41Sopenharmony_ci    BytecodeGraphBuilderFlags flags, TickCounter* tick_counter,
10281cb0ef41Sopenharmony_ci    ObserveNodeInfo const& observe_node_info)
10291cb0ef41Sopenharmony_ci    : broker_(broker),
10301cb0ef41Sopenharmony_ci      local_isolate_(broker_->local_isolate()
10311cb0ef41Sopenharmony_ci                         ? broker_->local_isolate()
10321cb0ef41Sopenharmony_ci                         : broker_->isolate()->AsLocalIsolate()),
10331cb0ef41Sopenharmony_ci      local_zone_(local_zone),
10341cb0ef41Sopenharmony_ci      jsgraph_(jsgraph),
10351cb0ef41Sopenharmony_ci      native_context_(native_context),
10361cb0ef41Sopenharmony_ci      shared_info_(shared_info),
10371cb0ef41Sopenharmony_ci      bytecode_array_(shared_info.GetBytecodeArray()),
10381cb0ef41Sopenharmony_ci      feedback_cell_(feedback_cell),
10391cb0ef41Sopenharmony_ci      feedback_vector_(feedback_cell.feedback_vector().value()),
10401cb0ef41Sopenharmony_ci      invocation_frequency_(invocation_frequency),
10411cb0ef41Sopenharmony_ci      type_hint_lowering_(
10421cb0ef41Sopenharmony_ci          broker, jsgraph, feedback_vector_,
10431cb0ef41Sopenharmony_ci          (flags & BytecodeGraphBuilderFlag::kBailoutOnUninitialized)
10441cb0ef41Sopenharmony_ci              ? JSTypeHintLowering::kBailoutOnUninitialized
10451cb0ef41Sopenharmony_ci              : JSTypeHintLowering::kNoFlags),
10461cb0ef41Sopenharmony_ci      frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
10471cb0ef41Sopenharmony_ci          FrameStateType::kUnoptimizedFunction,
10481cb0ef41Sopenharmony_ci          bytecode_array().parameter_count(), bytecode_array().register_count(),
10491cb0ef41Sopenharmony_ci          shared_info.object())),
10501cb0ef41Sopenharmony_ci      source_position_iterator_(std::make_unique<SourcePositionTableIterator>(
10511cb0ef41Sopenharmony_ci          bytecode_array().SourcePositionTable())),
10521cb0ef41Sopenharmony_ci      bytecode_iterator_(bytecode_array().object()),
10531cb0ef41Sopenharmony_ci      bytecode_analysis_(
10541cb0ef41Sopenharmony_ci          bytecode_array().object(), local_zone, osr_offset,
10551cb0ef41Sopenharmony_ci          flags & BytecodeGraphBuilderFlag::kAnalyzeEnvironmentLiveness),
10561cb0ef41Sopenharmony_ci      environment_(nullptr),
10571cb0ef41Sopenharmony_ci      osr_(!osr_offset.IsNone()),
10581cb0ef41Sopenharmony_ci      currently_peeled_loop_offset_(-1),
10591cb0ef41Sopenharmony_ci      skip_first_stack_and_tierup_check_(
10601cb0ef41Sopenharmony_ci          flags & BytecodeGraphBuilderFlag::kSkipFirstStackAndTierupCheck),
10611cb0ef41Sopenharmony_ci      merge_environments_(local_zone),
10621cb0ef41Sopenharmony_ci      generator_merge_environments_(local_zone),
10631cb0ef41Sopenharmony_ci      cached_parameters_(local_zone),
10641cb0ef41Sopenharmony_ci      exception_handlers_(local_zone),
10651cb0ef41Sopenharmony_ci      current_exception_handler_(0),
10661cb0ef41Sopenharmony_ci      input_buffer_size_(0),
10671cb0ef41Sopenharmony_ci      input_buffer_(nullptr),
10681cb0ef41Sopenharmony_ci      code_kind_(code_kind),
10691cb0ef41Sopenharmony_ci      feedback_vector_node_(nullptr),
10701cb0ef41Sopenharmony_ci      native_context_node_(nullptr),
10711cb0ef41Sopenharmony_ci      needs_eager_checkpoint_(true),
10721cb0ef41Sopenharmony_ci      exit_controls_(local_zone),
10731cb0ef41Sopenharmony_ci      state_values_cache_(jsgraph),
10741cb0ef41Sopenharmony_ci      source_positions_(source_positions),
10751cb0ef41Sopenharmony_ci      start_position_(shared_info.StartPosition(), inlining_id),
10761cb0ef41Sopenharmony_ci      tick_counter_(tick_counter),
10771cb0ef41Sopenharmony_ci      observe_node_info_(observe_node_info) {}
10781cb0ef41Sopenharmony_ci
10791cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::GetFunctionClosure() {
10801cb0ef41Sopenharmony_ci  if (!function_closure_.is_set()) {
10811cb0ef41Sopenharmony_ci    int index = Linkage::kJSCallClosureParamIndex;
10821cb0ef41Sopenharmony_ci    Node* node = GetParameter(index, "%closure");
10831cb0ef41Sopenharmony_ci    function_closure_.set(node);
10841cb0ef41Sopenharmony_ci  }
10851cb0ef41Sopenharmony_ci  return function_closure_.get();
10861cb0ef41Sopenharmony_ci}
10871cb0ef41Sopenharmony_ci
10881cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::GetParameter(int parameter_index,
10891cb0ef41Sopenharmony_ci                                         const char* debug_name_hint) {
10901cb0ef41Sopenharmony_ci  // We use negative indices for some parameters.
10911cb0ef41Sopenharmony_ci  DCHECK_LE(ParameterInfo::kMinIndex, parameter_index);
10921cb0ef41Sopenharmony_ci  const size_t index =
10931cb0ef41Sopenharmony_ci      static_cast<size_t>(parameter_index - ParameterInfo::kMinIndex);
10941cb0ef41Sopenharmony_ci
10951cb0ef41Sopenharmony_ci  if (cached_parameters_.size() <= index) {
10961cb0ef41Sopenharmony_ci    cached_parameters_.resize(index + 1, nullptr);
10971cb0ef41Sopenharmony_ci  }
10981cb0ef41Sopenharmony_ci
10991cb0ef41Sopenharmony_ci  if (cached_parameters_[index] == nullptr) {
11001cb0ef41Sopenharmony_ci    cached_parameters_[index] =
11011cb0ef41Sopenharmony_ci        NewNode(common()->Parameter(parameter_index, debug_name_hint),
11021cb0ef41Sopenharmony_ci                graph()->start());
11031cb0ef41Sopenharmony_ci  }
11041cb0ef41Sopenharmony_ci
11051cb0ef41Sopenharmony_ci  return cached_parameters_[index];
11061cb0ef41Sopenharmony_ci}
11071cb0ef41Sopenharmony_ci
11081cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::CreateFeedbackVectorNode() {
11091cb0ef41Sopenharmony_ci  DCHECK_NULL(feedback_vector_node_);
11101cb0ef41Sopenharmony_ci  feedback_vector_node_ = jsgraph()->Constant(feedback_vector());
11111cb0ef41Sopenharmony_ci}
11121cb0ef41Sopenharmony_ci
11131cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::BuildLoadFeedbackCell(int index) {
11141cb0ef41Sopenharmony_ci  return jsgraph()->Constant(feedback_vector().GetClosureFeedbackCell(index));
11151cb0ef41Sopenharmony_ci}
11161cb0ef41Sopenharmony_ci
11171cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::CreateNativeContextNode() {
11181cb0ef41Sopenharmony_ci  DCHECK_NULL(native_context_node_);
11191cb0ef41Sopenharmony_ci  native_context_node_ = jsgraph()->Constant(native_context());
11201cb0ef41Sopenharmony_ci}
11211cb0ef41Sopenharmony_ci
11221cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
11231cb0ef41Sopenharmony_ci  Node* result = NewNode(javascript()->LoadContext(0, index, true));
11241cb0ef41Sopenharmony_ci  NodeProperties::ReplaceContextInput(result, native_context_node());
11251cb0ef41Sopenharmony_ci  return result;
11261cb0ef41Sopenharmony_ci}
11271cb0ef41Sopenharmony_ci
11281cb0ef41Sopenharmony_ciFeedbackSource BytecodeGraphBuilder::CreateFeedbackSource(int slot_id) {
11291cb0ef41Sopenharmony_ci  return CreateFeedbackSource(FeedbackVector::ToSlot(slot_id));
11301cb0ef41Sopenharmony_ci}
11311cb0ef41Sopenharmony_ci
11321cb0ef41Sopenharmony_ciFeedbackSource BytecodeGraphBuilder::CreateFeedbackSource(FeedbackSlot slot) {
11331cb0ef41Sopenharmony_ci  return FeedbackSource(feedback_vector(), slot);
11341cb0ef41Sopenharmony_ci}
11351cb0ef41Sopenharmony_ci
11361cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::CreateGraph() {
11371cb0ef41Sopenharmony_ci  SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
11381cb0ef41Sopenharmony_ci
11391cb0ef41Sopenharmony_ci  // Set up the basic structure of the graph. Outputs for {Start} are the formal
11401cb0ef41Sopenharmony_ci  // parameters (including the receiver) plus new target, number of arguments,
11411cb0ef41Sopenharmony_ci  // context and closure.
11421cb0ef41Sopenharmony_ci  int start_output_arity = StartNode::OutputArityForFormalParameterCount(
11431cb0ef41Sopenharmony_ci      bytecode_array().parameter_count());
11441cb0ef41Sopenharmony_ci  graph()->SetStart(graph()->NewNode(common()->Start(start_output_arity)));
11451cb0ef41Sopenharmony_ci
11461cb0ef41Sopenharmony_ci  Environment env(this, bytecode_array().register_count(),
11471cb0ef41Sopenharmony_ci                  bytecode_array().parameter_count(),
11481cb0ef41Sopenharmony_ci                  bytecode_array().incoming_new_target_or_generator_register(),
11491cb0ef41Sopenharmony_ci                  graph()->start());
11501cb0ef41Sopenharmony_ci  set_environment(&env);
11511cb0ef41Sopenharmony_ci
11521cb0ef41Sopenharmony_ci  CreateFeedbackVectorNode();
11531cb0ef41Sopenharmony_ci  CreateNativeContextNode();
11541cb0ef41Sopenharmony_ci
11551cb0ef41Sopenharmony_ci  VisitBytecodes();
11561cb0ef41Sopenharmony_ci
11571cb0ef41Sopenharmony_ci  // Finish the basic structure of the graph.
11581cb0ef41Sopenharmony_ci  DCHECK_NE(0u, exit_controls_.size());
11591cb0ef41Sopenharmony_ci  int const input_count = static_cast<int>(exit_controls_.size());
11601cb0ef41Sopenharmony_ci  Node** const inputs = &exit_controls_.front();
11611cb0ef41Sopenharmony_ci  Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
11621cb0ef41Sopenharmony_ci  graph()->SetEnd(end);
11631cb0ef41Sopenharmony_ci}
11641cb0ef41Sopenharmony_ci
11651cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::PrepareEagerCheckpoint() {
11661cb0ef41Sopenharmony_ci  if (needs_eager_checkpoint()) {
11671cb0ef41Sopenharmony_ci    // Create an explicit checkpoint node for before the operation. This only
11681cb0ef41Sopenharmony_ci    // needs to happen if we aren't effect-dominated by a {Checkpoint} already.
11691cb0ef41Sopenharmony_ci    mark_as_needing_eager_checkpoint(false);
11701cb0ef41Sopenharmony_ci    Node* node = NewNode(common()->Checkpoint());
11711cb0ef41Sopenharmony_ci    DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
11721cb0ef41Sopenharmony_ci    DCHECK_EQ(IrOpcode::kDead,
11731cb0ef41Sopenharmony_ci              NodeProperties::GetFrameStateInput(node)->opcode());
11741cb0ef41Sopenharmony_ci    BytecodeOffset bailout_id(bytecode_iterator().current_offset());
11751cb0ef41Sopenharmony_ci
11761cb0ef41Sopenharmony_ci    const BytecodeLivenessState* liveness_before =
11771cb0ef41Sopenharmony_ci        bytecode_analysis().GetInLivenessFor(
11781cb0ef41Sopenharmony_ci            bytecode_iterator().current_offset());
11791cb0ef41Sopenharmony_ci
11801cb0ef41Sopenharmony_ci    Node* frame_state_before = environment()->Checkpoint(
11811cb0ef41Sopenharmony_ci        bailout_id, OutputFrameStateCombine::Ignore(), liveness_before);
11821cb0ef41Sopenharmony_ci    NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
11831cb0ef41Sopenharmony_ci#ifdef DEBUG
11841cb0ef41Sopenharmony_ci  } else {
11851cb0ef41Sopenharmony_ci    // In case we skipped checkpoint creation above, we must be able to find an
11861cb0ef41Sopenharmony_ci    // existing checkpoint that effect-dominates the nodes about to be created.
11871cb0ef41Sopenharmony_ci    // Starting a search from the current effect-dependency has to succeed.
11881cb0ef41Sopenharmony_ci    Node* effect = environment()->GetEffectDependency();
11891cb0ef41Sopenharmony_ci    while (effect->opcode() != IrOpcode::kCheckpoint) {
11901cb0ef41Sopenharmony_ci      DCHECK(effect->op()->HasProperty(Operator::kNoWrite));
11911cb0ef41Sopenharmony_ci      DCHECK_EQ(1, effect->op()->EffectInputCount());
11921cb0ef41Sopenharmony_ci      effect = NodeProperties::GetEffectInput(effect);
11931cb0ef41Sopenharmony_ci    }
11941cb0ef41Sopenharmony_ci  }
11951cb0ef41Sopenharmony_ci#else
11961cb0ef41Sopenharmony_ci  }
11971cb0ef41Sopenharmony_ci#endif  // DEBUG
11981cb0ef41Sopenharmony_ci}
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::PrepareFrameState(
12011cb0ef41Sopenharmony_ci    Node* node, OutputFrameStateCombine combine, BytecodeOffset bailout_id,
12021cb0ef41Sopenharmony_ci    const BytecodeLivenessState* liveness) {
12031cb0ef41Sopenharmony_ci  if (OperatorProperties::HasFrameStateInput(node->op())) {
12041cb0ef41Sopenharmony_ci    // Add the frame state for after the operation. The node in question has
12051cb0ef41Sopenharmony_ci    // already been created and had a {Dead} frame state input up until now.
12061cb0ef41Sopenharmony_ci    DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
12071cb0ef41Sopenharmony_ci    DCHECK_EQ(IrOpcode::kDead,
12081cb0ef41Sopenharmony_ci              NodeProperties::GetFrameStateInput(node)->opcode());
12091cb0ef41Sopenharmony_ci
12101cb0ef41Sopenharmony_ci    Node* frame_state_after =
12111cb0ef41Sopenharmony_ci        environment()->Checkpoint(bailout_id, combine, liveness);
12121cb0ef41Sopenharmony_ci    NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
12131cb0ef41Sopenharmony_ci  }
12141cb0ef41Sopenharmony_ci}
12151cb0ef41Sopenharmony_ci
12161cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::AdvanceIteratorsTo(int bytecode_offset) {
12171cb0ef41Sopenharmony_ci  for (; bytecode_iterator().current_offset() != bytecode_offset;
12181cb0ef41Sopenharmony_ci       bytecode_iterator().Advance()) {
12191cb0ef41Sopenharmony_ci    UpdateSourcePosition(bytecode_iterator().current_offset());
12201cb0ef41Sopenharmony_ci  }
12211cb0ef41Sopenharmony_ci}
12221cb0ef41Sopenharmony_ci
12231cb0ef41Sopenharmony_ci// Stores the state of the SourcePosition iterator, and the index to the
12241cb0ef41Sopenharmony_ci// current exception handlers stack. We need, during the OSR graph generation,
12251cb0ef41Sopenharmony_ci// to backup the states of these iterators at the LoopHeader offset of each
12261cb0ef41Sopenharmony_ci// outer loop which contains the OSR loop. The iterators are then restored when
12271cb0ef41Sopenharmony_ci// peeling the loops, so that both exception handling and synchronisation with
12281cb0ef41Sopenharmony_ci// the source position can be achieved.
12291cb0ef41Sopenharmony_ciclass BytecodeGraphBuilder::OsrIteratorState {
12301cb0ef41Sopenharmony_ci public:
12311cb0ef41Sopenharmony_ci  explicit OsrIteratorState(BytecodeGraphBuilder* graph_builder)
12321cb0ef41Sopenharmony_ci      : graph_builder_(graph_builder),
12331cb0ef41Sopenharmony_ci        saved_states_(graph_builder->local_zone()) {}
12341cb0ef41Sopenharmony_ci
12351cb0ef41Sopenharmony_ci  void ProcessOsrPrelude() {
12361cb0ef41Sopenharmony_ci    ZoneVector<int> outer_loop_offsets(graph_builder_->local_zone());
12371cb0ef41Sopenharmony_ci    int osr_entry = graph_builder_->bytecode_analysis().osr_entry_point();
12381cb0ef41Sopenharmony_ci
12391cb0ef41Sopenharmony_ci    // We find here the outermost loop which contains the OSR loop.
12401cb0ef41Sopenharmony_ci    int outermost_loop_offset = osr_entry;
12411cb0ef41Sopenharmony_ci    while ((outermost_loop_offset = graph_builder_->bytecode_analysis()
12421cb0ef41Sopenharmony_ci                                        .GetLoopInfoFor(outermost_loop_offset)
12431cb0ef41Sopenharmony_ci                                        .parent_offset()) != -1) {
12441cb0ef41Sopenharmony_ci      outer_loop_offsets.push_back(outermost_loop_offset);
12451cb0ef41Sopenharmony_ci    }
12461cb0ef41Sopenharmony_ci    outermost_loop_offset =
12471cb0ef41Sopenharmony_ci        outer_loop_offsets.empty() ? osr_entry : outer_loop_offsets.back();
12481cb0ef41Sopenharmony_ci    graph_builder_->AdvanceIteratorsTo(outermost_loop_offset);
12491cb0ef41Sopenharmony_ci
12501cb0ef41Sopenharmony_ci    // We save some iterators states at the offsets of the loop headers of the
12511cb0ef41Sopenharmony_ci    // outer loops (the ones containing the OSR loop). They will be used for
12521cb0ef41Sopenharmony_ci    // jumping back in the bytecode.
12531cb0ef41Sopenharmony_ci    for (ZoneVector<int>::const_reverse_iterator it =
12541cb0ef41Sopenharmony_ci             outer_loop_offsets.crbegin();
12551cb0ef41Sopenharmony_ci         it != outer_loop_offsets.crend(); ++it) {
12561cb0ef41Sopenharmony_ci      graph_builder_->AdvanceIteratorsTo(*it);
12571cb0ef41Sopenharmony_ci      graph_builder_->ExitThenEnterExceptionHandlers(
12581cb0ef41Sopenharmony_ci          graph_builder_->bytecode_iterator().current_offset());
12591cb0ef41Sopenharmony_ci      saved_states_.push(IteratorsStates(
12601cb0ef41Sopenharmony_ci          graph_builder_->current_exception_handler(),
12611cb0ef41Sopenharmony_ci          graph_builder_->source_position_iterator().GetState()));
12621cb0ef41Sopenharmony_ci    }
12631cb0ef41Sopenharmony_ci
12641cb0ef41Sopenharmony_ci    // Finishing by advancing to the OSR entry
12651cb0ef41Sopenharmony_ci    graph_builder_->AdvanceIteratorsTo(osr_entry);
12661cb0ef41Sopenharmony_ci
12671cb0ef41Sopenharmony_ci    // Enters all remaining exception handler which end before the OSR loop
12681cb0ef41Sopenharmony_ci    // so that on next call of VisitSingleBytecode they will get popped from
12691cb0ef41Sopenharmony_ci    // the exception handlers stack.
12701cb0ef41Sopenharmony_ci    graph_builder_->ExitThenEnterExceptionHandlers(osr_entry);
12711cb0ef41Sopenharmony_ci    graph_builder_->set_currently_peeled_loop_offset(
12721cb0ef41Sopenharmony_ci        graph_builder_->bytecode_analysis()
12731cb0ef41Sopenharmony_ci            .GetLoopInfoFor(osr_entry)
12741cb0ef41Sopenharmony_ci            .parent_offset());
12751cb0ef41Sopenharmony_ci  }
12761cb0ef41Sopenharmony_ci
12771cb0ef41Sopenharmony_ci  void RestoreState(int target_offset, int new_parent_offset) {
12781cb0ef41Sopenharmony_ci    graph_builder_->bytecode_iterator().SetOffset(target_offset);
12791cb0ef41Sopenharmony_ci    // In case of a return, we must not build loop exits for
12801cb0ef41Sopenharmony_ci    // not-yet-built outer loops.
12811cb0ef41Sopenharmony_ci    graph_builder_->set_currently_peeled_loop_offset(new_parent_offset);
12821cb0ef41Sopenharmony_ci    IteratorsStates saved_state = saved_states_.top();
12831cb0ef41Sopenharmony_ci    graph_builder_->source_position_iterator().RestoreState(
12841cb0ef41Sopenharmony_ci        saved_state.source_iterator_state_);
12851cb0ef41Sopenharmony_ci    graph_builder_->set_current_exception_handler(
12861cb0ef41Sopenharmony_ci        saved_state.exception_handler_index_);
12871cb0ef41Sopenharmony_ci    saved_states_.pop();
12881cb0ef41Sopenharmony_ci  }
12891cb0ef41Sopenharmony_ci
12901cb0ef41Sopenharmony_ci private:
12911cb0ef41Sopenharmony_ci  struct IteratorsStates {
12921cb0ef41Sopenharmony_ci    int exception_handler_index_;
12931cb0ef41Sopenharmony_ci    SourcePositionTableIterator::IndexAndPositionState source_iterator_state_;
12941cb0ef41Sopenharmony_ci
12951cb0ef41Sopenharmony_ci    IteratorsStates(int exception_handler_index,
12961cb0ef41Sopenharmony_ci                    SourcePositionTableIterator::IndexAndPositionState
12971cb0ef41Sopenharmony_ci                        source_iterator_state)
12981cb0ef41Sopenharmony_ci        : exception_handler_index_(exception_handler_index),
12991cb0ef41Sopenharmony_ci          source_iterator_state_(source_iterator_state) {}
13001cb0ef41Sopenharmony_ci  };
13011cb0ef41Sopenharmony_ci
13021cb0ef41Sopenharmony_ci  BytecodeGraphBuilder* graph_builder_;
13031cb0ef41Sopenharmony_ci  ZoneStack<IteratorsStates> saved_states_;
13041cb0ef41Sopenharmony_ci};
13051cb0ef41Sopenharmony_ci
13061cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::RemoveMergeEnvironmentsBeforeOffset(
13071cb0ef41Sopenharmony_ci    int limit_offset) {
13081cb0ef41Sopenharmony_ci  if (!merge_environments_.empty()) {
13091cb0ef41Sopenharmony_ci    ZoneMap<int, Environment*>::iterator it = merge_environments_.begin();
13101cb0ef41Sopenharmony_ci    ZoneMap<int, Environment*>::iterator stop_it = merge_environments_.end();
13111cb0ef41Sopenharmony_ci    while (it != stop_it && it->first <= limit_offset) {
13121cb0ef41Sopenharmony_ci      it = merge_environments_.erase(it);
13131cb0ef41Sopenharmony_ci    }
13141cb0ef41Sopenharmony_ci  }
13151cb0ef41Sopenharmony_ci}
13161cb0ef41Sopenharmony_ci
13171cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildFunctionEntryStackCheck() {
13181cb0ef41Sopenharmony_ci  if (!skip_first_stack_check()) {
13191cb0ef41Sopenharmony_ci    DCHECK(exception_handlers_.empty());
13201cb0ef41Sopenharmony_ci    Node* node =
13211cb0ef41Sopenharmony_ci        NewNode(javascript()->StackCheck(StackCheckKind::kJSFunctionEntry));
13221cb0ef41Sopenharmony_ci    PrepareFrameStateForFunctionEntryStackCheck(node);
13231cb0ef41Sopenharmony_ci  }
13241cb0ef41Sopenharmony_ci}
13251cb0ef41Sopenharmony_ci
13261cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildIterationBodyStackCheck() {
13271cb0ef41Sopenharmony_ci  Node* node =
13281cb0ef41Sopenharmony_ci      NewNode(javascript()->StackCheck(StackCheckKind::kJSIterationBody));
13291cb0ef41Sopenharmony_ci  environment()->RecordAfterState(node, Environment::kAttachFrameState);
13301cb0ef41Sopenharmony_ci}
13311cb0ef41Sopenharmony_ci
13321cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildOSREntryStackCheck() {
13331cb0ef41Sopenharmony_ci  DCHECK(exception_handlers_.empty());
13341cb0ef41Sopenharmony_ci  Node* node =
13351cb0ef41Sopenharmony_ci      NewNode(javascript()->StackCheck(StackCheckKind::kJSFunctionEntry));
13361cb0ef41Sopenharmony_ci  PrepareFrameStateForOSREntryStackCheck(node);
13371cb0ef41Sopenharmony_ci}
13381cb0ef41Sopenharmony_ci
13391cb0ef41Sopenharmony_ci// We will iterate through the OSR loop, then its parent, and so on
13401cb0ef41Sopenharmony_ci// until we have reached the outmost loop containing the OSR loop. We do
13411cb0ef41Sopenharmony_ci// not generate nodes for anything before the outermost loop.
13421cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::AdvanceToOsrEntryAndPeelLoops() {
13431cb0ef41Sopenharmony_ci  environment()->FillWithOsrValues();
13441cb0ef41Sopenharmony_ci
13451cb0ef41Sopenharmony_ci  // The entry stack check has to happen *before* initialising the OSR prelude;
13461cb0ef41Sopenharmony_ci  // it has to happen before setting up exception handlers, so that the
13471cb0ef41Sopenharmony_ci  // optimized code can't accidentally catch a failingstack with a OSR-ed loop
13481cb0ef41Sopenharmony_ci  // inside a try-catch, e.g.
13491cb0ef41Sopenharmony_ci  //
13501cb0ef41Sopenharmony_ci  //   try {
13511cb0ef41Sopenharmony_ci  //     loop { OSR(); }
13521cb0ef41Sopenharmony_ci  //   } catch {
13531cb0ef41Sopenharmony_ci  //     // Ignore failed stack check.
13541cb0ef41Sopenharmony_ci  //   }
13551cb0ef41Sopenharmony_ci  BuildOSREntryStackCheck();
13561cb0ef41Sopenharmony_ci
13571cb0ef41Sopenharmony_ci  OsrIteratorState iterator_states(this);
13581cb0ef41Sopenharmony_ci  iterator_states.ProcessOsrPrelude();
13591cb0ef41Sopenharmony_ci  int osr_entry = bytecode_analysis().osr_entry_point();
13601cb0ef41Sopenharmony_ci  DCHECK_EQ(bytecode_iterator().current_offset(), osr_entry);
13611cb0ef41Sopenharmony_ci
13621cb0ef41Sopenharmony_ci  // Suppose we have n nested loops, loop_0 being the outermost one, and
13631cb0ef41Sopenharmony_ci  // loop_n being the OSR loop. We start iterating the bytecode at the header
13641cb0ef41Sopenharmony_ci  // of loop_n (the OSR loop), and then we peel the part of the the body of
13651cb0ef41Sopenharmony_ci  // loop_{n-1} following the end of loop_n. We then rewind the iterator to
13661cb0ef41Sopenharmony_ci  // the header of loop_{n-1}, and so on until we have partly peeled loop 0.
13671cb0ef41Sopenharmony_ci  // The full loop_0 body will be generating with the rest of the function,
13681cb0ef41Sopenharmony_ci  // outside the OSR generation.
13691cb0ef41Sopenharmony_ci
13701cb0ef41Sopenharmony_ci  // To do so, if we are visiting a loop, we continue to visit what's left
13711cb0ef41Sopenharmony_ci  // of its parent, and then when reaching the parent's JumpLoop, we do not
13721cb0ef41Sopenharmony_ci  // create any jump for that but rewind the bytecode iterator to visit the
13731cb0ef41Sopenharmony_ci  // parent loop entirely, and so on.
13741cb0ef41Sopenharmony_ci
13751cb0ef41Sopenharmony_ci  int current_parent_offset =
13761cb0ef41Sopenharmony_ci      bytecode_analysis().GetLoopInfoFor(osr_entry).parent_offset();
13771cb0ef41Sopenharmony_ci  while (current_parent_offset != -1) {
13781cb0ef41Sopenharmony_ci    const LoopInfo& current_parent_loop =
13791cb0ef41Sopenharmony_ci        bytecode_analysis().GetLoopInfoFor(current_parent_offset);
13801cb0ef41Sopenharmony_ci    // We iterate until the back edge of the parent loop, which we detect by
13811cb0ef41Sopenharmony_ci    // the offset that the JumpLoop targets.
13821cb0ef41Sopenharmony_ci    for (; !bytecode_iterator().done(); bytecode_iterator().Advance()) {
13831cb0ef41Sopenharmony_ci      if (bytecode_iterator().current_bytecode() ==
13841cb0ef41Sopenharmony_ci              interpreter::Bytecode::kJumpLoop &&
13851cb0ef41Sopenharmony_ci          bytecode_iterator().GetJumpTargetOffset() == current_parent_offset) {
13861cb0ef41Sopenharmony_ci        // Reached the end of the current parent loop.
13871cb0ef41Sopenharmony_ci        break;
13881cb0ef41Sopenharmony_ci      }
13891cb0ef41Sopenharmony_ci      VisitSingleBytecode();
13901cb0ef41Sopenharmony_ci    }
13911cb0ef41Sopenharmony_ci    DCHECK(!bytecode_iterator()
13921cb0ef41Sopenharmony_ci                .done());  // Should have found the loop's jump target.
13931cb0ef41Sopenharmony_ci
13941cb0ef41Sopenharmony_ci    // We also need to take care of the merge environments and exceptions
13951cb0ef41Sopenharmony_ci    // handlers here because the omitted JumpLoop bytecode can still be the
13961cb0ef41Sopenharmony_ci    // target of jumps or the first bytecode after a try block.
13971cb0ef41Sopenharmony_ci    ExitThenEnterExceptionHandlers(bytecode_iterator().current_offset());
13981cb0ef41Sopenharmony_ci    SwitchToMergeEnvironment(bytecode_iterator().current_offset());
13991cb0ef41Sopenharmony_ci
14001cb0ef41Sopenharmony_ci    // This jump is the jump of our parent loop, which is not yet created.
14011cb0ef41Sopenharmony_ci    // So we do not build the jump nodes, but restore the bytecode and the
14021cb0ef41Sopenharmony_ci    // SourcePosition iterators to the values they had when we were visiting
14031cb0ef41Sopenharmony_ci    // the offset pointed at by the JumpLoop we've just reached.
14041cb0ef41Sopenharmony_ci    // We have already built nodes for inner loops, but now we will
14051cb0ef41Sopenharmony_ci    // iterate again over them and build new nodes corresponding to the same
14061cb0ef41Sopenharmony_ci    // bytecode offsets. Any jump or reference to this inner loops must now
14071cb0ef41Sopenharmony_ci    // point to the new nodes we will build, hence we clear the relevant part
14081cb0ef41Sopenharmony_ci    // of the environment.
14091cb0ef41Sopenharmony_ci    // Completely clearing the environment is not possible because merge
14101cb0ef41Sopenharmony_ci    // environments for forward jumps out of the loop need to be preserved
14111cb0ef41Sopenharmony_ci    // (e.g. a return or a labeled break in the middle of a loop).
14121cb0ef41Sopenharmony_ci    RemoveMergeEnvironmentsBeforeOffset(bytecode_iterator().current_offset());
14131cb0ef41Sopenharmony_ci    iterator_states.RestoreState(current_parent_offset,
14141cb0ef41Sopenharmony_ci                                 current_parent_loop.parent_offset());
14151cb0ef41Sopenharmony_ci    current_parent_offset = current_parent_loop.parent_offset();
14161cb0ef41Sopenharmony_ci  }
14171cb0ef41Sopenharmony_ci}
14181cb0ef41Sopenharmony_ci
14191cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSingleBytecode() {
14201cb0ef41Sopenharmony_ci  tick_counter_->TickAndMaybeEnterSafepoint();
14211cb0ef41Sopenharmony_ci  int current_offset = bytecode_iterator().current_offset();
14221cb0ef41Sopenharmony_ci  UpdateSourcePosition(current_offset);
14231cb0ef41Sopenharmony_ci  ExitThenEnterExceptionHandlers(current_offset);
14241cb0ef41Sopenharmony_ci  DCHECK_GE(exception_handlers_.empty() ? current_offset
14251cb0ef41Sopenharmony_ci                                        : exception_handlers_.top().end_offset_,
14261cb0ef41Sopenharmony_ci            current_offset);
14271cb0ef41Sopenharmony_ci  SwitchToMergeEnvironment(current_offset);
14281cb0ef41Sopenharmony_ci
14291cb0ef41Sopenharmony_ci  if (environment() != nullptr) {
14301cb0ef41Sopenharmony_ci    BuildLoopHeaderEnvironment(current_offset);
14311cb0ef41Sopenharmony_ci
14321cb0ef41Sopenharmony_ci    switch (bytecode_iterator().current_bytecode()) {
14331cb0ef41Sopenharmony_ci#define BYTECODE_CASE(name, ...)       \
14341cb0ef41Sopenharmony_ci  case interpreter::Bytecode::k##name: \
14351cb0ef41Sopenharmony_ci    Visit##name();                     \
14361cb0ef41Sopenharmony_ci    break;
14371cb0ef41Sopenharmony_ci      BYTECODE_LIST(BYTECODE_CASE)
14381cb0ef41Sopenharmony_ci#undef BYTECODE_CASE
14391cb0ef41Sopenharmony_ci    }
14401cb0ef41Sopenharmony_ci  }
14411cb0ef41Sopenharmony_ci}
14421cb0ef41Sopenharmony_ci
14431cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitBytecodes() {
14441cb0ef41Sopenharmony_ci  if (!bytecode_analysis().resume_jump_targets().empty()) {
14451cb0ef41Sopenharmony_ci    environment()->BindGeneratorState(
14461cb0ef41Sopenharmony_ci        jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
14471cb0ef41Sopenharmony_ci  }
14481cb0ef41Sopenharmony_ci
14491cb0ef41Sopenharmony_ci  if (osr_) {
14501cb0ef41Sopenharmony_ci    // We peel the OSR loop and any outer loop containing it except that we
14511cb0ef41Sopenharmony_ci    // leave the nodes corresponding to the whole outermost loop (including
14521cb0ef41Sopenharmony_ci    // the last copies of the loops it contains) to be generated by the normal
14531cb0ef41Sopenharmony_ci    // bytecode iteration below.
14541cb0ef41Sopenharmony_ci    AdvanceToOsrEntryAndPeelLoops();
14551cb0ef41Sopenharmony_ci  } else {
14561cb0ef41Sopenharmony_ci    BuildFunctionEntryStackCheck();
14571cb0ef41Sopenharmony_ci  }
14581cb0ef41Sopenharmony_ci
14591cb0ef41Sopenharmony_ci  for (; !bytecode_iterator().done(); bytecode_iterator().Advance()) {
14601cb0ef41Sopenharmony_ci    VisitSingleBytecode();
14611cb0ef41Sopenharmony_ci  }
14621cb0ef41Sopenharmony_ci
14631cb0ef41Sopenharmony_ci  DCHECK(exception_handlers_.empty());
14641cb0ef41Sopenharmony_ci}
14651cb0ef41Sopenharmony_ci
14661cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaZero() {
14671cb0ef41Sopenharmony_ci  Node* node = jsgraph()->ZeroConstant();
14681cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
14691cb0ef41Sopenharmony_ci}
14701cb0ef41Sopenharmony_ci
14711cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaSmi() {
14721cb0ef41Sopenharmony_ci  Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
14731cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
14741cb0ef41Sopenharmony_ci}
14751cb0ef41Sopenharmony_ci
14761cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaConstant() {
14771cb0ef41Sopenharmony_ci  ObjectRef object = MakeRefForConstantForIndexOperand(0);
14781cb0ef41Sopenharmony_ci  Node* node = jsgraph()->Constant(object);
14791cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
14801cb0ef41Sopenharmony_ci}
14811cb0ef41Sopenharmony_ci
14821cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaUndefined() {
14831cb0ef41Sopenharmony_ci  Node* node = jsgraph()->UndefinedConstant();
14841cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
14851cb0ef41Sopenharmony_ci}
14861cb0ef41Sopenharmony_ci
14871cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaNull() {
14881cb0ef41Sopenharmony_ci  Node* node = jsgraph()->NullConstant();
14891cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
14901cb0ef41Sopenharmony_ci}
14911cb0ef41Sopenharmony_ci
14921cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaTheHole() {
14931cb0ef41Sopenharmony_ci  Node* node = jsgraph()->TheHoleConstant();
14941cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
14951cb0ef41Sopenharmony_ci}
14961cb0ef41Sopenharmony_ci
14971cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaTrue() {
14981cb0ef41Sopenharmony_ci  Node* node = jsgraph()->TrueConstant();
14991cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
15001cb0ef41Sopenharmony_ci}
15011cb0ef41Sopenharmony_ci
15021cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaFalse() {
15031cb0ef41Sopenharmony_ci  Node* node = jsgraph()->FalseConstant();
15041cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
15051cb0ef41Sopenharmony_ci}
15061cb0ef41Sopenharmony_ci
15071cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdar() {
15081cb0ef41Sopenharmony_ci  Node* value =
15091cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
15101cb0ef41Sopenharmony_ci  environment()->BindAccumulator(value);
15111cb0ef41Sopenharmony_ci}
15121cb0ef41Sopenharmony_ci
15131cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitStar() {
15141cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
15151cb0ef41Sopenharmony_ci  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
15161cb0ef41Sopenharmony_ci}
15171cb0ef41Sopenharmony_ci
15181cb0ef41Sopenharmony_ci#define SHORT_STAR_VISITOR(Name, ...)                                         \
15191cb0ef41Sopenharmony_ci  void BytecodeGraphBuilder::Visit##Name() {                                  \
15201cb0ef41Sopenharmony_ci    Node* value = environment()->LookupAccumulator();                         \
15211cb0ef41Sopenharmony_ci    environment()->BindRegister(                                              \
15221cb0ef41Sopenharmony_ci        interpreter::Register::FromShortStar(interpreter::Bytecode::k##Name), \
15231cb0ef41Sopenharmony_ci        value);                                                               \
15241cb0ef41Sopenharmony_ci  }
15251cb0ef41Sopenharmony_ciSHORT_STAR_BYTECODE_LIST(SHORT_STAR_VISITOR)
15261cb0ef41Sopenharmony_ci#undef SHORT_STAR_VISITOR
15271cb0ef41Sopenharmony_ci
15281cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitMov() {
15291cb0ef41Sopenharmony_ci  Node* value =
15301cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
15311cb0ef41Sopenharmony_ci  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
15321cb0ef41Sopenharmony_ci}
15331cb0ef41Sopenharmony_ci
15341cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::BuildLoadGlobal(NameRef name,
15351cb0ef41Sopenharmony_ci                                            uint32_t feedback_slot_index,
15361cb0ef41Sopenharmony_ci                                            TypeofMode typeof_mode) {
15371cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(feedback_slot_index);
15381cb0ef41Sopenharmony_ci  DCHECK(IsLoadGlobalICKind(broker()->GetFeedbackSlotKind(feedback)));
15391cb0ef41Sopenharmony_ci  const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
15401cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
15411cb0ef41Sopenharmony_ci  return NewNode(op, feedback_vector_node());
15421cb0ef41Sopenharmony_ci}
15431cb0ef41Sopenharmony_ci
15441cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaGlobal() {
15451cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
15461cb0ef41Sopenharmony_ci  NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
15471cb0ef41Sopenharmony_ci  uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
15481cb0ef41Sopenharmony_ci  Node* node =
15491cb0ef41Sopenharmony_ci      BuildLoadGlobal(name, feedback_slot_index, TypeofMode::kNotInside);
15501cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
15511cb0ef41Sopenharmony_ci}
15521cb0ef41Sopenharmony_ci
15531cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
15541cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
15551cb0ef41Sopenharmony_ci  NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
15561cb0ef41Sopenharmony_ci  uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
15571cb0ef41Sopenharmony_ci  Node* node = BuildLoadGlobal(name, feedback_slot_index, TypeofMode::kInside);
15581cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
15591cb0ef41Sopenharmony_ci}
15601cb0ef41Sopenharmony_ci
15611cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitStaGlobal() {
15621cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
15631cb0ef41Sopenharmony_ci  NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
15641cb0ef41Sopenharmony_ci  FeedbackSource feedback =
15651cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
15661cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
15671cb0ef41Sopenharmony_ci
15681cb0ef41Sopenharmony_ci  LanguageMode language_mode =
15691cb0ef41Sopenharmony_ci      GetLanguageModeFromSlotKind(broker()->GetFeedbackSlotKind(feedback));
15701cb0ef41Sopenharmony_ci  const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
15711cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
15721cb0ef41Sopenharmony_ci  Node* node = NewNode(op, value, feedback_vector_node());
15731cb0ef41Sopenharmony_ci  environment()->RecordAfterState(node, Environment::kAttachFrameState);
15741cb0ef41Sopenharmony_ci}
15751cb0ef41Sopenharmony_ci
15761cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitStaInArrayLiteral() {
15771cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
15781cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
15791cb0ef41Sopenharmony_ci  Node* array =
15801cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
15811cb0ef41Sopenharmony_ci  Node* index =
15821cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
15831cb0ef41Sopenharmony_ci  FeedbackSource feedback =
15841cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
15851cb0ef41Sopenharmony_ci  const Operator* op = javascript()->StoreInArrayLiteral(feedback);
15861cb0ef41Sopenharmony_ci
15871cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
15881cb0ef41Sopenharmony_ci      TryBuildSimplifiedStoreKeyed(op, array, index, value, feedback.slot);
15891cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
15901cb0ef41Sopenharmony_ci
15911cb0ef41Sopenharmony_ci  Node* node = nullptr;
15921cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
15931cb0ef41Sopenharmony_ci    node = lowering.value();
15941cb0ef41Sopenharmony_ci  } else {
15951cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
15961cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
15971cb0ef41Sopenharmony_ci    node = NewNode(op, array, index, value, feedback_vector_node());
15981cb0ef41Sopenharmony_ci  }
15991cb0ef41Sopenharmony_ci
16001cb0ef41Sopenharmony_ci  environment()->RecordAfterState(node, Environment::kAttachFrameState);
16011cb0ef41Sopenharmony_ci}
16021cb0ef41Sopenharmony_ci
16031cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDefineKeyedOwnPropertyInLiteral() {
16041cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
16051cb0ef41Sopenharmony_ci
16061cb0ef41Sopenharmony_ci  Node* object =
16071cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
16081cb0ef41Sopenharmony_ci  Node* name =
16091cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
16101cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
16111cb0ef41Sopenharmony_ci  int flags = bytecode_iterator().GetFlagOperand(2);
16121cb0ef41Sopenharmony_ci  FeedbackSource feedback =
16131cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(3));
16141cb0ef41Sopenharmony_ci  const Operator* op = javascript()->DefineKeyedOwnPropertyInLiteral(feedback);
16151cb0ef41Sopenharmony_ci
16161cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
16171cb0ef41Sopenharmony_ci      TryBuildSimplifiedStoreKeyed(op, object, name, value, feedback.slot);
16181cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
16191cb0ef41Sopenharmony_ci
16201cb0ef41Sopenharmony_ci  Node* node = nullptr;
16211cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
16221cb0ef41Sopenharmony_ci    node = lowering.value();
16231cb0ef41Sopenharmony_ci  } else {
16241cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
16251cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
16261cb0ef41Sopenharmony_ci    node = NewNode(op, object, name, value, jsgraph()->Constant(flags),
16271cb0ef41Sopenharmony_ci                   feedback_vector_node());
16281cb0ef41Sopenharmony_ci  }
16291cb0ef41Sopenharmony_ci
16301cb0ef41Sopenharmony_ci  environment()->RecordAfterState(node, Environment::kAttachFrameState);
16311cb0ef41Sopenharmony_ci}
16321cb0ef41Sopenharmony_ci
16331cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCollectTypeProfile() {
16341cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
16351cb0ef41Sopenharmony_ci
16361cb0ef41Sopenharmony_ci  Node* position =
16371cb0ef41Sopenharmony_ci      jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
16381cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
16391cb0ef41Sopenharmony_ci  Node* vector = jsgraph()->Constant(feedback_vector());
16401cb0ef41Sopenharmony_ci
16411cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CallRuntime(Runtime::kCollectTypeProfile);
16421cb0ef41Sopenharmony_ci
16431cb0ef41Sopenharmony_ci  Node* node = NewNode(op, position, value, vector);
16441cb0ef41Sopenharmony_ci  environment()->RecordAfterState(node, Environment::kAttachFrameState);
16451cb0ef41Sopenharmony_ci}
16461cb0ef41Sopenharmony_ci
16471cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaContextSlot() {
16481cb0ef41Sopenharmony_ci  const Operator* op = javascript()->LoadContext(
16491cb0ef41Sopenharmony_ci      bytecode_iterator().GetUnsignedImmediateOperand(2),
16501cb0ef41Sopenharmony_ci      bytecode_iterator().GetIndexOperand(1), false);
16511cb0ef41Sopenharmony_ci  Node* node = NewNode(op);
16521cb0ef41Sopenharmony_ci  Node* context =
16531cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
16541cb0ef41Sopenharmony_ci  NodeProperties::ReplaceContextInput(node, context);
16551cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
16561cb0ef41Sopenharmony_ci}
16571cb0ef41Sopenharmony_ci
16581cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaImmutableContextSlot() {
16591cb0ef41Sopenharmony_ci  const Operator* op = javascript()->LoadContext(
16601cb0ef41Sopenharmony_ci      bytecode_iterator().GetUnsignedImmediateOperand(2),
16611cb0ef41Sopenharmony_ci      bytecode_iterator().GetIndexOperand(1), true);
16621cb0ef41Sopenharmony_ci  Node* node = NewNode(op);
16631cb0ef41Sopenharmony_ci  Node* context =
16641cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
16651cb0ef41Sopenharmony_ci  NodeProperties::ReplaceContextInput(node, context);
16661cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
16671cb0ef41Sopenharmony_ci}
16681cb0ef41Sopenharmony_ci
16691cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
16701cb0ef41Sopenharmony_ci  const Operator* op = javascript()->LoadContext(
16711cb0ef41Sopenharmony_ci      0, bytecode_iterator().GetIndexOperand(0), false);
16721cb0ef41Sopenharmony_ci  Node* node = NewNode(op);
16731cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
16741cb0ef41Sopenharmony_ci}
16751cb0ef41Sopenharmony_ci
16761cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaImmutableCurrentContextSlot() {
16771cb0ef41Sopenharmony_ci  const Operator* op = javascript()->LoadContext(
16781cb0ef41Sopenharmony_ci      0, bytecode_iterator().GetIndexOperand(0), true);
16791cb0ef41Sopenharmony_ci  Node* node = NewNode(op);
16801cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
16811cb0ef41Sopenharmony_ci}
16821cb0ef41Sopenharmony_ci
16831cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitStaContextSlot() {
16841cb0ef41Sopenharmony_ci  const Operator* op = javascript()->StoreContext(
16851cb0ef41Sopenharmony_ci      bytecode_iterator().GetUnsignedImmediateOperand(2),
16861cb0ef41Sopenharmony_ci      bytecode_iterator().GetIndexOperand(1));
16871cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
16881cb0ef41Sopenharmony_ci  Node* node = NewNode(op, value);
16891cb0ef41Sopenharmony_ci  Node* context =
16901cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
16911cb0ef41Sopenharmony_ci  NodeProperties::ReplaceContextInput(node, context);
16921cb0ef41Sopenharmony_ci}
16931cb0ef41Sopenharmony_ci
16941cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitStaCurrentContextSlot() {
16951cb0ef41Sopenharmony_ci  const Operator* op =
16961cb0ef41Sopenharmony_ci      javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0));
16971cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
16981cb0ef41Sopenharmony_ci  NewNode(op, value);
16991cb0ef41Sopenharmony_ci}
17001cb0ef41Sopenharmony_ci
17011cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
17021cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
17031cb0ef41Sopenharmony_ci  Node* name = jsgraph()->Constant(MakeRefForConstantForIndexOperand(0));
17041cb0ef41Sopenharmony_ci  const Operator* op =
17051cb0ef41Sopenharmony_ci      javascript()->CallRuntime(typeof_mode == TypeofMode::kNotInside
17061cb0ef41Sopenharmony_ci                                    ? Runtime::kLoadLookupSlot
17071cb0ef41Sopenharmony_ci                                    : Runtime::kLoadLookupSlotInsideTypeof);
17081cb0ef41Sopenharmony_ci  Node* value = NewNode(op, name);
17091cb0ef41Sopenharmony_ci  environment()->BindAccumulator(value, Environment::kAttachFrameState);
17101cb0ef41Sopenharmony_ci}
17111cb0ef41Sopenharmony_ci
17121cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaLookupSlot() {
17131cb0ef41Sopenharmony_ci  BuildLdaLookupSlot(TypeofMode::kNotInside);
17141cb0ef41Sopenharmony_ci}
17151cb0ef41Sopenharmony_ci
17161cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
17171cb0ef41Sopenharmony_ci  BuildLdaLookupSlot(TypeofMode::kInside);
17181cb0ef41Sopenharmony_ci}
17191cb0ef41Sopenharmony_ci
17201cb0ef41Sopenharmony_ciBytecodeGraphBuilder::Environment*
17211cb0ef41Sopenharmony_ciBytecodeGraphBuilder::CheckContextExtensionAtDepth(
17221cb0ef41Sopenharmony_ci    Environment* slow_environment, uint32_t depth) {
17231cb0ef41Sopenharmony_ci  Node* extension_slot = NewNode(
17241cb0ef41Sopenharmony_ci      javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false));
17251cb0ef41Sopenharmony_ci  Node* check_no_extension =
17261cb0ef41Sopenharmony_ci      NewNode(simplified()->ReferenceEqual(), extension_slot,
17271cb0ef41Sopenharmony_ci              jsgraph()->UndefinedConstant());
17281cb0ef41Sopenharmony_ci  NewBranch(check_no_extension);
17291cb0ef41Sopenharmony_ci  {
17301cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
17311cb0ef41Sopenharmony_ci    NewIfFalse();
17321cb0ef41Sopenharmony_ci    // If there is an extension, merge into the slow path.
17331cb0ef41Sopenharmony_ci    if (slow_environment == nullptr) {
17341cb0ef41Sopenharmony_ci      slow_environment = environment();
17351cb0ef41Sopenharmony_ci      NewMerge();
17361cb0ef41Sopenharmony_ci    } else {
17371cb0ef41Sopenharmony_ci      slow_environment->Merge(environment(),
17381cb0ef41Sopenharmony_ci                              bytecode_analysis().GetInLivenessFor(
17391cb0ef41Sopenharmony_ci                                  bytecode_iterator().current_offset()));
17401cb0ef41Sopenharmony_ci    }
17411cb0ef41Sopenharmony_ci  }
17421cb0ef41Sopenharmony_ci  NewIfTrue();
17431cb0ef41Sopenharmony_ci  // Do nothing on if there is no extension, eventually falling through to
17441cb0ef41Sopenharmony_ci  // the fast path.
17451cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(slow_environment);
17461cb0ef41Sopenharmony_ci  return slow_environment;
17471cb0ef41Sopenharmony_ci}
17481cb0ef41Sopenharmony_ci
17491cb0ef41Sopenharmony_cibase::Optional<ScopeInfoRef> BytecodeGraphBuilder::TryGetScopeInfo() {
17501cb0ef41Sopenharmony_ci  Node* context = environment()->Context();
17511cb0ef41Sopenharmony_ci  switch (context->opcode()) {
17521cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateFunctionContext:
17531cb0ef41Sopenharmony_ci      return CreateFunctionContextParametersOf(context->op())
17541cb0ef41Sopenharmony_ci          .scope_info(broker());
17551cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateBlockContext:
17561cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateCatchContext:
17571cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateWithContext:
17581cb0ef41Sopenharmony_ci      return ScopeInfoOf(broker(), context->op());
17591cb0ef41Sopenharmony_ci    case IrOpcode::kParameter: {
17601cb0ef41Sopenharmony_ci      ScopeInfoRef scope_info = shared_info_.scope_info();
17611cb0ef41Sopenharmony_ci      if (scope_info.HasOuterScopeInfo()) {
17621cb0ef41Sopenharmony_ci        scope_info = scope_info.OuterScopeInfo();
17631cb0ef41Sopenharmony_ci      }
17641cb0ef41Sopenharmony_ci      return scope_info;
17651cb0ef41Sopenharmony_ci    }
17661cb0ef41Sopenharmony_ci    default:
17671cb0ef41Sopenharmony_ci      return base::nullopt;
17681cb0ef41Sopenharmony_ci  }
17691cb0ef41Sopenharmony_ci}
17701cb0ef41Sopenharmony_ci
17711cb0ef41Sopenharmony_ciBytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
17721cb0ef41Sopenharmony_ci    uint32_t depth) {
17731cb0ef41Sopenharmony_ci  base::Optional<ScopeInfoRef> maybe_scope_info = TryGetScopeInfo();
17741cb0ef41Sopenharmony_ci  if (!maybe_scope_info.has_value()) {
17751cb0ef41Sopenharmony_ci    return CheckContextExtensionsSlowPath(depth);
17761cb0ef41Sopenharmony_ci  }
17771cb0ef41Sopenharmony_ci
17781cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = maybe_scope_info.value();
17791cb0ef41Sopenharmony_ci  // We only need to check up to the last-but-one depth, because an eval
17801cb0ef41Sopenharmony_ci  // in the same scope as the variable itself has no way of shadowing it.
17811cb0ef41Sopenharmony_ci  Environment* slow_environment = nullptr;
17821cb0ef41Sopenharmony_ci  for (uint32_t d = 0; d < depth; d++) {
17831cb0ef41Sopenharmony_ci    if (scope_info.HasContextExtensionSlot()) {
17841cb0ef41Sopenharmony_ci      slow_environment = CheckContextExtensionAtDepth(slow_environment, d);
17851cb0ef41Sopenharmony_ci    }
17861cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(!scope_info.HasOuterScopeInfo(), d + 1 == depth);
17871cb0ef41Sopenharmony_ci    if (scope_info.HasOuterScopeInfo()) {
17881cb0ef41Sopenharmony_ci      scope_info = scope_info.OuterScopeInfo();
17891cb0ef41Sopenharmony_ci    }
17901cb0ef41Sopenharmony_ci  }
17911cb0ef41Sopenharmony_ci
17921cb0ef41Sopenharmony_ci  // The depth can be zero, in which case no slow-path checks are built, and
17931cb0ef41Sopenharmony_ci  // the slow path environment can be null.
17941cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(slow_environment == nullptr, depth == 0);
17951cb0ef41Sopenharmony_ci  return slow_environment;
17961cb0ef41Sopenharmony_ci}
17971cb0ef41Sopenharmony_ci
17981cb0ef41Sopenharmony_ciBytecodeGraphBuilder::Environment*
17991cb0ef41Sopenharmony_ciBytecodeGraphBuilder::CheckContextExtensionsSlowPath(uint32_t depth) {
18001cb0ef41Sopenharmony_ci  // Output environment where the context has an extension
18011cb0ef41Sopenharmony_ci  Environment* slow_environment = nullptr;
18021cb0ef41Sopenharmony_ci
18031cb0ef41Sopenharmony_ci  // We only need to check up to the last-but-one depth, because an eval
18041cb0ef41Sopenharmony_ci  // in the same scope as the variable itself has no way of shadowing it.
18051cb0ef41Sopenharmony_ci  for (uint32_t d = 0; d < depth; d++) {
18061cb0ef41Sopenharmony_ci    Node* has_extension = NewNode(javascript()->HasContextExtension(d));
18071cb0ef41Sopenharmony_ci
18081cb0ef41Sopenharmony_ci    Environment* undefined_extension_env;
18091cb0ef41Sopenharmony_ci    NewBranch(has_extension);
18101cb0ef41Sopenharmony_ci    {
18111cb0ef41Sopenharmony_ci      SubEnvironment sub_environment(this);
18121cb0ef41Sopenharmony_ci      NewIfTrue();
18131cb0ef41Sopenharmony_ci      slow_environment = CheckContextExtensionAtDepth(slow_environment, d);
18141cb0ef41Sopenharmony_ci      undefined_extension_env = environment();
18151cb0ef41Sopenharmony_ci    }
18161cb0ef41Sopenharmony_ci    NewIfFalse();
18171cb0ef41Sopenharmony_ci    environment()->Merge(undefined_extension_env,
18181cb0ef41Sopenharmony_ci                         bytecode_analysis().GetInLivenessFor(
18191cb0ef41Sopenharmony_ci                             bytecode_iterator().current_offset()));
18201cb0ef41Sopenharmony_ci    mark_as_needing_eager_checkpoint(true);
18211cb0ef41Sopenharmony_ci    // Do nothing on if there is no extension, eventually falling through to
18221cb0ef41Sopenharmony_ci    // the fast path.
18231cb0ef41Sopenharmony_ci  }
18241cb0ef41Sopenharmony_ci
18251cb0ef41Sopenharmony_ci  // The depth can be zero, in which case no slow-path checks are built, and
18261cb0ef41Sopenharmony_ci  // the slow path environment can be null.
18271cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(slow_environment == nullptr, depth == 0);
18281cb0ef41Sopenharmony_ci  return slow_environment;
18291cb0ef41Sopenharmony_ci}
18301cb0ef41Sopenharmony_ci
18311cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
18321cb0ef41Sopenharmony_ci  uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
18331cb0ef41Sopenharmony_ci
18341cb0ef41Sopenharmony_ci  // Check if any context in the depth has an extension.
18351cb0ef41Sopenharmony_ci  Environment* slow_environment = CheckContextExtensions(depth);
18361cb0ef41Sopenharmony_ci
18371cb0ef41Sopenharmony_ci  // Fast path, do a context load.
18381cb0ef41Sopenharmony_ci  {
18391cb0ef41Sopenharmony_ci    uint32_t slot_index = bytecode_iterator().GetIndexOperand(1);
18401cb0ef41Sopenharmony_ci
18411cb0ef41Sopenharmony_ci    const Operator* op = javascript()->LoadContext(depth, slot_index, false);
18421cb0ef41Sopenharmony_ci    environment()->BindAccumulator(NewNode(op));
18431cb0ef41Sopenharmony_ci  }
18441cb0ef41Sopenharmony_ci
18451cb0ef41Sopenharmony_ci  // Only build the slow path if there were any slow-path checks.
18461cb0ef41Sopenharmony_ci  if (slow_environment != nullptr) {
18471cb0ef41Sopenharmony_ci    // Add a merge to the fast environment.
18481cb0ef41Sopenharmony_ci    NewMerge();
18491cb0ef41Sopenharmony_ci    Environment* fast_environment = environment();
18501cb0ef41Sopenharmony_ci
18511cb0ef41Sopenharmony_ci    // Slow path, do a runtime load lookup.
18521cb0ef41Sopenharmony_ci    set_environment(slow_environment);
18531cb0ef41Sopenharmony_ci    {
18541cb0ef41Sopenharmony_ci      Node* name = jsgraph()->Constant(MakeRefForConstantForIndexOperand(0));
18551cb0ef41Sopenharmony_ci
18561cb0ef41Sopenharmony_ci      const Operator* op =
18571cb0ef41Sopenharmony_ci          javascript()->CallRuntime(typeof_mode == TypeofMode::kNotInside
18581cb0ef41Sopenharmony_ci                                        ? Runtime::kLoadLookupSlot
18591cb0ef41Sopenharmony_ci                                        : Runtime::kLoadLookupSlotInsideTypeof);
18601cb0ef41Sopenharmony_ci      Node* value = NewNode(op, name);
18611cb0ef41Sopenharmony_ci      environment()->BindAccumulator(value, Environment::kAttachFrameState);
18621cb0ef41Sopenharmony_ci    }
18631cb0ef41Sopenharmony_ci
18641cb0ef41Sopenharmony_ci    fast_environment->Merge(environment(),
18651cb0ef41Sopenharmony_ci                            bytecode_analysis().GetOutLivenessFor(
18661cb0ef41Sopenharmony_ci                                bytecode_iterator().current_offset()));
18671cb0ef41Sopenharmony_ci    set_environment(fast_environment);
18681cb0ef41Sopenharmony_ci    mark_as_needing_eager_checkpoint(true);
18691cb0ef41Sopenharmony_ci  }
18701cb0ef41Sopenharmony_ci}
18711cb0ef41Sopenharmony_ci
18721cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaLookupContextSlot() {
18731cb0ef41Sopenharmony_ci  BuildLdaLookupContextSlot(TypeofMode::kNotInside);
18741cb0ef41Sopenharmony_ci}
18751cb0ef41Sopenharmony_ci
18761cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() {
18771cb0ef41Sopenharmony_ci  BuildLdaLookupContextSlot(TypeofMode::kInside);
18781cb0ef41Sopenharmony_ci}
18791cb0ef41Sopenharmony_ci
18801cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
18811cb0ef41Sopenharmony_ci  uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
18821cb0ef41Sopenharmony_ci
18831cb0ef41Sopenharmony_ci  // Check if any context in the depth has an extension.
18841cb0ef41Sopenharmony_ci  Environment* slow_environment = CheckContextExtensions(depth);
18851cb0ef41Sopenharmony_ci
18861cb0ef41Sopenharmony_ci  // Fast path, do a global load.
18871cb0ef41Sopenharmony_ci  {
18881cb0ef41Sopenharmony_ci    PrepareEagerCheckpoint();
18891cb0ef41Sopenharmony_ci    NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
18901cb0ef41Sopenharmony_ci    uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
18911cb0ef41Sopenharmony_ci    Node* node = BuildLoadGlobal(name, feedback_slot_index, typeof_mode);
18921cb0ef41Sopenharmony_ci    environment()->BindAccumulator(node, Environment::kAttachFrameState);
18931cb0ef41Sopenharmony_ci  }
18941cb0ef41Sopenharmony_ci
18951cb0ef41Sopenharmony_ci  // Only build the slow path if there were any slow-path checks.
18961cb0ef41Sopenharmony_ci  if (slow_environment != nullptr) {
18971cb0ef41Sopenharmony_ci    // Add a merge to the fast environment.
18981cb0ef41Sopenharmony_ci    NewMerge();
18991cb0ef41Sopenharmony_ci    Environment* fast_environment = environment();
19001cb0ef41Sopenharmony_ci
19011cb0ef41Sopenharmony_ci    // Slow path, do a runtime load lookup.
19021cb0ef41Sopenharmony_ci    set_environment(slow_environment);
19031cb0ef41Sopenharmony_ci    {
19041cb0ef41Sopenharmony_ci      Node* name =
19051cb0ef41Sopenharmony_ci          jsgraph()->Constant(MakeRefForConstantForIndexOperand<Name>(0));
19061cb0ef41Sopenharmony_ci
19071cb0ef41Sopenharmony_ci      const Operator* op =
19081cb0ef41Sopenharmony_ci          javascript()->CallRuntime(typeof_mode == TypeofMode::kNotInside
19091cb0ef41Sopenharmony_ci                                        ? Runtime::kLoadLookupSlot
19101cb0ef41Sopenharmony_ci                                        : Runtime::kLoadLookupSlotInsideTypeof);
19111cb0ef41Sopenharmony_ci      Node* value = NewNode(op, name);
19121cb0ef41Sopenharmony_ci      environment()->BindAccumulator(value, Environment::kAttachFrameState);
19131cb0ef41Sopenharmony_ci    }
19141cb0ef41Sopenharmony_ci
19151cb0ef41Sopenharmony_ci    fast_environment->Merge(environment(),
19161cb0ef41Sopenharmony_ci                            bytecode_analysis().GetOutLivenessFor(
19171cb0ef41Sopenharmony_ci                                bytecode_iterator().current_offset()));
19181cb0ef41Sopenharmony_ci    set_environment(fast_environment);
19191cb0ef41Sopenharmony_ci    mark_as_needing_eager_checkpoint(true);
19201cb0ef41Sopenharmony_ci  }
19211cb0ef41Sopenharmony_ci}
19221cb0ef41Sopenharmony_ci
19231cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() {
19241cb0ef41Sopenharmony_ci  BuildLdaLookupGlobalSlot(TypeofMode::kNotInside);
19251cb0ef41Sopenharmony_ci}
19261cb0ef41Sopenharmony_ci
19271cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
19281cb0ef41Sopenharmony_ci  BuildLdaLookupGlobalSlot(TypeofMode::kInside);
19291cb0ef41Sopenharmony_ci}
19301cb0ef41Sopenharmony_ci
19311cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitStaLookupSlot() {
19321cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
19331cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
19341cb0ef41Sopenharmony_ci  Node* name = jsgraph()->Constant(MakeRefForConstantForIndexOperand(0));
19351cb0ef41Sopenharmony_ci  int bytecode_flags = bytecode_iterator().GetFlagOperand(1);
19361cb0ef41Sopenharmony_ci  LanguageMode language_mode = static_cast<LanguageMode>(
19371cb0ef41Sopenharmony_ci      interpreter::StoreLookupSlotFlags::LanguageModeBit::decode(
19381cb0ef41Sopenharmony_ci          bytecode_flags));
19391cb0ef41Sopenharmony_ci  LookupHoistingMode lookup_hoisting_mode = static_cast<LookupHoistingMode>(
19401cb0ef41Sopenharmony_ci      interpreter::StoreLookupSlotFlags::LookupHoistingModeBit::decode(
19411cb0ef41Sopenharmony_ci          bytecode_flags));
19421cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy,
19431cb0ef41Sopenharmony_ci                 is_sloppy(language_mode));
19441cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CallRuntime(
19451cb0ef41Sopenharmony_ci      is_strict(language_mode)
19461cb0ef41Sopenharmony_ci          ? Runtime::kStoreLookupSlot_Strict
19471cb0ef41Sopenharmony_ci          : lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy
19481cb0ef41Sopenharmony_ci                ? Runtime::kStoreLookupSlot_SloppyHoisting
19491cb0ef41Sopenharmony_ci                : Runtime::kStoreLookupSlot_Sloppy);
19501cb0ef41Sopenharmony_ci  Node* store = NewNode(op, name, value);
19511cb0ef41Sopenharmony_ci  environment()->BindAccumulator(store, Environment::kAttachFrameState);
19521cb0ef41Sopenharmony_ci}
19531cb0ef41Sopenharmony_ci
19541cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitGetNamedProperty() {
19551cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
19561cb0ef41Sopenharmony_ci  Node* object =
19571cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
19581cb0ef41Sopenharmony_ci  NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
19591cb0ef41Sopenharmony_ci  FeedbackSource feedback =
19601cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
19611cb0ef41Sopenharmony_ci  const Operator* op = javascript()->LoadNamed(name, feedback);
19621cb0ef41Sopenharmony_ci
19631cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
19641cb0ef41Sopenharmony_ci      TryBuildSimplifiedLoadNamed(op, feedback.slot);
19651cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
19661cb0ef41Sopenharmony_ci
19671cb0ef41Sopenharmony_ci  Node* node = nullptr;
19681cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
19691cb0ef41Sopenharmony_ci    node = lowering.value();
19701cb0ef41Sopenharmony_ci  } else {
19711cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
19721cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
19731cb0ef41Sopenharmony_ci    node = NewNode(op, object, feedback_vector_node());
19741cb0ef41Sopenharmony_ci  }
19751cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
19761cb0ef41Sopenharmony_ci}
19771cb0ef41Sopenharmony_ci
19781cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitGetNamedPropertyFromSuper() {
19791cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
19801cb0ef41Sopenharmony_ci  Node* receiver =
19811cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
19821cb0ef41Sopenharmony_ci  Node* home_object = environment()->LookupAccumulator();
19831cb0ef41Sopenharmony_ci  NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
19841cb0ef41Sopenharmony_ci
19851cb0ef41Sopenharmony_ci  FeedbackSource feedback =
19861cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
19871cb0ef41Sopenharmony_ci  const Operator* op = javascript()->LoadNamedFromSuper(name, feedback);
19881cb0ef41Sopenharmony_ci
19891cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
19901cb0ef41Sopenharmony_ci      TryBuildSimplifiedLoadNamed(op, feedback.slot);
19911cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
19921cb0ef41Sopenharmony_ci
19931cb0ef41Sopenharmony_ci  Node* node = nullptr;
19941cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
19951cb0ef41Sopenharmony_ci    node = lowering.value();
19961cb0ef41Sopenharmony_ci  } else {
19971cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
19981cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
19991cb0ef41Sopenharmony_ci    node = NewNode(op, receiver, home_object, feedback_vector_node());
20001cb0ef41Sopenharmony_ci  }
20011cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
20021cb0ef41Sopenharmony_ci}
20031cb0ef41Sopenharmony_ci
20041cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitGetKeyedProperty() {
20051cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
20061cb0ef41Sopenharmony_ci  Node* key = environment()->LookupAccumulator();
20071cb0ef41Sopenharmony_ci  Node* object =
20081cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
20091cb0ef41Sopenharmony_ci  FeedbackSource feedback =
20101cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
20111cb0ef41Sopenharmony_ci  const Operator* op = javascript()->LoadProperty(feedback);
20121cb0ef41Sopenharmony_ci
20131cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
20141cb0ef41Sopenharmony_ci      TryBuildSimplifiedLoadKeyed(op, object, key, feedback.slot);
20151cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
20161cb0ef41Sopenharmony_ci
20171cb0ef41Sopenharmony_ci  Node* node = nullptr;
20181cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
20191cb0ef41Sopenharmony_ci    node = lowering.value();
20201cb0ef41Sopenharmony_ci  } else {
20211cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
20221cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSLoadPropertyNode::ObjectIndex() == 0);
20231cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSLoadPropertyNode::KeyIndex() == 1);
20241cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSLoadPropertyNode::FeedbackVectorIndex() == 2);
20251cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
20261cb0ef41Sopenharmony_ci    node = NewNode(op, object, key, feedback_vector_node());
20271cb0ef41Sopenharmony_ci  }
20281cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
20291cb0ef41Sopenharmony_ci}
20301cb0ef41Sopenharmony_ci
20311cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildNamedStore(NamedStoreMode store_mode) {
20321cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
20331cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
20341cb0ef41Sopenharmony_ci  Node* object =
20351cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
20361cb0ef41Sopenharmony_ci  NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
20371cb0ef41Sopenharmony_ci  FeedbackSource feedback =
20381cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
20391cb0ef41Sopenharmony_ci
20401cb0ef41Sopenharmony_ci  const Operator* op;
20411cb0ef41Sopenharmony_ci  if (store_mode == NamedStoreMode::kDefineOwn) {
20421cb0ef41Sopenharmony_ci    DCHECK_EQ(FeedbackSlotKind::kDefineNamedOwn,
20431cb0ef41Sopenharmony_ci              broker()->GetFeedbackSlotKind(feedback));
20441cb0ef41Sopenharmony_ci
20451cb0ef41Sopenharmony_ci    op = javascript()->DefineNamedOwnProperty(name, feedback);
20461cb0ef41Sopenharmony_ci  } else {
20471cb0ef41Sopenharmony_ci    DCHECK_EQ(NamedStoreMode::kSet, store_mode);
20481cb0ef41Sopenharmony_ci    LanguageMode language_mode =
20491cb0ef41Sopenharmony_ci        GetLanguageModeFromSlotKind(broker()->GetFeedbackSlotKind(feedback));
20501cb0ef41Sopenharmony_ci    op = javascript()->SetNamedProperty(language_mode, name, feedback);
20511cb0ef41Sopenharmony_ci  }
20521cb0ef41Sopenharmony_ci
20531cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
20541cb0ef41Sopenharmony_ci      TryBuildSimplifiedStoreNamed(op, object, value, feedback.slot);
20551cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
20561cb0ef41Sopenharmony_ci
20571cb0ef41Sopenharmony_ci  Node* node = nullptr;
20581cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
20591cb0ef41Sopenharmony_ci    node = lowering.value();
20601cb0ef41Sopenharmony_ci  } else {
20611cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
20621cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
20631cb0ef41Sopenharmony_ci    node = NewNode(op, object, value, feedback_vector_node());
20641cb0ef41Sopenharmony_ci  }
20651cb0ef41Sopenharmony_ci  environment()->RecordAfterState(node, Environment::kAttachFrameState);
20661cb0ef41Sopenharmony_ci}
20671cb0ef41Sopenharmony_ci
20681cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSetNamedProperty() {
20691cb0ef41Sopenharmony_ci  BuildNamedStore(NamedStoreMode::kSet);
20701cb0ef41Sopenharmony_ci}
20711cb0ef41Sopenharmony_ci
20721cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDefineNamedOwnProperty() {
20731cb0ef41Sopenharmony_ci  BuildNamedStore(NamedStoreMode::kDefineOwn);
20741cb0ef41Sopenharmony_ci}
20751cb0ef41Sopenharmony_ci
20761cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSetKeyedProperty() {
20771cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
20781cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
20791cb0ef41Sopenharmony_ci  Node* object =
20801cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
20811cb0ef41Sopenharmony_ci  Node* key =
20821cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
20831cb0ef41Sopenharmony_ci  FeedbackSource source =
20841cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
20851cb0ef41Sopenharmony_ci  LanguageMode language_mode =
20861cb0ef41Sopenharmony_ci      GetLanguageModeFromSlotKind(broker()->GetFeedbackSlotKind(source));
20871cb0ef41Sopenharmony_ci  const Operator* op = javascript()->SetKeyedProperty(language_mode, source);
20881cb0ef41Sopenharmony_ci
20891cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
20901cb0ef41Sopenharmony_ci      TryBuildSimplifiedStoreKeyed(op, object, key, value, source.slot);
20911cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
20921cb0ef41Sopenharmony_ci
20931cb0ef41Sopenharmony_ci  Node* node = nullptr;
20941cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
20951cb0ef41Sopenharmony_ci    node = lowering.value();
20961cb0ef41Sopenharmony_ci  } else {
20971cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
20981cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSSetKeyedPropertyNode::ObjectIndex() == 0);
20991cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSSetKeyedPropertyNode::KeyIndex() == 1);
21001cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSSetKeyedPropertyNode::ValueIndex() == 2);
21011cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSSetKeyedPropertyNode::FeedbackVectorIndex() == 3);
21021cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
21031cb0ef41Sopenharmony_ci    node = NewNode(op, object, key, value, feedback_vector_node());
21041cb0ef41Sopenharmony_ci  }
21051cb0ef41Sopenharmony_ci
21061cb0ef41Sopenharmony_ci  environment()->RecordAfterState(node, Environment::kAttachFrameState);
21071cb0ef41Sopenharmony_ci}
21081cb0ef41Sopenharmony_ci
21091cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDefineKeyedOwnProperty() {
21101cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
21111cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
21121cb0ef41Sopenharmony_ci  Node* object =
21131cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
21141cb0ef41Sopenharmony_ci  Node* key =
21151cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
21161cb0ef41Sopenharmony_ci  FeedbackSource source =
21171cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
21181cb0ef41Sopenharmony_ci  LanguageMode language_mode =
21191cb0ef41Sopenharmony_ci      GetLanguageModeFromSlotKind(broker()->GetFeedbackSlotKind(source));
21201cb0ef41Sopenharmony_ci
21211cb0ef41Sopenharmony_ci  const Operator* op =
21221cb0ef41Sopenharmony_ci      javascript()->DefineKeyedOwnProperty(language_mode, source);
21231cb0ef41Sopenharmony_ci
21241cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
21251cb0ef41Sopenharmony_ci      TryBuildSimplifiedStoreKeyed(op, object, key, value, source.slot);
21261cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
21271cb0ef41Sopenharmony_ci
21281cb0ef41Sopenharmony_ci  Node* node = nullptr;
21291cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
21301cb0ef41Sopenharmony_ci    node = lowering.value();
21311cb0ef41Sopenharmony_ci  } else {
21321cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
21331cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSDefineKeyedOwnPropertyNode::ObjectIndex() == 0);
21341cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSDefineKeyedOwnPropertyNode::KeyIndex() == 1);
21351cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSDefineKeyedOwnPropertyNode::ValueIndex() == 2);
21361cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSDefineKeyedOwnPropertyNode::FeedbackVectorIndex() == 3);
21371cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
21381cb0ef41Sopenharmony_ci    node = NewNode(op, object, key, value, feedback_vector_node());
21391cb0ef41Sopenharmony_ci  }
21401cb0ef41Sopenharmony_ci
21411cb0ef41Sopenharmony_ci  environment()->RecordAfterState(node, Environment::kAttachFrameState);
21421cb0ef41Sopenharmony_ci}
21431cb0ef41Sopenharmony_ci
21441cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLdaModuleVariable() {
21451cb0ef41Sopenharmony_ci  int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
21461cb0ef41Sopenharmony_ci  uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
21471cb0ef41Sopenharmony_ci  Node* module =
21481cb0ef41Sopenharmony_ci      NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
21491cb0ef41Sopenharmony_ci  Node* value = NewNode(javascript()->LoadModule(cell_index), module);
21501cb0ef41Sopenharmony_ci  environment()->BindAccumulator(value);
21511cb0ef41Sopenharmony_ci}
21521cb0ef41Sopenharmony_ci
21531cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitStaModuleVariable() {
21541cb0ef41Sopenharmony_ci  int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
21551cb0ef41Sopenharmony_ci  uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
21561cb0ef41Sopenharmony_ci  Node* module =
21571cb0ef41Sopenharmony_ci      NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
21581cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
21591cb0ef41Sopenharmony_ci  NewNode(javascript()->StoreModule(cell_index), module, value);
21601cb0ef41Sopenharmony_ci}
21611cb0ef41Sopenharmony_ci
21621cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitPushContext() {
21631cb0ef41Sopenharmony_ci  Node* new_context = environment()->LookupAccumulator();
21641cb0ef41Sopenharmony_ci  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
21651cb0ef41Sopenharmony_ci                              environment()->Context());
21661cb0ef41Sopenharmony_ci  environment()->SetContext(new_context);
21671cb0ef41Sopenharmony_ci}
21681cb0ef41Sopenharmony_ci
21691cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitPopContext() {
21701cb0ef41Sopenharmony_ci  Node* context =
21711cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
21721cb0ef41Sopenharmony_ci  environment()->SetContext(context);
21731cb0ef41Sopenharmony_ci}
21741cb0ef41Sopenharmony_ci
21751cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateClosure() {
21761cb0ef41Sopenharmony_ci  SharedFunctionInfoRef shared_info =
21771cb0ef41Sopenharmony_ci      MakeRefForConstantForIndexOperand<SharedFunctionInfo>(0);
21781cb0ef41Sopenharmony_ci  AllocationType allocation =
21791cb0ef41Sopenharmony_ci      interpreter::CreateClosureFlags::PretenuredBit::decode(
21801cb0ef41Sopenharmony_ci          bytecode_iterator().GetFlagOperand(2))
21811cb0ef41Sopenharmony_ci          ? AllocationType::kOld
21821cb0ef41Sopenharmony_ci          : AllocationType::kYoung;
21831cb0ef41Sopenharmony_ci  CodeTRef compile_lazy =
21841cb0ef41Sopenharmony_ci      MakeRef(broker(), *BUILTIN_CODE(jsgraph()->isolate(), CompileLazy));
21851cb0ef41Sopenharmony_ci  const Operator* op =
21861cb0ef41Sopenharmony_ci      javascript()->CreateClosure(shared_info, compile_lazy, allocation);
21871cb0ef41Sopenharmony_ci  Node* closure = NewNode(
21881cb0ef41Sopenharmony_ci      op, BuildLoadFeedbackCell(bytecode_iterator().GetIndexOperand(1)));
21891cb0ef41Sopenharmony_ci  environment()->BindAccumulator(closure);
21901cb0ef41Sopenharmony_ci}
21911cb0ef41Sopenharmony_ci
21921cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateBlockContext() {
21931cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
21941cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CreateBlockContext(scope_info);
21951cb0ef41Sopenharmony_ci  Node* context = NewNode(op);
21961cb0ef41Sopenharmony_ci  environment()->BindAccumulator(context);
21971cb0ef41Sopenharmony_ci}
21981cb0ef41Sopenharmony_ci
21991cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateFunctionContext() {
22001cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
22011cb0ef41Sopenharmony_ci  uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
22021cb0ef41Sopenharmony_ci  const Operator* op =
22031cb0ef41Sopenharmony_ci      javascript()->CreateFunctionContext(scope_info, slots, FUNCTION_SCOPE);
22041cb0ef41Sopenharmony_ci  Node* context = NewNode(op);
22051cb0ef41Sopenharmony_ci  environment()->BindAccumulator(context);
22061cb0ef41Sopenharmony_ci}
22071cb0ef41Sopenharmony_ci
22081cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateEvalContext() {
22091cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
22101cb0ef41Sopenharmony_ci  uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
22111cb0ef41Sopenharmony_ci  const Operator* op =
22121cb0ef41Sopenharmony_ci      javascript()->CreateFunctionContext(scope_info, slots, EVAL_SCOPE);
22131cb0ef41Sopenharmony_ci  Node* context = NewNode(op);
22141cb0ef41Sopenharmony_ci  environment()->BindAccumulator(context);
22151cb0ef41Sopenharmony_ci}
22161cb0ef41Sopenharmony_ci
22171cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateCatchContext() {
22181cb0ef41Sopenharmony_ci  interpreter::Register reg = bytecode_iterator().GetRegisterOperand(0);
22191cb0ef41Sopenharmony_ci  Node* exception = environment()->LookupRegister(reg);
22201cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(1);
22211cb0ef41Sopenharmony_ci
22221cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CreateCatchContext(scope_info);
22231cb0ef41Sopenharmony_ci  Node* context = NewNode(op, exception);
22241cb0ef41Sopenharmony_ci  environment()->BindAccumulator(context);
22251cb0ef41Sopenharmony_ci}
22261cb0ef41Sopenharmony_ci
22271cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateWithContext() {
22281cb0ef41Sopenharmony_ci  Node* object =
22291cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
22301cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(1);
22311cb0ef41Sopenharmony_ci
22321cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CreateWithContext(scope_info);
22331cb0ef41Sopenharmony_ci  Node* context = NewNode(op, object);
22341cb0ef41Sopenharmony_ci  environment()->BindAccumulator(context);
22351cb0ef41Sopenharmony_ci}
22361cb0ef41Sopenharmony_ci
22371cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
22381cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CreateArguments(type);
22391cb0ef41Sopenharmony_ci  Node* object = NewNode(op, GetFunctionClosure());
22401cb0ef41Sopenharmony_ci  environment()->BindAccumulator(object, Environment::kAttachFrameState);
22411cb0ef41Sopenharmony_ci}
22421cb0ef41Sopenharmony_ci
22431cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateMappedArguments() {
22441cb0ef41Sopenharmony_ci  BuildCreateArguments(CreateArgumentsType::kMappedArguments);
22451cb0ef41Sopenharmony_ci}
22461cb0ef41Sopenharmony_ci
22471cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
22481cb0ef41Sopenharmony_ci  BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
22491cb0ef41Sopenharmony_ci}
22501cb0ef41Sopenharmony_ci
22511cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateRestParameter() {
22521cb0ef41Sopenharmony_ci  BuildCreateArguments(CreateArgumentsType::kRestParameter);
22531cb0ef41Sopenharmony_ci}
22541cb0ef41Sopenharmony_ci
22551cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
22561cb0ef41Sopenharmony_ci  StringRef constant_pattern = MakeRefForConstantForIndexOperand<String>(0);
22571cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(1);
22581cb0ef41Sopenharmony_ci  FeedbackSource pair = CreateFeedbackSource(slot_id);
22591cb0ef41Sopenharmony_ci  int literal_flags = bytecode_iterator().GetFlagOperand(2);
22601cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCreateLiteralRegExpNode::FeedbackVectorIndex() == 0);
22611cb0ef41Sopenharmony_ci  const Operator* op =
22621cb0ef41Sopenharmony_ci      javascript()->CreateLiteralRegExp(constant_pattern, pair, literal_flags);
22631cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
22641cb0ef41Sopenharmony_ci  Node* literal = NewNode(op, feedback_vector_node());
22651cb0ef41Sopenharmony_ci  environment()->BindAccumulator(literal, Environment::kAttachFrameState);
22661cb0ef41Sopenharmony_ci}
22671cb0ef41Sopenharmony_ci
22681cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateArrayLiteral() {
22691cb0ef41Sopenharmony_ci  ArrayBoilerplateDescriptionRef array_boilerplate_description =
22701cb0ef41Sopenharmony_ci      MakeRefForConstantForIndexOperand<ArrayBoilerplateDescription>(0);
22711cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(1);
22721cb0ef41Sopenharmony_ci  FeedbackSource pair = CreateFeedbackSource(slot_id);
22731cb0ef41Sopenharmony_ci  int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
22741cb0ef41Sopenharmony_ci  int literal_flags =
22751cb0ef41Sopenharmony_ci      interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
22761cb0ef41Sopenharmony_ci  // Disable allocation site mementos. Only unoptimized code will collect
22771cb0ef41Sopenharmony_ci  // feedback about allocation site. Once the code is optimized we expect the
22781cb0ef41Sopenharmony_ci  // data to converge. So, we disable allocation site mementos in optimized
22791cb0ef41Sopenharmony_ci  // code. We can revisit this when we have data to the contrary.
22801cb0ef41Sopenharmony_ci  literal_flags |= ArrayLiteral::kDisableMementos;
22811cb0ef41Sopenharmony_ci  int number_of_elements =
22821cb0ef41Sopenharmony_ci      array_boilerplate_description.constants_elements_length();
22831cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCreateLiteralArrayNode::FeedbackVectorIndex() == 0);
22841cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CreateLiteralArray(
22851cb0ef41Sopenharmony_ci      array_boilerplate_description, pair, literal_flags, number_of_elements);
22861cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
22871cb0ef41Sopenharmony_ci  Node* literal = NewNode(op, feedback_vector_node());
22881cb0ef41Sopenharmony_ci  environment()->BindAccumulator(literal, Environment::kAttachFrameState);
22891cb0ef41Sopenharmony_ci}
22901cb0ef41Sopenharmony_ci
22911cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
22921cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(0);
22931cb0ef41Sopenharmony_ci  FeedbackSource pair = CreateFeedbackSource(slot_id);
22941cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CreateEmptyLiteralArray(pair);
22951cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
22961cb0ef41Sopenharmony_ci  Node* literal = NewNode(op, feedback_vector_node());
22971cb0ef41Sopenharmony_ci  environment()->BindAccumulator(literal);
22981cb0ef41Sopenharmony_ci}
22991cb0ef41Sopenharmony_ci
23001cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateArrayFromIterable() {
23011cb0ef41Sopenharmony_ci  Node* iterable = NewNode(javascript()->CreateArrayFromIterable(),
23021cb0ef41Sopenharmony_ci                           environment()->LookupAccumulator());
23031cb0ef41Sopenharmony_ci  environment()->BindAccumulator(iterable, Environment::kAttachFrameState);
23041cb0ef41Sopenharmony_ci}
23051cb0ef41Sopenharmony_ci
23061cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateObjectLiteral() {
23071cb0ef41Sopenharmony_ci  ObjectBoilerplateDescriptionRef constant_properties =
23081cb0ef41Sopenharmony_ci      MakeRefForConstantForIndexOperand<ObjectBoilerplateDescription>(0);
23091cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(1);
23101cb0ef41Sopenharmony_ci  FeedbackSource pair = CreateFeedbackSource(slot_id);
23111cb0ef41Sopenharmony_ci  int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
23121cb0ef41Sopenharmony_ci  int literal_flags =
23131cb0ef41Sopenharmony_ci      interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
23141cb0ef41Sopenharmony_ci  int number_of_properties = constant_properties.size();
23151cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCreateLiteralObjectNode::FeedbackVectorIndex() == 0);
23161cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CreateLiteralObject(
23171cb0ef41Sopenharmony_ci      constant_properties, pair, literal_flags, number_of_properties);
23181cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
23191cb0ef41Sopenharmony_ci  Node* literal = NewNode(op, feedback_vector_node());
23201cb0ef41Sopenharmony_ci  environment()->BindAccumulator(literal, Environment::kAttachFrameState);
23211cb0ef41Sopenharmony_ci}
23221cb0ef41Sopenharmony_ci
23231cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCreateEmptyObjectLiteral() {
23241cb0ef41Sopenharmony_ci  Node* literal = NewNode(javascript()->CreateEmptyLiteralObject());
23251cb0ef41Sopenharmony_ci  environment()->BindAccumulator(literal);
23261cb0ef41Sopenharmony_ci}
23271cb0ef41Sopenharmony_ci
23281cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCloneObject() {
23291cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
23301cb0ef41Sopenharmony_ci  Node* source =
23311cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
23321cb0ef41Sopenharmony_ci  int flags = bytecode_iterator().GetFlagOperand(1);
23331cb0ef41Sopenharmony_ci  int slot = bytecode_iterator().GetIndexOperand(2);
23341cb0ef41Sopenharmony_ci  const Operator* op =
23351cb0ef41Sopenharmony_ci      javascript()->CloneObject(CreateFeedbackSource(slot), flags);
23361cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCloneObjectNode::SourceIndex() == 0);
23371cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCloneObjectNode::FeedbackVectorIndex() == 1);
23381cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
23391cb0ef41Sopenharmony_ci  Node* value = NewNode(op, source, feedback_vector_node());
23401cb0ef41Sopenharmony_ci  environment()->BindAccumulator(value, Environment::kAttachFrameState);
23411cb0ef41Sopenharmony_ci}
23421cb0ef41Sopenharmony_ci
23431cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitGetTemplateObject() {
23441cb0ef41Sopenharmony_ci  FeedbackSource source =
23451cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
23461cb0ef41Sopenharmony_ci  TemplateObjectDescriptionRef description =
23471cb0ef41Sopenharmony_ci      MakeRefForConstantForIndexOperand<TemplateObjectDescription>(0);
23481cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSGetTemplateObjectNode::FeedbackVectorIndex() == 0);
23491cb0ef41Sopenharmony_ci  const Operator* op =
23501cb0ef41Sopenharmony_ci      javascript()->GetTemplateObject(description, shared_info(), source);
23511cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
23521cb0ef41Sopenharmony_ci  Node* template_object = NewNode(op, feedback_vector_node());
23531cb0ef41Sopenharmony_ci  environment()->BindAccumulator(template_object);
23541cb0ef41Sopenharmony_ci}
23551cb0ef41Sopenharmony_ci
23561cb0ef41Sopenharmony_ciNode* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
23571cb0ef41Sopenharmony_ci    Node* callee, Node* receiver, interpreter::Register first_arg,
23581cb0ef41Sopenharmony_ci    int arg_count) {
23591cb0ef41Sopenharmony_ci  const int arity = JSCallNode::ArityForArgc(arg_count);
23601cb0ef41Sopenharmony_ci  Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
23611cb0ef41Sopenharmony_ci  int cursor = 0;
23621cb0ef41Sopenharmony_ci
23631cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCallNode::TargetIndex() == 0);
23641cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCallNode::ReceiverIndex() == 1);
23651cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCallNode::FirstArgumentIndex() == 2);
23661cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSCallNode::kFeedbackVectorIsLastInput);
23671cb0ef41Sopenharmony_ci
23681cb0ef41Sopenharmony_ci  all[cursor++] = callee;
23691cb0ef41Sopenharmony_ci  all[cursor++] = receiver;
23701cb0ef41Sopenharmony_ci
23711cb0ef41Sopenharmony_ci  // The function arguments are in consecutive registers.
23721cb0ef41Sopenharmony_ci  const int arg_base = first_arg.index();
23731cb0ef41Sopenharmony_ci  for (int i = 0; i < arg_count; ++i) {
23741cb0ef41Sopenharmony_ci    all[cursor++] =
23751cb0ef41Sopenharmony_ci        environment()->LookupRegister(interpreter::Register(arg_base + i));
23761cb0ef41Sopenharmony_ci  }
23771cb0ef41Sopenharmony_ci
23781cb0ef41Sopenharmony_ci  all[cursor++] = feedback_vector_node();
23791cb0ef41Sopenharmony_ci
23801cb0ef41Sopenharmony_ci  DCHECK_EQ(cursor, arity);
23811cb0ef41Sopenharmony_ci  return all;
23821cb0ef41Sopenharmony_ci}
23831cb0ef41Sopenharmony_ci
23841cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildCall(ConvertReceiverMode receiver_mode,
23851cb0ef41Sopenharmony_ci                                     Node* const* args, size_t arg_count,
23861cb0ef41Sopenharmony_ci                                     int slot_id) {
23871cb0ef41Sopenharmony_ci  DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
23881cb0ef41Sopenharmony_ci                bytecode_iterator().current_bytecode()),
23891cb0ef41Sopenharmony_ci            receiver_mode);
23901cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
23911cb0ef41Sopenharmony_ci
23921cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(slot_id);
23931cb0ef41Sopenharmony_ci  CallFrequency frequency = ComputeCallFrequency(slot_id);
23941cb0ef41Sopenharmony_ci  SpeculationMode speculation_mode = GetSpeculationMode(slot_id);
23951cb0ef41Sopenharmony_ci  CallFeedbackRelation call_feedback_relation =
23961cb0ef41Sopenharmony_ci      ComputeCallFeedbackRelation(slot_id);
23971cb0ef41Sopenharmony_ci  const Operator* op =
23981cb0ef41Sopenharmony_ci      javascript()->Call(arg_count, frequency, feedback, receiver_mode,
23991cb0ef41Sopenharmony_ci                         speculation_mode, call_feedback_relation);
24001cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
24011cb0ef41Sopenharmony_ci
24021cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
24031cb0ef41Sopenharmony_ci      op, args, static_cast<int>(arg_count), feedback.slot);
24041cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
24051cb0ef41Sopenharmony_ci
24061cb0ef41Sopenharmony_ci  Node* node = nullptr;
24071cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
24081cb0ef41Sopenharmony_ci    node = lowering.value();
24091cb0ef41Sopenharmony_ci  } else {
24101cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
24111cb0ef41Sopenharmony_ci    node = MakeNode(op, static_cast<int>(arg_count), args);
24121cb0ef41Sopenharmony_ci  }
24131cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
24141cb0ef41Sopenharmony_ci}
24151cb0ef41Sopenharmony_ci
24161cb0ef41Sopenharmony_ciNode* const* BytecodeGraphBuilder::ProcessCallVarArgs(
24171cb0ef41Sopenharmony_ci    ConvertReceiverMode receiver_mode, Node* callee,
24181cb0ef41Sopenharmony_ci    interpreter::Register first_reg, int arg_count) {
24191cb0ef41Sopenharmony_ci  DCHECK_GE(arg_count, 0);
24201cb0ef41Sopenharmony_ci  Node* receiver_node;
24211cb0ef41Sopenharmony_ci  interpreter::Register first_arg;
24221cb0ef41Sopenharmony_ci
24231cb0ef41Sopenharmony_ci  if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
24241cb0ef41Sopenharmony_ci    // The receiver is implicit (and undefined), the arguments are in
24251cb0ef41Sopenharmony_ci    // consecutive registers.
24261cb0ef41Sopenharmony_ci    receiver_node = jsgraph()->UndefinedConstant();
24271cb0ef41Sopenharmony_ci    first_arg = first_reg;
24281cb0ef41Sopenharmony_ci  } else {
24291cb0ef41Sopenharmony_ci    // The receiver is the first register, followed by the arguments in the
24301cb0ef41Sopenharmony_ci    // consecutive registers.
24311cb0ef41Sopenharmony_ci    receiver_node = environment()->LookupRegister(first_reg);
24321cb0ef41Sopenharmony_ci    first_arg = interpreter::Register(first_reg.index() + 1);
24331cb0ef41Sopenharmony_ci  }
24341cb0ef41Sopenharmony_ci
24351cb0ef41Sopenharmony_ci  Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
24361cb0ef41Sopenharmony_ci                                                         first_arg, arg_count);
24371cb0ef41Sopenharmony_ci  return call_args;
24381cb0ef41Sopenharmony_ci}
24391cb0ef41Sopenharmony_ci
24401cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildCallVarArgs(ConvertReceiverMode receiver_mode) {
24411cb0ef41Sopenharmony_ci  DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
24421cb0ef41Sopenharmony_ci                bytecode_iterator().current_bytecode()),
24431cb0ef41Sopenharmony_ci            receiver_mode);
24441cb0ef41Sopenharmony_ci  Node* callee =
24451cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
24461cb0ef41Sopenharmony_ci  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
24471cb0ef41Sopenharmony_ci  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
24481cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(3);
24491cb0ef41Sopenharmony_ci
24501cb0ef41Sopenharmony_ci  int arg_count = receiver_mode == ConvertReceiverMode::kNullOrUndefined
24511cb0ef41Sopenharmony_ci                      ? static_cast<int>(reg_count)
24521cb0ef41Sopenharmony_ci                      : static_cast<int>(reg_count) - 1;
24531cb0ef41Sopenharmony_ci  Node* const* call_args =
24541cb0ef41Sopenharmony_ci      ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count);
24551cb0ef41Sopenharmony_ci  BuildCall(receiver_mode, call_args, JSCallNode::ArityForArgc(arg_count),
24561cb0ef41Sopenharmony_ci            slot_id);
24571cb0ef41Sopenharmony_ci}
24581cb0ef41Sopenharmony_ci
24591cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallAnyReceiver() {
24601cb0ef41Sopenharmony_ci  BuildCallVarArgs(ConvertReceiverMode::kAny);
24611cb0ef41Sopenharmony_ci}
24621cb0ef41Sopenharmony_ci
24631cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallProperty() {
24641cb0ef41Sopenharmony_ci  BuildCallVarArgs(ConvertReceiverMode::kNotNullOrUndefined);
24651cb0ef41Sopenharmony_ci}
24661cb0ef41Sopenharmony_ci
24671cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallProperty0() {
24681cb0ef41Sopenharmony_ci  Node* callee =
24691cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
24701cb0ef41Sopenharmony_ci  Node* receiver =
24711cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
24721cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(2);
24731cb0ef41Sopenharmony_ci  BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
24741cb0ef41Sopenharmony_ci            {callee, receiver, feedback_vector_node()}, slot_id);
24751cb0ef41Sopenharmony_ci}
24761cb0ef41Sopenharmony_ci
24771cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallProperty1() {
24781cb0ef41Sopenharmony_ci  Node* callee =
24791cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
24801cb0ef41Sopenharmony_ci  Node* receiver =
24811cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
24821cb0ef41Sopenharmony_ci  Node* arg0 =
24831cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
24841cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(3);
24851cb0ef41Sopenharmony_ci  BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
24861cb0ef41Sopenharmony_ci            {callee, receiver, arg0, feedback_vector_node()}, slot_id);
24871cb0ef41Sopenharmony_ci}
24881cb0ef41Sopenharmony_ci
24891cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallProperty2() {
24901cb0ef41Sopenharmony_ci  Node* callee =
24911cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
24921cb0ef41Sopenharmony_ci  Node* receiver =
24931cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
24941cb0ef41Sopenharmony_ci  Node* arg0 =
24951cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
24961cb0ef41Sopenharmony_ci  Node* arg1 =
24971cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
24981cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(4);
24991cb0ef41Sopenharmony_ci  BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
25001cb0ef41Sopenharmony_ci            {callee, receiver, arg0, arg1, feedback_vector_node()}, slot_id);
25011cb0ef41Sopenharmony_ci}
25021cb0ef41Sopenharmony_ci
25031cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallUndefinedReceiver() {
25041cb0ef41Sopenharmony_ci  BuildCallVarArgs(ConvertReceiverMode::kNullOrUndefined);
25051cb0ef41Sopenharmony_ci}
25061cb0ef41Sopenharmony_ci
25071cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallUndefinedReceiver0() {
25081cb0ef41Sopenharmony_ci  Node* callee =
25091cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
25101cb0ef41Sopenharmony_ci  Node* receiver = jsgraph()->UndefinedConstant();
25111cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(1);
25121cb0ef41Sopenharmony_ci  BuildCall(ConvertReceiverMode::kNullOrUndefined,
25131cb0ef41Sopenharmony_ci            {callee, receiver, feedback_vector_node()}, slot_id);
25141cb0ef41Sopenharmony_ci}
25151cb0ef41Sopenharmony_ci
25161cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallUndefinedReceiver1() {
25171cb0ef41Sopenharmony_ci  Node* callee =
25181cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
25191cb0ef41Sopenharmony_ci  Node* receiver = jsgraph()->UndefinedConstant();
25201cb0ef41Sopenharmony_ci  Node* arg0 =
25211cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
25221cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(2);
25231cb0ef41Sopenharmony_ci  BuildCall(ConvertReceiverMode::kNullOrUndefined,
25241cb0ef41Sopenharmony_ci            {callee, receiver, arg0, feedback_vector_node()}, slot_id);
25251cb0ef41Sopenharmony_ci}
25261cb0ef41Sopenharmony_ci
25271cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallUndefinedReceiver2() {
25281cb0ef41Sopenharmony_ci  Node* callee =
25291cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
25301cb0ef41Sopenharmony_ci  Node* receiver = jsgraph()->UndefinedConstant();
25311cb0ef41Sopenharmony_ci  Node* arg0 =
25321cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
25331cb0ef41Sopenharmony_ci  Node* arg1 =
25341cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
25351cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(3);
25361cb0ef41Sopenharmony_ci  BuildCall(ConvertReceiverMode::kNullOrUndefined,
25371cb0ef41Sopenharmony_ci            {callee, receiver, arg0, arg1, feedback_vector_node()}, slot_id);
25381cb0ef41Sopenharmony_ci}
25391cb0ef41Sopenharmony_ci
25401cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallWithSpread() {
25411cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
25421cb0ef41Sopenharmony_ci  Node* callee =
25431cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
25441cb0ef41Sopenharmony_ci  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
25451cb0ef41Sopenharmony_ci  Node* receiver_node = environment()->LookupRegister(receiver);
25461cb0ef41Sopenharmony_ci  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
25471cb0ef41Sopenharmony_ci  interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
25481cb0ef41Sopenharmony_ci  int arg_count = static_cast<int>(reg_count) - 1;
25491cb0ef41Sopenharmony_ci  Node* const* args = GetCallArgumentsFromRegisters(callee, receiver_node,
25501cb0ef41Sopenharmony_ci                                                    first_arg, arg_count);
25511cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(3);
25521cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(slot_id);
25531cb0ef41Sopenharmony_ci  CallFrequency frequency = ComputeCallFrequency(slot_id);
25541cb0ef41Sopenharmony_ci  SpeculationMode speculation_mode = GetSpeculationMode(slot_id);
25551cb0ef41Sopenharmony_ci  const Operator* op = javascript()->CallWithSpread(
25561cb0ef41Sopenharmony_ci      JSCallWithSpreadNode::ArityForArgc(arg_count), frequency, feedback,
25571cb0ef41Sopenharmony_ci      speculation_mode);
25581cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
25591cb0ef41Sopenharmony_ci
25601cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
25611cb0ef41Sopenharmony_ci      op, args, static_cast<int>(arg_count), feedback.slot);
25621cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
25631cb0ef41Sopenharmony_ci
25641cb0ef41Sopenharmony_ci  Node* node = nullptr;
25651cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
25661cb0ef41Sopenharmony_ci    node = lowering.value();
25671cb0ef41Sopenharmony_ci  } else {
25681cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
25691cb0ef41Sopenharmony_ci    node = MakeNode(op, JSCallWithSpreadNode::ArityForArgc(arg_count), args);
25701cb0ef41Sopenharmony_ci  }
25711cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
25721cb0ef41Sopenharmony_ci}
25731cb0ef41Sopenharmony_ci
25741cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallJSRuntime() {
25751cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
25761cb0ef41Sopenharmony_ci  Node* callee = BuildLoadNativeContextField(
25771cb0ef41Sopenharmony_ci      bytecode_iterator().GetNativeContextIndexOperand(0));
25781cb0ef41Sopenharmony_ci  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
25791cb0ef41Sopenharmony_ci  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
25801cb0ef41Sopenharmony_ci  int arg_count = static_cast<int>(reg_count);
25811cb0ef41Sopenharmony_ci  int arity = JSCallNode::ArityForArgc(arg_count);
25821cb0ef41Sopenharmony_ci
25831cb0ef41Sopenharmony_ci  const Operator* call = javascript()->Call(arity);
25841cb0ef41Sopenharmony_ci  Node* const* call_args = ProcessCallVarArgs(
25851cb0ef41Sopenharmony_ci      ConvertReceiverMode::kNullOrUndefined, callee, first_reg, arg_count);
25861cb0ef41Sopenharmony_ci  Node* value = MakeNode(call, arity, call_args);
25871cb0ef41Sopenharmony_ci  environment()->BindAccumulator(value, Environment::kAttachFrameState);
25881cb0ef41Sopenharmony_ci}
25891cb0ef41Sopenharmony_ci
25901cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
25911cb0ef41Sopenharmony_ci    const Operator* call_runtime_op, interpreter::Register receiver,
25921cb0ef41Sopenharmony_ci    size_t reg_count) {
25931cb0ef41Sopenharmony_ci  int arg_count = static_cast<int>(reg_count);
25941cb0ef41Sopenharmony_ci  // arity is args.
25951cb0ef41Sopenharmony_ci  int arity = arg_count;
25961cb0ef41Sopenharmony_ci  Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
25971cb0ef41Sopenharmony_ci  int first_arg_index = receiver.index();
25981cb0ef41Sopenharmony_ci  for (int i = 0; i < static_cast<int>(reg_count); ++i) {
25991cb0ef41Sopenharmony_ci    all[i] = environment()->LookupRegister(
26001cb0ef41Sopenharmony_ci        interpreter::Register(first_arg_index + i));
26011cb0ef41Sopenharmony_ci  }
26021cb0ef41Sopenharmony_ci  Node* value = MakeNode(call_runtime_op, arity, all);
26031cb0ef41Sopenharmony_ci  return value;
26041cb0ef41Sopenharmony_ci}
26051cb0ef41Sopenharmony_ci
26061cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallRuntime() {
26071cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
26081cb0ef41Sopenharmony_ci  Runtime::FunctionId function_id = bytecode_iterator().GetRuntimeIdOperand(0);
26091cb0ef41Sopenharmony_ci  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
26101cb0ef41Sopenharmony_ci  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
26111cb0ef41Sopenharmony_ci
26121cb0ef41Sopenharmony_ci  // Handle %ObserveNode here (rather than in JSIntrinsicLowering) to observe
26131cb0ef41Sopenharmony_ci  // the node as early as possible.
26141cb0ef41Sopenharmony_ci  if (function_id == Runtime::FunctionId::kObserveNode) {
26151cb0ef41Sopenharmony_ci    DCHECK_EQ(1, reg_count);
26161cb0ef41Sopenharmony_ci    Node* value = environment()->LookupRegister(receiver);
26171cb0ef41Sopenharmony_ci    observe_node_info_.StartObserving(value);
26181cb0ef41Sopenharmony_ci    environment()->BindAccumulator(value);
26191cb0ef41Sopenharmony_ci  } else {
26201cb0ef41Sopenharmony_ci    // Create node to perform the runtime call.
26211cb0ef41Sopenharmony_ci    const Operator* call = javascript()->CallRuntime(function_id, reg_count);
26221cb0ef41Sopenharmony_ci    Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
26231cb0ef41Sopenharmony_ci    environment()->BindAccumulator(value, Environment::kAttachFrameState);
26241cb0ef41Sopenharmony_ci
26251cb0ef41Sopenharmony_ci    // Connect to the end if {function_id} is non-returning.
26261cb0ef41Sopenharmony_ci    if (Runtime::IsNonReturning(function_id)) {
26271cb0ef41Sopenharmony_ci      // TODO(7099): Investigate if we need LoopExit node here.
26281cb0ef41Sopenharmony_ci      Node* control = NewNode(common()->Throw());
26291cb0ef41Sopenharmony_ci      MergeControlToLeaveFunction(control);
26301cb0ef41Sopenharmony_ci    }
26311cb0ef41Sopenharmony_ci  }
26321cb0ef41Sopenharmony_ci}
26331cb0ef41Sopenharmony_ci
26341cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitCallRuntimeForPair() {
26351cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
26361cb0ef41Sopenharmony_ci  Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
26371cb0ef41Sopenharmony_ci  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
26381cb0ef41Sopenharmony_ci  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
26391cb0ef41Sopenharmony_ci  interpreter::Register first_return =
26401cb0ef41Sopenharmony_ci      bytecode_iterator().GetRegisterOperand(3);
26411cb0ef41Sopenharmony_ci
26421cb0ef41Sopenharmony_ci  // Create node to perform the runtime call.
26431cb0ef41Sopenharmony_ci  const Operator* call = javascript()->CallRuntime(functionId, reg_count);
26441cb0ef41Sopenharmony_ci  Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count);
26451cb0ef41Sopenharmony_ci  environment()->BindRegistersToProjections(first_return, return_pair,
26461cb0ef41Sopenharmony_ci                                            Environment::kAttachFrameState);
26471cb0ef41Sopenharmony_ci}
26481cb0ef41Sopenharmony_ci
26491cb0ef41Sopenharmony_ciNode* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister(
26501cb0ef41Sopenharmony_ci    Node* target, Node* new_target, interpreter::Register first_arg,
26511cb0ef41Sopenharmony_ci    int arg_count) {
26521cb0ef41Sopenharmony_ci  const int arity = JSConstructNode::ArityForArgc(arg_count);
26531cb0ef41Sopenharmony_ci  Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
26541cb0ef41Sopenharmony_ci  int cursor = 0;
26551cb0ef41Sopenharmony_ci
26561cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSConstructNode::TargetIndex() == 0);
26571cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSConstructNode::NewTargetIndex() == 1);
26581cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSConstructNode::FirstArgumentIndex() == 2);
26591cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSConstructNode::kFeedbackVectorIsLastInput);
26601cb0ef41Sopenharmony_ci
26611cb0ef41Sopenharmony_ci  all[cursor++] = target;
26621cb0ef41Sopenharmony_ci  all[cursor++] = new_target;
26631cb0ef41Sopenharmony_ci
26641cb0ef41Sopenharmony_ci  // The function arguments are in consecutive registers.
26651cb0ef41Sopenharmony_ci  int arg_base = first_arg.index();
26661cb0ef41Sopenharmony_ci  for (int i = 0; i < arg_count; ++i) {
26671cb0ef41Sopenharmony_ci    all[cursor++] =
26681cb0ef41Sopenharmony_ci        environment()->LookupRegister(interpreter::Register(arg_base + i));
26691cb0ef41Sopenharmony_ci  }
26701cb0ef41Sopenharmony_ci
26711cb0ef41Sopenharmony_ci  all[cursor++] = feedback_vector_node();
26721cb0ef41Sopenharmony_ci
26731cb0ef41Sopenharmony_ci  DCHECK_EQ(cursor, arity);
26741cb0ef41Sopenharmony_ci  return all;
26751cb0ef41Sopenharmony_ci}
26761cb0ef41Sopenharmony_ci
26771cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitConstruct() {
26781cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
26791cb0ef41Sopenharmony_ci  interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
26801cb0ef41Sopenharmony_ci  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
26811cb0ef41Sopenharmony_ci  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
26821cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(3);
26831cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(slot_id);
26841cb0ef41Sopenharmony_ci
26851cb0ef41Sopenharmony_ci  Node* new_target = environment()->LookupAccumulator();
26861cb0ef41Sopenharmony_ci  Node* callee = environment()->LookupRegister(callee_reg);
26871cb0ef41Sopenharmony_ci
26881cb0ef41Sopenharmony_ci  CallFrequency frequency = ComputeCallFrequency(slot_id);
26891cb0ef41Sopenharmony_ci  const uint32_t arg_count = static_cast<uint32_t>(reg_count);
26901cb0ef41Sopenharmony_ci  const uint32_t arity = JSConstructNode::ArityForArgc(arg_count);
26911cb0ef41Sopenharmony_ci  const Operator* op = javascript()->Construct(arity, frequency, feedback);
26921cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
26931cb0ef41Sopenharmony_ci  Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
26941cb0ef41Sopenharmony_ci                                                        first_reg, arg_count);
26951cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
26961cb0ef41Sopenharmony_ci      op, args, static_cast<int>(arg_count), feedback.slot);
26971cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
26981cb0ef41Sopenharmony_ci
26991cb0ef41Sopenharmony_ci  Node* node = nullptr;
27001cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
27011cb0ef41Sopenharmony_ci    node = lowering.value();
27021cb0ef41Sopenharmony_ci  } else {
27031cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
27041cb0ef41Sopenharmony_ci    node = MakeNode(op, arity, args);
27051cb0ef41Sopenharmony_ci  }
27061cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
27071cb0ef41Sopenharmony_ci}
27081cb0ef41Sopenharmony_ci
27091cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitConstructWithSpread() {
27101cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
27111cb0ef41Sopenharmony_ci  interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
27121cb0ef41Sopenharmony_ci  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
27131cb0ef41Sopenharmony_ci  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
27141cb0ef41Sopenharmony_ci  int const slot_id = bytecode_iterator().GetIndexOperand(3);
27151cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(slot_id);
27161cb0ef41Sopenharmony_ci
27171cb0ef41Sopenharmony_ci  Node* new_target = environment()->LookupAccumulator();
27181cb0ef41Sopenharmony_ci  Node* callee = environment()->LookupRegister(callee_reg);
27191cb0ef41Sopenharmony_ci
27201cb0ef41Sopenharmony_ci  CallFrequency frequency = ComputeCallFrequency(slot_id);
27211cb0ef41Sopenharmony_ci  const uint32_t arg_count = static_cast<uint32_t>(reg_count);
27221cb0ef41Sopenharmony_ci  const uint32_t arity = JSConstructNode::ArityForArgc(arg_count);
27231cb0ef41Sopenharmony_ci  const Operator* op =
27241cb0ef41Sopenharmony_ci      javascript()->ConstructWithSpread(arity, frequency, feedback);
27251cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
27261cb0ef41Sopenharmony_ci  Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
27271cb0ef41Sopenharmony_ci                                                        first_reg, arg_count);
27281cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
27291cb0ef41Sopenharmony_ci      op, args, static_cast<int>(arg_count), feedback.slot);
27301cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
27311cb0ef41Sopenharmony_ci
27321cb0ef41Sopenharmony_ci  Node* node = nullptr;
27331cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
27341cb0ef41Sopenharmony_ci    node = lowering.value();
27351cb0ef41Sopenharmony_ci  } else {
27361cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
27371cb0ef41Sopenharmony_ci    node = MakeNode(op, arity, args);
27381cb0ef41Sopenharmony_ci  }
27391cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
27401cb0ef41Sopenharmony_ci}
27411cb0ef41Sopenharmony_ci
27421cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitInvokeIntrinsic() {
27431cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
27441cb0ef41Sopenharmony_ci  Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
27451cb0ef41Sopenharmony_ci  interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
27461cb0ef41Sopenharmony_ci  size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
27471cb0ef41Sopenharmony_ci
27481cb0ef41Sopenharmony_ci  // Create node to perform the runtime call. Turbofan will take care of the
27491cb0ef41Sopenharmony_ci  // lowering.
27501cb0ef41Sopenharmony_ci  const Operator* call = javascript()->CallRuntime(functionId, reg_count);
27511cb0ef41Sopenharmony_ci  Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
27521cb0ef41Sopenharmony_ci  environment()->BindAccumulator(value, Environment::kAttachFrameState);
27531cb0ef41Sopenharmony_ci}
27541cb0ef41Sopenharmony_ci
27551cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitThrow() {
27561cb0ef41Sopenharmony_ci  BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
27571cb0ef41Sopenharmony_ci      bytecode_iterator().current_offset()));
27581cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
27591cb0ef41Sopenharmony_ci  Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
27601cb0ef41Sopenharmony_ci  environment()->BindAccumulator(call, Environment::kAttachFrameState);
27611cb0ef41Sopenharmony_ci  Node* control = NewNode(common()->Throw());
27621cb0ef41Sopenharmony_ci  MergeControlToLeaveFunction(control);
27631cb0ef41Sopenharmony_ci}
27641cb0ef41Sopenharmony_ci
27651cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitAbort() {
27661cb0ef41Sopenharmony_ci  BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
27671cb0ef41Sopenharmony_ci      bytecode_iterator().current_offset()));
27681cb0ef41Sopenharmony_ci  AbortReason reason =
27691cb0ef41Sopenharmony_ci      static_cast<AbortReason>(bytecode_iterator().GetIndexOperand(0));
27701cb0ef41Sopenharmony_ci  NewNode(simplified()->RuntimeAbort(reason));
27711cb0ef41Sopenharmony_ci  Node* control = NewNode(common()->Throw());
27721cb0ef41Sopenharmony_ci  MergeControlToLeaveFunction(control);
27731cb0ef41Sopenharmony_ci}
27741cb0ef41Sopenharmony_ci
27751cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitReThrow() {
27761cb0ef41Sopenharmony_ci  BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
27771cb0ef41Sopenharmony_ci      bytecode_iterator().current_offset()));
27781cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
27791cb0ef41Sopenharmony_ci  NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
27801cb0ef41Sopenharmony_ci  Node* control = NewNode(common()->Throw());
27811cb0ef41Sopenharmony_ci  MergeControlToLeaveFunction(control);
27821cb0ef41Sopenharmony_ci}
27831cb0ef41Sopenharmony_ci
27841cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildHoleCheckAndThrow(
27851cb0ef41Sopenharmony_ci    Node* condition, Runtime::FunctionId runtime_id, Node* name) {
27861cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
27871cb0ef41Sopenharmony_ci  NewBranch(condition, BranchHint::kFalse);
27881cb0ef41Sopenharmony_ci  {
27891cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
27901cb0ef41Sopenharmony_ci
27911cb0ef41Sopenharmony_ci    NewIfTrue();
27921cb0ef41Sopenharmony_ci    BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
27931cb0ef41Sopenharmony_ci        bytecode_iterator().current_offset()));
27941cb0ef41Sopenharmony_ci    Node* node;
27951cb0ef41Sopenharmony_ci    const Operator* op = javascript()->CallRuntime(runtime_id);
27961cb0ef41Sopenharmony_ci    if (runtime_id == Runtime::kThrowAccessedUninitializedVariable) {
27971cb0ef41Sopenharmony_ci      DCHECK_NOT_NULL(name);
27981cb0ef41Sopenharmony_ci      node = NewNode(op, name);
27991cb0ef41Sopenharmony_ci    } else {
28001cb0ef41Sopenharmony_ci      DCHECK(runtime_id == Runtime::kThrowSuperAlreadyCalledError ||
28011cb0ef41Sopenharmony_ci             runtime_id == Runtime::kThrowSuperNotCalled);
28021cb0ef41Sopenharmony_ci      node = NewNode(op);
28031cb0ef41Sopenharmony_ci    }
28041cb0ef41Sopenharmony_ci    environment()->RecordAfterState(node, Environment::kAttachFrameState);
28051cb0ef41Sopenharmony_ci    Node* control = NewNode(common()->Throw());
28061cb0ef41Sopenharmony_ci    MergeControlToLeaveFunction(control);
28071cb0ef41Sopenharmony_ci  }
28081cb0ef41Sopenharmony_ci  NewIfFalse();
28091cb0ef41Sopenharmony_ci  environment()->BindAccumulator(accumulator);
28101cb0ef41Sopenharmony_ci}
28111cb0ef41Sopenharmony_ci
28121cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitThrowReferenceErrorIfHole() {
28131cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
28141cb0ef41Sopenharmony_ci  Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
28151cb0ef41Sopenharmony_ci                                 jsgraph()->TheHoleConstant());
28161cb0ef41Sopenharmony_ci  Node* name = jsgraph()->Constant(MakeRefForConstantForIndexOperand(0));
28171cb0ef41Sopenharmony_ci  BuildHoleCheckAndThrow(check_for_hole,
28181cb0ef41Sopenharmony_ci                         Runtime::kThrowAccessedUninitializedVariable, name);
28191cb0ef41Sopenharmony_ci}
28201cb0ef41Sopenharmony_ci
28211cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitThrowSuperNotCalledIfHole() {
28221cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
28231cb0ef41Sopenharmony_ci  Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
28241cb0ef41Sopenharmony_ci                                 jsgraph()->TheHoleConstant());
28251cb0ef41Sopenharmony_ci  BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowSuperNotCalled);
28261cb0ef41Sopenharmony_ci}
28271cb0ef41Sopenharmony_ci
28281cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
28291cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
28301cb0ef41Sopenharmony_ci  Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
28311cb0ef41Sopenharmony_ci                                 jsgraph()->TheHoleConstant());
28321cb0ef41Sopenharmony_ci  Node* check_for_not_hole =
28331cb0ef41Sopenharmony_ci      NewNode(simplified()->BooleanNot(), check_for_hole);
28341cb0ef41Sopenharmony_ci  BuildHoleCheckAndThrow(check_for_not_hole,
28351cb0ef41Sopenharmony_ci                         Runtime::kThrowSuperAlreadyCalledError);
28361cb0ef41Sopenharmony_ci}
28371cb0ef41Sopenharmony_ci
28381cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitThrowIfNotSuperConstructor() {
28391cb0ef41Sopenharmony_ci  Node* constructor =
28401cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
28411cb0ef41Sopenharmony_ci  Node* check_is_constructor =
28421cb0ef41Sopenharmony_ci      NewNode(simplified()->ObjectIsConstructor(), constructor);
28431cb0ef41Sopenharmony_ci  NewBranch(check_is_constructor, BranchHint::kTrue);
28441cb0ef41Sopenharmony_ci  {
28451cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
28461cb0ef41Sopenharmony_ci    NewIfFalse();
28471cb0ef41Sopenharmony_ci    BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
28481cb0ef41Sopenharmony_ci        bytecode_iterator().current_offset()));
28491cb0ef41Sopenharmony_ci    Node* node =
28501cb0ef41Sopenharmony_ci        NewNode(javascript()->CallRuntime(Runtime::kThrowNotSuperConstructor),
28511cb0ef41Sopenharmony_ci                constructor, GetFunctionClosure());
28521cb0ef41Sopenharmony_ci    environment()->RecordAfterState(node, Environment::kAttachFrameState);
28531cb0ef41Sopenharmony_ci    Node* control = NewNode(common()->Throw());
28541cb0ef41Sopenharmony_ci    MergeControlToLeaveFunction(control);
28551cb0ef41Sopenharmony_ci  }
28561cb0ef41Sopenharmony_ci  NewIfTrue();
28571cb0ef41Sopenharmony_ci
28581cb0ef41Sopenharmony_ci  constructor = NewNode(common()->TypeGuard(Type::Callable()), constructor);
28591cb0ef41Sopenharmony_ci  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
28601cb0ef41Sopenharmony_ci                              constructor);
28611cb0ef41Sopenharmony_ci}
28621cb0ef41Sopenharmony_ci
28631cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) {
28641cb0ef41Sopenharmony_ci  DCHECK(JSOperator::IsUnaryWithFeedback(op->opcode()));
28651cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
28661cb0ef41Sopenharmony_ci  Node* operand = environment()->LookupAccumulator();
28671cb0ef41Sopenharmony_ci
28681cb0ef41Sopenharmony_ci  FeedbackSlot slot =
28691cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex);
28701cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
28711cb0ef41Sopenharmony_ci      TryBuildSimplifiedUnaryOp(op, operand, slot);
28721cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
28731cb0ef41Sopenharmony_ci
28741cb0ef41Sopenharmony_ci  Node* node = nullptr;
28751cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
28761cb0ef41Sopenharmony_ci    node = lowering.value();
28771cb0ef41Sopenharmony_ci  } else {
28781cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
28791cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
28801cb0ef41Sopenharmony_ci    node = NewNode(op, operand, feedback_vector_node());
28811cb0ef41Sopenharmony_ci  }
28821cb0ef41Sopenharmony_ci
28831cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
28841cb0ef41Sopenharmony_ci}
28851cb0ef41Sopenharmony_ci
28861cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) {
28871cb0ef41Sopenharmony_ci  DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
28881cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
28891cb0ef41Sopenharmony_ci  Node* left =
28901cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
28911cb0ef41Sopenharmony_ci  Node* right = environment()->LookupAccumulator();
28921cb0ef41Sopenharmony_ci
28931cb0ef41Sopenharmony_ci  FeedbackSlot slot =
28941cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex);
28951cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
28961cb0ef41Sopenharmony_ci      TryBuildSimplifiedBinaryOp(op, left, right, slot);
28971cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
28981cb0ef41Sopenharmony_ci
28991cb0ef41Sopenharmony_ci  Node* node = nullptr;
29001cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
29011cb0ef41Sopenharmony_ci    node = lowering.value();
29021cb0ef41Sopenharmony_ci  } else {
29031cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
29041cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
29051cb0ef41Sopenharmony_ci    node = NewNode(op, left, right, feedback_vector_node());
29061cb0ef41Sopenharmony_ci  }
29071cb0ef41Sopenharmony_ci
29081cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
29091cb0ef41Sopenharmony_ci}
29101cb0ef41Sopenharmony_ci
29111cb0ef41Sopenharmony_ci// Helper function to create for-in mode from the recorded type feedback.
29121cb0ef41Sopenharmony_ciForInMode BytecodeGraphBuilder::GetForInMode(FeedbackSlot slot) {
29131cb0ef41Sopenharmony_ci  FeedbackSource source(feedback_vector(), slot);
29141cb0ef41Sopenharmony_ci  switch (broker()->GetFeedbackForForIn(source)) {
29151cb0ef41Sopenharmony_ci    case ForInHint::kNone:
29161cb0ef41Sopenharmony_ci    case ForInHint::kEnumCacheKeysAndIndices:
29171cb0ef41Sopenharmony_ci      return ForInMode::kUseEnumCacheKeysAndIndices;
29181cb0ef41Sopenharmony_ci    case ForInHint::kEnumCacheKeys:
29191cb0ef41Sopenharmony_ci      return ForInMode::kUseEnumCacheKeys;
29201cb0ef41Sopenharmony_ci    case ForInHint::kAny:
29211cb0ef41Sopenharmony_ci      return ForInMode::kGeneric;
29221cb0ef41Sopenharmony_ci  }
29231cb0ef41Sopenharmony_ci  UNREACHABLE();
29241cb0ef41Sopenharmony_ci}
29251cb0ef41Sopenharmony_ci
29261cb0ef41Sopenharmony_ciCallFrequency BytecodeGraphBuilder::ComputeCallFrequency(int slot_id) const {
29271cb0ef41Sopenharmony_ci  if (invocation_frequency_.IsUnknown()) return CallFrequency();
29281cb0ef41Sopenharmony_ci  FeedbackSlot slot = FeedbackVector::ToSlot(slot_id);
29291cb0ef41Sopenharmony_ci  FeedbackSource source(feedback_vector(), slot);
29301cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = broker()->GetFeedbackForCall(source);
29311cb0ef41Sopenharmony_ci  float feedback_frequency =
29321cb0ef41Sopenharmony_ci      feedback.IsInsufficient() ? 0.0f : feedback.AsCall().frequency();
29331cb0ef41Sopenharmony_ci  if (feedback_frequency == 0.0f) {  // Prevent multiplying zero and infinity.
29341cb0ef41Sopenharmony_ci    return CallFrequency(0.0f);
29351cb0ef41Sopenharmony_ci  } else {
29361cb0ef41Sopenharmony_ci    return CallFrequency(feedback_frequency * invocation_frequency_.value());
29371cb0ef41Sopenharmony_ci  }
29381cb0ef41Sopenharmony_ci}
29391cb0ef41Sopenharmony_ci
29401cb0ef41Sopenharmony_ciSpeculationMode BytecodeGraphBuilder::GetSpeculationMode(int slot_id) const {
29411cb0ef41Sopenharmony_ci  FeedbackSlot slot = FeedbackVector::ToSlot(slot_id);
29421cb0ef41Sopenharmony_ci  FeedbackSource source(feedback_vector(), slot);
29431cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = broker()->GetFeedbackForCall(source);
29441cb0ef41Sopenharmony_ci  return feedback.IsInsufficient() ? SpeculationMode::kDisallowSpeculation
29451cb0ef41Sopenharmony_ci                                   : feedback.AsCall().speculation_mode();
29461cb0ef41Sopenharmony_ci}
29471cb0ef41Sopenharmony_ci
29481cb0ef41Sopenharmony_ciCallFeedbackRelation BytecodeGraphBuilder::ComputeCallFeedbackRelation(
29491cb0ef41Sopenharmony_ci    int slot_id) const {
29501cb0ef41Sopenharmony_ci  FeedbackSlot slot = FeedbackVector::ToSlot(slot_id);
29511cb0ef41Sopenharmony_ci  FeedbackSource source(feedback_vector(), slot);
29521cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = broker()->GetFeedbackForCall(source);
29531cb0ef41Sopenharmony_ci  if (feedback.IsInsufficient()) return CallFeedbackRelation::kUnrelated;
29541cb0ef41Sopenharmony_ci  CallFeedbackContent call_feedback_content =
29551cb0ef41Sopenharmony_ci      feedback.AsCall().call_feedback_content();
29561cb0ef41Sopenharmony_ci  return call_feedback_content == CallFeedbackContent::kTarget
29571cb0ef41Sopenharmony_ci             ? CallFeedbackRelation::kTarget
29581cb0ef41Sopenharmony_ci             : CallFeedbackRelation::kReceiver;
29591cb0ef41Sopenharmony_ci}
29601cb0ef41Sopenharmony_ci
29611cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitBitwiseNot() {
29621cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
29631cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
29641cb0ef41Sopenharmony_ci  BuildUnaryOp(javascript()->BitwiseNot(feedback));
29651cb0ef41Sopenharmony_ci}
29661cb0ef41Sopenharmony_ci
29671cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDec() {
29681cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
29691cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
29701cb0ef41Sopenharmony_ci  BuildUnaryOp(javascript()->Decrement(feedback));
29711cb0ef41Sopenharmony_ci}
29721cb0ef41Sopenharmony_ci
29731cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitInc() {
29741cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
29751cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
29761cb0ef41Sopenharmony_ci  BuildUnaryOp(javascript()->Increment(feedback));
29771cb0ef41Sopenharmony_ci}
29781cb0ef41Sopenharmony_ci
29791cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitNegate() {
29801cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
29811cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
29821cb0ef41Sopenharmony_ci  BuildUnaryOp(javascript()->Negate(feedback));
29831cb0ef41Sopenharmony_ci}
29841cb0ef41Sopenharmony_ci
29851cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitAdd() {
29861cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
29871cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
29881cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->Add(feedback));
29891cb0ef41Sopenharmony_ci}
29901cb0ef41Sopenharmony_ci
29911cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSub() {
29921cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
29931cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
29941cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->Subtract(feedback));
29951cb0ef41Sopenharmony_ci}
29961cb0ef41Sopenharmony_ci
29971cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitMul() {
29981cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
29991cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30001cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->Multiply(feedback));
30011cb0ef41Sopenharmony_ci}
30021cb0ef41Sopenharmony_ci
30031cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDiv() {
30041cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30051cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30061cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->Divide(feedback));
30071cb0ef41Sopenharmony_ci}
30081cb0ef41Sopenharmony_ci
30091cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitMod() {
30101cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30111cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30121cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->Modulus(feedback));
30131cb0ef41Sopenharmony_ci}
30141cb0ef41Sopenharmony_ci
30151cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitExp() {
30161cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30171cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30181cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->Exponentiate(feedback));
30191cb0ef41Sopenharmony_ci}
30201cb0ef41Sopenharmony_ci
30211cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitBitwiseOr() {
30221cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30231cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30241cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->BitwiseOr(feedback));
30251cb0ef41Sopenharmony_ci}
30261cb0ef41Sopenharmony_ci
30271cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitBitwiseXor() {
30281cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30291cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30301cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->BitwiseXor(feedback));
30311cb0ef41Sopenharmony_ci}
30321cb0ef41Sopenharmony_ci
30331cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitBitwiseAnd() {
30341cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30351cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30361cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->BitwiseAnd(feedback));
30371cb0ef41Sopenharmony_ci}
30381cb0ef41Sopenharmony_ci
30391cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitShiftLeft() {
30401cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30411cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30421cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->ShiftLeft(feedback));
30431cb0ef41Sopenharmony_ci}
30441cb0ef41Sopenharmony_ci
30451cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitShiftRight() {
30461cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30471cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30481cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->ShiftRight(feedback));
30491cb0ef41Sopenharmony_ci}
30501cb0ef41Sopenharmony_ci
30511cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitShiftRightLogical() {
30521cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30531cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
30541cb0ef41Sopenharmony_ci  BuildBinaryOp(javascript()->ShiftRightLogical(feedback));
30551cb0ef41Sopenharmony_ci}
30561cb0ef41Sopenharmony_ci
30571cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) {
30581cb0ef41Sopenharmony_ci  DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
30591cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
30601cb0ef41Sopenharmony_ci  Node* left = environment()->LookupAccumulator();
30611cb0ef41Sopenharmony_ci  Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
30621cb0ef41Sopenharmony_ci
30631cb0ef41Sopenharmony_ci  FeedbackSlot slot =
30641cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex);
30651cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
30661cb0ef41Sopenharmony_ci      TryBuildSimplifiedBinaryOp(op, left, right, slot);
30671cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
30681cb0ef41Sopenharmony_ci
30691cb0ef41Sopenharmony_ci  Node* node = nullptr;
30701cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
30711cb0ef41Sopenharmony_ci    node = lowering.value();
30721cb0ef41Sopenharmony_ci  } else {
30731cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
30741cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
30751cb0ef41Sopenharmony_ci    node = NewNode(op, left, right, feedback_vector_node());
30761cb0ef41Sopenharmony_ci  }
30771cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
30781cb0ef41Sopenharmony_ci}
30791cb0ef41Sopenharmony_ci
30801cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitAddSmi() {
30811cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30821cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
30831cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->Add(feedback));
30841cb0ef41Sopenharmony_ci}
30851cb0ef41Sopenharmony_ci
30861cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSubSmi() {
30871cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30881cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
30891cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->Subtract(feedback));
30901cb0ef41Sopenharmony_ci}
30911cb0ef41Sopenharmony_ci
30921cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitMulSmi() {
30931cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
30941cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
30951cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->Multiply(feedback));
30961cb0ef41Sopenharmony_ci}
30971cb0ef41Sopenharmony_ci
30981cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDivSmi() {
30991cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31001cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31011cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->Divide(feedback));
31021cb0ef41Sopenharmony_ci}
31031cb0ef41Sopenharmony_ci
31041cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitModSmi() {
31051cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31061cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31071cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->Modulus(feedback));
31081cb0ef41Sopenharmony_ci}
31091cb0ef41Sopenharmony_ci
31101cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitExpSmi() {
31111cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31121cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31131cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->Exponentiate(feedback));
31141cb0ef41Sopenharmony_ci}
31151cb0ef41Sopenharmony_ci
31161cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitBitwiseOrSmi() {
31171cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31181cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31191cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->BitwiseOr(feedback));
31201cb0ef41Sopenharmony_ci}
31211cb0ef41Sopenharmony_ci
31221cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitBitwiseXorSmi() {
31231cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31241cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31251cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->BitwiseXor(feedback));
31261cb0ef41Sopenharmony_ci}
31271cb0ef41Sopenharmony_ci
31281cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitBitwiseAndSmi() {
31291cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31301cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31311cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(feedback));
31321cb0ef41Sopenharmony_ci}
31331cb0ef41Sopenharmony_ci
31341cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitShiftLeftSmi() {
31351cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31361cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31371cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->ShiftLeft(feedback));
31381cb0ef41Sopenharmony_ci}
31391cb0ef41Sopenharmony_ci
31401cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitShiftRightSmi() {
31411cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31421cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31431cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->ShiftRight(feedback));
31441cb0ef41Sopenharmony_ci}
31451cb0ef41Sopenharmony_ci
31461cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitShiftRightLogicalSmi() {
31471cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
31481cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
31491cb0ef41Sopenharmony_ci  BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical(feedback));
31501cb0ef41Sopenharmony_ci}
31511cb0ef41Sopenharmony_ci
31521cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitLogicalNot() {
31531cb0ef41Sopenharmony_ci  Node* value = environment()->LookupAccumulator();
31541cb0ef41Sopenharmony_ci  Node* node = NewNode(simplified()->BooleanNot(), value);
31551cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
31561cb0ef41Sopenharmony_ci}
31571cb0ef41Sopenharmony_ci
31581cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
31591cb0ef41Sopenharmony_ci  Node* value =
31601cb0ef41Sopenharmony_ci      NewNode(simplified()->ToBoolean(), environment()->LookupAccumulator());
31611cb0ef41Sopenharmony_ci  Node* node = NewNode(simplified()->BooleanNot(), value);
31621cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
31631cb0ef41Sopenharmony_ci}
31641cb0ef41Sopenharmony_ci
31651cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTypeOf() {
31661cb0ef41Sopenharmony_ci  Node* node =
31671cb0ef41Sopenharmony_ci      NewNode(simplified()->TypeOf(), environment()->LookupAccumulator());
31681cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
31691cb0ef41Sopenharmony_ci}
31701cb0ef41Sopenharmony_ci
31711cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
31721cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
31731cb0ef41Sopenharmony_ci  Node* key = environment()->LookupAccumulator();
31741cb0ef41Sopenharmony_ci  Node* object =
31751cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
31761cb0ef41Sopenharmony_ci  Node* mode = jsgraph()->Constant(static_cast<int32_t>(language_mode));
31771cb0ef41Sopenharmony_ci  Node* node = NewNode(javascript()->DeleteProperty(), object, key, mode);
31781cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
31791cb0ef41Sopenharmony_ci}
31801cb0ef41Sopenharmony_ci
31811cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDeletePropertyStrict() {
31821cb0ef41Sopenharmony_ci  BuildDelete(LanguageMode::kStrict);
31831cb0ef41Sopenharmony_ci}
31841cb0ef41Sopenharmony_ci
31851cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDeletePropertySloppy() {
31861cb0ef41Sopenharmony_ci  BuildDelete(LanguageMode::kSloppy);
31871cb0ef41Sopenharmony_ci}
31881cb0ef41Sopenharmony_ci
31891cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitGetSuperConstructor() {
31901cb0ef41Sopenharmony_ci  Node* node = NewNode(javascript()->GetSuperConstructor(),
31911cb0ef41Sopenharmony_ci                       environment()->LookupAccumulator());
31921cb0ef41Sopenharmony_ci  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
31931cb0ef41Sopenharmony_ci                              Environment::kAttachFrameState);
31941cb0ef41Sopenharmony_ci}
31951cb0ef41Sopenharmony_ci
31961cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildCompareOp(const Operator* op) {
31971cb0ef41Sopenharmony_ci  DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
31981cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
31991cb0ef41Sopenharmony_ci  Node* left =
32001cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
32011cb0ef41Sopenharmony_ci  Node* right = environment()->LookupAccumulator();
32021cb0ef41Sopenharmony_ci
32031cb0ef41Sopenharmony_ci  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
32041cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
32051cb0ef41Sopenharmony_ci      TryBuildSimplifiedBinaryOp(op, left, right, slot);
32061cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
32071cb0ef41Sopenharmony_ci
32081cb0ef41Sopenharmony_ci  Node* node = nullptr;
32091cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
32101cb0ef41Sopenharmony_ci    node = lowering.value();
32111cb0ef41Sopenharmony_ci  } else {
32121cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
32131cb0ef41Sopenharmony_ci    DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
32141cb0ef41Sopenharmony_ci    node = NewNode(op, left, right, feedback_vector_node());
32151cb0ef41Sopenharmony_ci  }
32161cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
32171cb0ef41Sopenharmony_ci}
32181cb0ef41Sopenharmony_ci
32191cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestEqual() {
32201cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
32211cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
32221cb0ef41Sopenharmony_ci  BuildCompareOp(javascript()->Equal(feedback));
32231cb0ef41Sopenharmony_ci}
32241cb0ef41Sopenharmony_ci
32251cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestEqualStrict() {
32261cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
32271cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
32281cb0ef41Sopenharmony_ci  BuildCompareOp(javascript()->StrictEqual(feedback));
32291cb0ef41Sopenharmony_ci}
32301cb0ef41Sopenharmony_ci
32311cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestLessThan() {
32321cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
32331cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
32341cb0ef41Sopenharmony_ci  BuildCompareOp(javascript()->LessThan(feedback));
32351cb0ef41Sopenharmony_ci}
32361cb0ef41Sopenharmony_ci
32371cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestGreaterThan() {
32381cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
32391cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
32401cb0ef41Sopenharmony_ci  BuildCompareOp(javascript()->GreaterThan(feedback));
32411cb0ef41Sopenharmony_ci}
32421cb0ef41Sopenharmony_ci
32431cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
32441cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
32451cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
32461cb0ef41Sopenharmony_ci  BuildCompareOp(javascript()->LessThanOrEqual(feedback));
32471cb0ef41Sopenharmony_ci}
32481cb0ef41Sopenharmony_ci
32491cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
32501cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
32511cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
32521cb0ef41Sopenharmony_ci  BuildCompareOp(javascript()->GreaterThanOrEqual(feedback));
32531cb0ef41Sopenharmony_ci}
32541cb0ef41Sopenharmony_ci
32551cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestReferenceEqual() {
32561cb0ef41Sopenharmony_ci  Node* left =
32571cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
32581cb0ef41Sopenharmony_ci  Node* right = environment()->LookupAccumulator();
32591cb0ef41Sopenharmony_ci  Node* result = NewNode(simplified()->ReferenceEqual(), left, right);
32601cb0ef41Sopenharmony_ci  environment()->BindAccumulator(result);
32611cb0ef41Sopenharmony_ci}
32621cb0ef41Sopenharmony_ci
32631cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestIn() {
32641cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
32651cb0ef41Sopenharmony_ci  Node* object = environment()->LookupAccumulator();
32661cb0ef41Sopenharmony_ci  Node* key =
32671cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
32681cb0ef41Sopenharmony_ci  FeedbackSource feedback =
32691cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
32701cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSHasPropertyNode::ObjectIndex() == 0);
32711cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSHasPropertyNode::KeyIndex() == 1);
32721cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSHasPropertyNode::FeedbackVectorIndex() == 2);
32731cb0ef41Sopenharmony_ci  const Operator* op = javascript()->HasProperty(feedback);
32741cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
32751cb0ef41Sopenharmony_ci  Node* node = NewNode(op, object, key, feedback_vector_node());
32761cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
32771cb0ef41Sopenharmony_ci}
32781cb0ef41Sopenharmony_ci
32791cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestInstanceOf() {
32801cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(
32811cb0ef41Sopenharmony_ci      bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
32821cb0ef41Sopenharmony_ci  BuildCompareOp(javascript()->InstanceOf(feedback));
32831cb0ef41Sopenharmony_ci}
32841cb0ef41Sopenharmony_ci
32851cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestUndetectable() {
32861cb0ef41Sopenharmony_ci  Node* object = environment()->LookupAccumulator();
32871cb0ef41Sopenharmony_ci  Node* node = NewNode(jsgraph()->simplified()->ObjectIsUndetectable(), object);
32881cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node);
32891cb0ef41Sopenharmony_ci}
32901cb0ef41Sopenharmony_ci
32911cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestNull() {
32921cb0ef41Sopenharmony_ci  Node* object = environment()->LookupAccumulator();
32931cb0ef41Sopenharmony_ci  Node* result = NewNode(simplified()->ReferenceEqual(), object,
32941cb0ef41Sopenharmony_ci                         jsgraph()->NullConstant());
32951cb0ef41Sopenharmony_ci  environment()->BindAccumulator(result);
32961cb0ef41Sopenharmony_ci}
32971cb0ef41Sopenharmony_ci
32981cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestUndefined() {
32991cb0ef41Sopenharmony_ci  Node* object = environment()->LookupAccumulator();
33001cb0ef41Sopenharmony_ci  Node* result = NewNode(simplified()->ReferenceEqual(), object,
33011cb0ef41Sopenharmony_ci                         jsgraph()->UndefinedConstant());
33021cb0ef41Sopenharmony_ci  environment()->BindAccumulator(result);
33031cb0ef41Sopenharmony_ci}
33041cb0ef41Sopenharmony_ci
33051cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitTestTypeOf() {
33061cb0ef41Sopenharmony_ci  Node* object = environment()->LookupAccumulator();
33071cb0ef41Sopenharmony_ci  auto literal_flag = interpreter::TestTypeOfFlags::Decode(
33081cb0ef41Sopenharmony_ci      bytecode_iterator().GetFlagOperand(0));
33091cb0ef41Sopenharmony_ci  Node* result;
33101cb0ef41Sopenharmony_ci  switch (literal_flag) {
33111cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kNumber:
33121cb0ef41Sopenharmony_ci      result = NewNode(simplified()->ObjectIsNumber(), object);
33131cb0ef41Sopenharmony_ci      break;
33141cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kString:
33151cb0ef41Sopenharmony_ci      result = NewNode(simplified()->ObjectIsString(), object);
33161cb0ef41Sopenharmony_ci      break;
33171cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kSymbol:
33181cb0ef41Sopenharmony_ci      result = NewNode(simplified()->ObjectIsSymbol(), object);
33191cb0ef41Sopenharmony_ci      break;
33201cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kBigInt:
33211cb0ef41Sopenharmony_ci      result = NewNode(simplified()->ObjectIsBigInt(), object);
33221cb0ef41Sopenharmony_ci      break;
33231cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kBoolean:
33241cb0ef41Sopenharmony_ci      result = NewNode(common()->Select(MachineRepresentation::kTagged),
33251cb0ef41Sopenharmony_ci                       NewNode(simplified()->ReferenceEqual(), object,
33261cb0ef41Sopenharmony_ci                               jsgraph()->TrueConstant()),
33271cb0ef41Sopenharmony_ci                       jsgraph()->TrueConstant(),
33281cb0ef41Sopenharmony_ci                       NewNode(simplified()->ReferenceEqual(), object,
33291cb0ef41Sopenharmony_ci                               jsgraph()->FalseConstant()));
33301cb0ef41Sopenharmony_ci      break;
33311cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kUndefined:
33321cb0ef41Sopenharmony_ci      result = graph()->NewNode(
33331cb0ef41Sopenharmony_ci          common()->Select(MachineRepresentation::kTagged),
33341cb0ef41Sopenharmony_ci          graph()->NewNode(simplified()->ReferenceEqual(), object,
33351cb0ef41Sopenharmony_ci                           jsgraph()->NullConstant()),
33361cb0ef41Sopenharmony_ci          jsgraph()->FalseConstant(),
33371cb0ef41Sopenharmony_ci          graph()->NewNode(simplified()->ObjectIsUndetectable(), object));
33381cb0ef41Sopenharmony_ci      break;
33391cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kFunction:
33401cb0ef41Sopenharmony_ci      result =
33411cb0ef41Sopenharmony_ci          graph()->NewNode(simplified()->ObjectIsDetectableCallable(), object);
33421cb0ef41Sopenharmony_ci      break;
33431cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kObject:
33441cb0ef41Sopenharmony_ci      result = graph()->NewNode(
33451cb0ef41Sopenharmony_ci          common()->Select(MachineRepresentation::kTagged),
33461cb0ef41Sopenharmony_ci          graph()->NewNode(simplified()->ObjectIsNonCallable(), object),
33471cb0ef41Sopenharmony_ci          jsgraph()->TrueConstant(),
33481cb0ef41Sopenharmony_ci          graph()->NewNode(simplified()->ReferenceEqual(), object,
33491cb0ef41Sopenharmony_ci                           jsgraph()->NullConstant()));
33501cb0ef41Sopenharmony_ci      break;
33511cb0ef41Sopenharmony_ci    case interpreter::TestTypeOfFlags::LiteralFlag::kOther:
33521cb0ef41Sopenharmony_ci      UNREACHABLE();  // Should never be emitted.
33531cb0ef41Sopenharmony_ci  }
33541cb0ef41Sopenharmony_ci  environment()->BindAccumulator(result);
33551cb0ef41Sopenharmony_ci}
33561cb0ef41Sopenharmony_ci
33571cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
33581cb0ef41Sopenharmony_ci  Node* value = NewNode(js_op, environment()->LookupAccumulator());
33591cb0ef41Sopenharmony_ci  environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
33601cb0ef41Sopenharmony_ci                              Environment::kAttachFrameState);
33611cb0ef41Sopenharmony_ci}
33621cb0ef41Sopenharmony_ci
33631cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitToName() {
33641cb0ef41Sopenharmony_ci  BuildCastOperator(javascript()->ToName());
33651cb0ef41Sopenharmony_ci}
33661cb0ef41Sopenharmony_ci
33671cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitToObject() {
33681cb0ef41Sopenharmony_ci  BuildCastOperator(javascript()->ToObject());
33691cb0ef41Sopenharmony_ci}
33701cb0ef41Sopenharmony_ci
33711cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitToString() {
33721cb0ef41Sopenharmony_ci  Node* value =
33731cb0ef41Sopenharmony_ci      NewNode(javascript()->ToString(), environment()->LookupAccumulator());
33741cb0ef41Sopenharmony_ci  environment()->BindAccumulator(value, Environment::kAttachFrameState);
33751cb0ef41Sopenharmony_ci}
33761cb0ef41Sopenharmony_ci
33771cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitToNumber() {
33781cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
33791cb0ef41Sopenharmony_ci  Node* object = environment()->LookupAccumulator();
33801cb0ef41Sopenharmony_ci
33811cb0ef41Sopenharmony_ci  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
33821cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
33831cb0ef41Sopenharmony_ci      TryBuildSimplifiedToNumber(object, slot);
33841cb0ef41Sopenharmony_ci
33851cb0ef41Sopenharmony_ci  Node* node = nullptr;
33861cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
33871cb0ef41Sopenharmony_ci    node = lowering.value();
33881cb0ef41Sopenharmony_ci  } else {
33891cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
33901cb0ef41Sopenharmony_ci    node = NewNode(javascript()->ToNumber(), object);
33911cb0ef41Sopenharmony_ci  }
33921cb0ef41Sopenharmony_ci
33931cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
33941cb0ef41Sopenharmony_ci}
33951cb0ef41Sopenharmony_ci
33961cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitToNumeric() {
33971cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
33981cb0ef41Sopenharmony_ci  Node* object = environment()->LookupAccumulator();
33991cb0ef41Sopenharmony_ci
34001cb0ef41Sopenharmony_ci  // If we have some kind of Number feedback, we do the same lowering as for
34011cb0ef41Sopenharmony_ci  // ToNumber.
34021cb0ef41Sopenharmony_ci  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
34031cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
34041cb0ef41Sopenharmony_ci      TryBuildSimplifiedToNumber(object, slot);
34051cb0ef41Sopenharmony_ci
34061cb0ef41Sopenharmony_ci  Node* node = nullptr;
34071cb0ef41Sopenharmony_ci  if (lowering.IsSideEffectFree()) {
34081cb0ef41Sopenharmony_ci    node = lowering.value();
34091cb0ef41Sopenharmony_ci  } else {
34101cb0ef41Sopenharmony_ci    DCHECK(!lowering.Changed());
34111cb0ef41Sopenharmony_ci    node = NewNode(javascript()->ToNumeric(), object);
34121cb0ef41Sopenharmony_ci  }
34131cb0ef41Sopenharmony_ci
34141cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
34151cb0ef41Sopenharmony_ci}
34161cb0ef41Sopenharmony_ci
34171cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJump() { BuildJump(); }
34181cb0ef41Sopenharmony_ci
34191cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
34201cb0ef41Sopenharmony_ci
34211cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfTrue() { BuildJumpIfTrue(); }
34221cb0ef41Sopenharmony_ci
34231cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfTrueConstant() { BuildJumpIfTrue(); }
34241cb0ef41Sopenharmony_ci
34251cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfFalse() { BuildJumpIfFalse(); }
34261cb0ef41Sopenharmony_ci
34271cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfFalseConstant() { BuildJumpIfFalse(); }
34281cb0ef41Sopenharmony_ci
34291cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
34301cb0ef41Sopenharmony_ci  BuildJumpIfToBooleanTrue();
34311cb0ef41Sopenharmony_ci}
34321cb0ef41Sopenharmony_ci
34331cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
34341cb0ef41Sopenharmony_ci  BuildJumpIfToBooleanTrue();
34351cb0ef41Sopenharmony_ci}
34361cb0ef41Sopenharmony_ci
34371cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
34381cb0ef41Sopenharmony_ci  BuildJumpIfToBooleanFalse();
34391cb0ef41Sopenharmony_ci}
34401cb0ef41Sopenharmony_ci
34411cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
34421cb0ef41Sopenharmony_ci  BuildJumpIfToBooleanFalse();
34431cb0ef41Sopenharmony_ci}
34441cb0ef41Sopenharmony_ci
34451cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfJSReceiver() { BuildJumpIfJSReceiver(); }
34461cb0ef41Sopenharmony_ci
34471cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfJSReceiverConstant() {
34481cb0ef41Sopenharmony_ci  BuildJumpIfJSReceiver();
34491cb0ef41Sopenharmony_ci}
34501cb0ef41Sopenharmony_ci
34511cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfNull() {
34521cb0ef41Sopenharmony_ci  BuildJumpIfEqual(jsgraph()->NullConstant());
34531cb0ef41Sopenharmony_ci}
34541cb0ef41Sopenharmony_ci
34551cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfNullConstant() {
34561cb0ef41Sopenharmony_ci  BuildJumpIfEqual(jsgraph()->NullConstant());
34571cb0ef41Sopenharmony_ci}
34581cb0ef41Sopenharmony_ci
34591cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfNotNull() {
34601cb0ef41Sopenharmony_ci  BuildJumpIfNotEqual(jsgraph()->NullConstant());
34611cb0ef41Sopenharmony_ci}
34621cb0ef41Sopenharmony_ci
34631cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfNotNullConstant() {
34641cb0ef41Sopenharmony_ci  BuildJumpIfNotEqual(jsgraph()->NullConstant());
34651cb0ef41Sopenharmony_ci}
34661cb0ef41Sopenharmony_ci
34671cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfUndefined() {
34681cb0ef41Sopenharmony_ci  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
34691cb0ef41Sopenharmony_ci}
34701cb0ef41Sopenharmony_ci
34711cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
34721cb0ef41Sopenharmony_ci  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
34731cb0ef41Sopenharmony_ci}
34741cb0ef41Sopenharmony_ci
34751cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfNotUndefined() {
34761cb0ef41Sopenharmony_ci  BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
34771cb0ef41Sopenharmony_ci}
34781cb0ef41Sopenharmony_ci
34791cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
34801cb0ef41Sopenharmony_ci  BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
34811cb0ef41Sopenharmony_ci}
34821cb0ef41Sopenharmony_ci
34831cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfUndefinedOrNull() {
34841cb0ef41Sopenharmony_ci  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
34851cb0ef41Sopenharmony_ci  BuildJumpIfEqual(jsgraph()->NullConstant());
34861cb0ef41Sopenharmony_ci}
34871cb0ef41Sopenharmony_ci
34881cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpIfUndefinedOrNullConstant() {
34891cb0ef41Sopenharmony_ci  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
34901cb0ef41Sopenharmony_ci  BuildJumpIfEqual(jsgraph()->NullConstant());
34911cb0ef41Sopenharmony_ci}
34921cb0ef41Sopenharmony_ci
34931cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitJumpLoop() {
34941cb0ef41Sopenharmony_ci  BuildIterationBodyStackCheck();
34951cb0ef41Sopenharmony_ci  BuildJump();
34961cb0ef41Sopenharmony_ci}
34971cb0ef41Sopenharmony_ci
34981cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildSwitchOnSmi(Node* condition) {
34991cb0ef41Sopenharmony_ci  interpreter::JumpTableTargetOffsets offsets =
35001cb0ef41Sopenharmony_ci      bytecode_iterator().GetJumpTableTargetOffsets();
35011cb0ef41Sopenharmony_ci
35021cb0ef41Sopenharmony_ci  NewSwitch(condition, offsets.size() + 1);
35031cb0ef41Sopenharmony_ci  for (interpreter::JumpTableTargetOffset entry : offsets) {
35041cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
35051cb0ef41Sopenharmony_ci    NewIfValue(entry.case_value);
35061cb0ef41Sopenharmony_ci    MergeIntoSuccessorEnvironment(entry.target_offset);
35071cb0ef41Sopenharmony_ci  }
35081cb0ef41Sopenharmony_ci  NewIfDefault();
35091cb0ef41Sopenharmony_ci}
35101cb0ef41Sopenharmony_ci
35111cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
35121cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
35131cb0ef41Sopenharmony_ci
35141cb0ef41Sopenharmony_ci  Node* acc = environment()->LookupAccumulator();
35151cb0ef41Sopenharmony_ci  Node* acc_smi = NewNode(simplified()->CheckSmi(FeedbackSource()), acc);
35161cb0ef41Sopenharmony_ci  BuildSwitchOnSmi(acc_smi);
35171cb0ef41Sopenharmony_ci}
35181cb0ef41Sopenharmony_ci
35191cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSetPendingMessage() {
35201cb0ef41Sopenharmony_ci  Node* previous_message = NewNode(javascript()->LoadMessage());
35211cb0ef41Sopenharmony_ci  NewNode(javascript()->StoreMessage(), environment()->LookupAccumulator());
35221cb0ef41Sopenharmony_ci  environment()->BindAccumulator(previous_message);
35231cb0ef41Sopenharmony_ci}
35241cb0ef41Sopenharmony_ci
35251cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildReturn(const BytecodeLivenessState* liveness) {
35261cb0ef41Sopenharmony_ci  BuildLoopExitsForFunctionExit(liveness);
35271cb0ef41Sopenharmony_ci  Node* pop_node = jsgraph()->ZeroConstant();
35281cb0ef41Sopenharmony_ci  Node* control =
35291cb0ef41Sopenharmony_ci      NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
35301cb0ef41Sopenharmony_ci  MergeControlToLeaveFunction(control);
35311cb0ef41Sopenharmony_ci}
35321cb0ef41Sopenharmony_ci
35331cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitReturn() {
35341cb0ef41Sopenharmony_ci  BuildReturn(bytecode_analysis().GetInLivenessFor(
35351cb0ef41Sopenharmony_ci      bytecode_iterator().current_offset()));
35361cb0ef41Sopenharmony_ci}
35371cb0ef41Sopenharmony_ci
35381cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitDebugger() {
35391cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
35401cb0ef41Sopenharmony_ci  Node* call = NewNode(javascript()->Debugger());
35411cb0ef41Sopenharmony_ci  environment()->RecordAfterState(call, Environment::kAttachFrameState);
35421cb0ef41Sopenharmony_ci}
35431cb0ef41Sopenharmony_ci
35441cb0ef41Sopenharmony_ci// We cannot create a graph from the debugger copy of the bytecode array.
35451cb0ef41Sopenharmony_ci#define DEBUG_BREAK(Name, ...) \
35461cb0ef41Sopenharmony_ci  void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
35471cb0ef41Sopenharmony_ciDEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK)
35481cb0ef41Sopenharmony_ci#undef DEBUG_BREAK
35491cb0ef41Sopenharmony_ci
35501cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitIncBlockCounter() {
35511cb0ef41Sopenharmony_ci  Node* closure = GetFunctionClosure();
35521cb0ef41Sopenharmony_ci  Node* coverage_array_slot =
35531cb0ef41Sopenharmony_ci      jsgraph()->Constant(bytecode_iterator().GetIndexOperand(0));
35541cb0ef41Sopenharmony_ci
35551cb0ef41Sopenharmony_ci  // Lowered by js-intrinsic-lowering to call Builtin::kIncBlockCounter.
35561cb0ef41Sopenharmony_ci  const Operator* op =
35571cb0ef41Sopenharmony_ci      javascript()->CallRuntime(Runtime::kInlineIncBlockCounter);
35581cb0ef41Sopenharmony_ci
35591cb0ef41Sopenharmony_ci  NewNode(op, closure, coverage_array_slot);
35601cb0ef41Sopenharmony_ci}
35611cb0ef41Sopenharmony_ci
35621cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitForInEnumerate() {
35631cb0ef41Sopenharmony_ci  Node* receiver =
35641cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
35651cb0ef41Sopenharmony_ci  Node* enumerator = NewNode(javascript()->ForInEnumerate(), receiver);
35661cb0ef41Sopenharmony_ci  environment()->BindAccumulator(enumerator, Environment::kAttachFrameState);
35671cb0ef41Sopenharmony_ci}
35681cb0ef41Sopenharmony_ci
35691cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitForInPrepare() {
35701cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
35711cb0ef41Sopenharmony_ci  Node* enumerator = environment()->LookupAccumulator();
35721cb0ef41Sopenharmony_ci
35731cb0ef41Sopenharmony_ci  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
35741cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering =
35751cb0ef41Sopenharmony_ci      TryBuildSimplifiedForInPrepare(enumerator, slot);
35761cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
35771cb0ef41Sopenharmony_ci  DCHECK(!lowering.Changed());
35781cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(slot);
35791cb0ef41Sopenharmony_ci  Node* node = NewNode(javascript()->ForInPrepare(GetForInMode(slot), feedback),
35801cb0ef41Sopenharmony_ci                       enumerator, feedback_vector_node());
35811cb0ef41Sopenharmony_ci  environment()->BindRegistersToProjections(
35821cb0ef41Sopenharmony_ci      bytecode_iterator().GetRegisterOperand(0), node);
35831cb0ef41Sopenharmony_ci}
35841cb0ef41Sopenharmony_ci
35851cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitForInContinue() {
35861cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
35871cb0ef41Sopenharmony_ci  Node* index =
35881cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
35891cb0ef41Sopenharmony_ci  Node* cache_length =
35901cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
35911cb0ef41Sopenharmony_ci  Node* exit_cond = NewNode(simplified()->SpeculativeNumberLessThan(
35921cb0ef41Sopenharmony_ci                                NumberOperationHint::kSignedSmall),
35931cb0ef41Sopenharmony_ci                            index, cache_length);
35941cb0ef41Sopenharmony_ci  environment()->BindAccumulator(exit_cond);
35951cb0ef41Sopenharmony_ci}
35961cb0ef41Sopenharmony_ci
35971cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitForInNext() {
35981cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
35991cb0ef41Sopenharmony_ci  Node* receiver =
36001cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
36011cb0ef41Sopenharmony_ci  Node* index =
36021cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
36031cb0ef41Sopenharmony_ci  int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
36041cb0ef41Sopenharmony_ci  Node* cache_type = environment()->LookupRegister(
36051cb0ef41Sopenharmony_ci      interpreter::Register(catch_reg_pair_index));
36061cb0ef41Sopenharmony_ci  Node* cache_array = environment()->LookupRegister(
36071cb0ef41Sopenharmony_ci      interpreter::Register(catch_reg_pair_index + 1));
36081cb0ef41Sopenharmony_ci
36091cb0ef41Sopenharmony_ci  // We need to rename the {index} here, as in case of OSR we lose the
36101cb0ef41Sopenharmony_ci  // information that the {index} is always a valid unsigned Smi value.
36111cb0ef41Sopenharmony_ci  index = NewNode(common()->TypeGuard(Type::UnsignedSmall()), index);
36121cb0ef41Sopenharmony_ci
36131cb0ef41Sopenharmony_ci  FeedbackSlot slot = bytecode_iterator().GetSlotOperand(3);
36141cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedForInNext(
36151cb0ef41Sopenharmony_ci      receiver, cache_array, cache_type, index, slot);
36161cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
36171cb0ef41Sopenharmony_ci
36181cb0ef41Sopenharmony_ci  DCHECK(!lowering.Changed());
36191cb0ef41Sopenharmony_ci  FeedbackSource feedback = CreateFeedbackSource(slot);
36201cb0ef41Sopenharmony_ci  Node* node =
36211cb0ef41Sopenharmony_ci      NewNode(javascript()->ForInNext(GetForInMode(slot), feedback), receiver,
36221cb0ef41Sopenharmony_ci              cache_array, cache_type, index, feedback_vector_node());
36231cb0ef41Sopenharmony_ci  environment()->BindAccumulator(node, Environment::kAttachFrameState);
36241cb0ef41Sopenharmony_ci}
36251cb0ef41Sopenharmony_ci
36261cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitForInStep() {
36271cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
36281cb0ef41Sopenharmony_ci  Node* index =
36291cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
36301cb0ef41Sopenharmony_ci  index = NewNode(simplified()->SpeculativeSafeIntegerAdd(
36311cb0ef41Sopenharmony_ci                      NumberOperationHint::kSignedSmall),
36321cb0ef41Sopenharmony_ci                  index, jsgraph()->OneConstant());
36331cb0ef41Sopenharmony_ci  environment()->BindAccumulator(index, Environment::kAttachFrameState);
36341cb0ef41Sopenharmony_ci}
36351cb0ef41Sopenharmony_ci
36361cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitGetIterator() {
36371cb0ef41Sopenharmony_ci  PrepareEagerCheckpoint();
36381cb0ef41Sopenharmony_ci  Node* receiver =
36391cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
36401cb0ef41Sopenharmony_ci  FeedbackSource load_feedback =
36411cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
36421cb0ef41Sopenharmony_ci  FeedbackSource call_feedback =
36431cb0ef41Sopenharmony_ci      CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
36441cb0ef41Sopenharmony_ci  const Operator* op = javascript()->GetIterator(load_feedback, call_feedback);
36451cb0ef41Sopenharmony_ci
36461cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedGetIterator(
36471cb0ef41Sopenharmony_ci      op, receiver, load_feedback.slot, call_feedback.slot);
36481cb0ef41Sopenharmony_ci  if (lowering.IsExit()) return;
36491cb0ef41Sopenharmony_ci
36501cb0ef41Sopenharmony_ci  DCHECK(!lowering.Changed());
36511cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSGetIteratorNode::ReceiverIndex() == 0);
36521cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSGetIteratorNode::FeedbackVectorIndex() == 1);
36531cb0ef41Sopenharmony_ci  DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
36541cb0ef41Sopenharmony_ci  Node* iterator = NewNode(op, receiver, feedback_vector_node());
36551cb0ef41Sopenharmony_ci  environment()->BindAccumulator(iterator, Environment::kAttachFrameState);
36561cb0ef41Sopenharmony_ci}
36571cb0ef41Sopenharmony_ci
36581cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSuspendGenerator() {
36591cb0ef41Sopenharmony_ci  Node* generator = environment()->LookupRegister(
36601cb0ef41Sopenharmony_ci      bytecode_iterator().GetRegisterOperand(0));
36611cb0ef41Sopenharmony_ci  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
36621cb0ef41Sopenharmony_ci  // We assume we are storing a range starting from index 0.
36631cb0ef41Sopenharmony_ci  CHECK_EQ(0, first_reg.index());
36641cb0ef41Sopenharmony_ci  int register_count =
36651cb0ef41Sopenharmony_ci      static_cast<int>(bytecode_iterator().GetRegisterCountOperand(2));
36661cb0ef41Sopenharmony_ci  int parameter_count_without_receiver = bytecode_array().parameter_count() - 1;
36671cb0ef41Sopenharmony_ci
36681cb0ef41Sopenharmony_ci  Node* suspend_id = jsgraph()->SmiConstant(
36691cb0ef41Sopenharmony_ci      bytecode_iterator().GetUnsignedImmediateOperand(3));
36701cb0ef41Sopenharmony_ci
36711cb0ef41Sopenharmony_ci  // The offsets used by the bytecode iterator are relative to a different base
36721cb0ef41Sopenharmony_ci  // than what is used in the interpreter, hence the addition.
36731cb0ef41Sopenharmony_ci  Node* offset =
36741cb0ef41Sopenharmony_ci      jsgraph()->Constant(bytecode_iterator().current_offset() +
36751cb0ef41Sopenharmony_ci                          (BytecodeArray::kHeaderSize - kHeapObjectTag));
36761cb0ef41Sopenharmony_ci
36771cb0ef41Sopenharmony_ci  const BytecodeLivenessState* liveness = bytecode_analysis().GetInLivenessFor(
36781cb0ef41Sopenharmony_ci      bytecode_iterator().current_offset());
36791cb0ef41Sopenharmony_ci
36801cb0ef41Sopenharmony_ci  // Maybe overallocate the value list since we don't know how many registers
36811cb0ef41Sopenharmony_ci  // are live.
36821cb0ef41Sopenharmony_ci  // TODO(leszeks): We could get this count from liveness rather than the
36831cb0ef41Sopenharmony_ci  // register list.
36841cb0ef41Sopenharmony_ci  int value_input_count = 3 + parameter_count_without_receiver + register_count;
36851cb0ef41Sopenharmony_ci
36861cb0ef41Sopenharmony_ci  Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
36871cb0ef41Sopenharmony_ci  value_inputs[0] = generator;
36881cb0ef41Sopenharmony_ci  value_inputs[1] = suspend_id;
36891cb0ef41Sopenharmony_ci  value_inputs[2] = offset;
36901cb0ef41Sopenharmony_ci
36911cb0ef41Sopenharmony_ci  int count_written = 0;
36921cb0ef41Sopenharmony_ci  // Store the parameters.
36931cb0ef41Sopenharmony_ci  for (int i = 0; i < parameter_count_without_receiver; i++) {
36941cb0ef41Sopenharmony_ci    value_inputs[3 + count_written++] =
36951cb0ef41Sopenharmony_ci        environment()->LookupRegister(bytecode_iterator().GetParameter(i));
36961cb0ef41Sopenharmony_ci  }
36971cb0ef41Sopenharmony_ci
36981cb0ef41Sopenharmony_ci  // Store the registers.
36991cb0ef41Sopenharmony_ci  for (int i = 0; i < register_count; ++i) {
37001cb0ef41Sopenharmony_ci    if (liveness == nullptr || liveness->RegisterIsLive(i)) {
37011cb0ef41Sopenharmony_ci      int index_in_parameters_and_registers =
37021cb0ef41Sopenharmony_ci          parameter_count_without_receiver + i;
37031cb0ef41Sopenharmony_ci      while (count_written < index_in_parameters_and_registers) {
37041cb0ef41Sopenharmony_ci        value_inputs[3 + count_written++] = jsgraph()->OptimizedOutConstant();
37051cb0ef41Sopenharmony_ci      }
37061cb0ef41Sopenharmony_ci      value_inputs[3 + count_written++] =
37071cb0ef41Sopenharmony_ci          environment()->LookupRegister(interpreter::Register(i));
37081cb0ef41Sopenharmony_ci      DCHECK_EQ(count_written, index_in_parameters_and_registers + 1);
37091cb0ef41Sopenharmony_ci    }
37101cb0ef41Sopenharmony_ci  }
37111cb0ef41Sopenharmony_ci
37121cb0ef41Sopenharmony_ci  // Use the actual written count rather than the register count to create the
37131cb0ef41Sopenharmony_ci  // node.
37141cb0ef41Sopenharmony_ci  MakeNode(javascript()->GeneratorStore(count_written), 3 + count_written,
37151cb0ef41Sopenharmony_ci           value_inputs, false);
37161cb0ef41Sopenharmony_ci
37171cb0ef41Sopenharmony_ci  // TODO(leszeks): This over-approximates the liveness at exit, only the
37181cb0ef41Sopenharmony_ci  // accumulator should be live by this point.
37191cb0ef41Sopenharmony_ci  BuildReturn(bytecode_analysis().GetInLivenessFor(
37201cb0ef41Sopenharmony_ci      bytecode_iterator().current_offset()));
37211cb0ef41Sopenharmony_ci}
37221cb0ef41Sopenharmony_ci
37231cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildSwitchOnGeneratorState(
37241cb0ef41Sopenharmony_ci    const ZoneVector<ResumeJumpTarget>& resume_jump_targets,
37251cb0ef41Sopenharmony_ci    bool allow_fallthrough_on_executing) {
37261cb0ef41Sopenharmony_ci  Node* generator_state = environment()->LookupGeneratorState();
37271cb0ef41Sopenharmony_ci
37281cb0ef41Sopenharmony_ci  int extra_cases = allow_fallthrough_on_executing ? 2 : 1;
37291cb0ef41Sopenharmony_ci  NewSwitch(generator_state,
37301cb0ef41Sopenharmony_ci            static_cast<int>(resume_jump_targets.size() + extra_cases));
37311cb0ef41Sopenharmony_ci  for (const ResumeJumpTarget& target : resume_jump_targets) {
37321cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
37331cb0ef41Sopenharmony_ci    NewIfValue(target.suspend_id());
37341cb0ef41Sopenharmony_ci    if (target.is_leaf()) {
37351cb0ef41Sopenharmony_ci      // Mark that we are resuming executing.
37361cb0ef41Sopenharmony_ci      environment()->BindGeneratorState(
37371cb0ef41Sopenharmony_ci          jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
37381cb0ef41Sopenharmony_ci    }
37391cb0ef41Sopenharmony_ci    // Jump to the target offset, whether it's a loop header or the resume.
37401cb0ef41Sopenharmony_ci    MergeIntoSuccessorEnvironment(target.target_offset());
37411cb0ef41Sopenharmony_ci  }
37421cb0ef41Sopenharmony_ci
37431cb0ef41Sopenharmony_ci  {
37441cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
37451cb0ef41Sopenharmony_ci    // We should never hit the default case (assuming generator state cannot be
37461cb0ef41Sopenharmony_ci    // corrupted), so abort if we do.
37471cb0ef41Sopenharmony_ci    // TODO(leszeks): Maybe only check this in debug mode, and otherwise use
37481cb0ef41Sopenharmony_ci    // the default to represent one of the cases above/fallthrough below?
37491cb0ef41Sopenharmony_ci    NewIfDefault();
37501cb0ef41Sopenharmony_ci    NewNode(simplified()->RuntimeAbort(AbortReason::kInvalidJumpTableIndex));
37511cb0ef41Sopenharmony_ci    // TODO(7099): Investigate if we need LoopExit here.
37521cb0ef41Sopenharmony_ci    Node* control = NewNode(common()->Throw());
37531cb0ef41Sopenharmony_ci    MergeControlToLeaveFunction(control);
37541cb0ef41Sopenharmony_ci  }
37551cb0ef41Sopenharmony_ci
37561cb0ef41Sopenharmony_ci  if (allow_fallthrough_on_executing) {
37571cb0ef41Sopenharmony_ci    // If we are executing (rather than resuming), and we allow it, just fall
37581cb0ef41Sopenharmony_ci    // through to the actual loop body.
37591cb0ef41Sopenharmony_ci    NewIfValue(JSGeneratorObject::kGeneratorExecuting);
37601cb0ef41Sopenharmony_ci  } else {
37611cb0ef41Sopenharmony_ci    // Otherwise, this environment is dead.
37621cb0ef41Sopenharmony_ci    set_environment(nullptr);
37631cb0ef41Sopenharmony_ci  }
37641cb0ef41Sopenharmony_ci}
37651cb0ef41Sopenharmony_ci
37661cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitSwitchOnGeneratorState() {
37671cb0ef41Sopenharmony_ci  Node* generator =
37681cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
37691cb0ef41Sopenharmony_ci
37701cb0ef41Sopenharmony_ci  Node* generator_is_undefined =
37711cb0ef41Sopenharmony_ci      NewNode(simplified()->ReferenceEqual(), generator,
37721cb0ef41Sopenharmony_ci              jsgraph()->UndefinedConstant());
37731cb0ef41Sopenharmony_ci
37741cb0ef41Sopenharmony_ci  NewBranch(generator_is_undefined);
37751cb0ef41Sopenharmony_ci  {
37761cb0ef41Sopenharmony_ci    SubEnvironment resume_env(this);
37771cb0ef41Sopenharmony_ci    NewIfFalse();
37781cb0ef41Sopenharmony_ci
37791cb0ef41Sopenharmony_ci    Node* generator_state =
37801cb0ef41Sopenharmony_ci        NewNode(javascript()->GeneratorRestoreContinuation(), generator);
37811cb0ef41Sopenharmony_ci    environment()->BindGeneratorState(generator_state);
37821cb0ef41Sopenharmony_ci
37831cb0ef41Sopenharmony_ci    Node* generator_context =
37841cb0ef41Sopenharmony_ci        NewNode(javascript()->GeneratorRestoreContext(), generator);
37851cb0ef41Sopenharmony_ci    environment()->SetContext(generator_context);
37861cb0ef41Sopenharmony_ci
37871cb0ef41Sopenharmony_ci    BuildSwitchOnGeneratorState(bytecode_analysis().resume_jump_targets(),
37881cb0ef41Sopenharmony_ci                                false);
37891cb0ef41Sopenharmony_ci  }
37901cb0ef41Sopenharmony_ci
37911cb0ef41Sopenharmony_ci  // Fallthrough for the first-call case.
37921cb0ef41Sopenharmony_ci  NewIfTrue();
37931cb0ef41Sopenharmony_ci}
37941cb0ef41Sopenharmony_ci
37951cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitResumeGenerator() {
37961cb0ef41Sopenharmony_ci  Node* generator =
37971cb0ef41Sopenharmony_ci      environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
37981cb0ef41Sopenharmony_ci  interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
37991cb0ef41Sopenharmony_ci  // We assume we are restoring registers starting fromm index 0.
38001cb0ef41Sopenharmony_ci  CHECK_EQ(0, first_reg.index());
38011cb0ef41Sopenharmony_ci
38021cb0ef41Sopenharmony_ci  const BytecodeLivenessState* liveness = bytecode_analysis().GetOutLivenessFor(
38031cb0ef41Sopenharmony_ci      bytecode_iterator().current_offset());
38041cb0ef41Sopenharmony_ci
38051cb0ef41Sopenharmony_ci  int parameter_count_without_receiver = bytecode_array().parameter_count() - 1;
38061cb0ef41Sopenharmony_ci
38071cb0ef41Sopenharmony_ci  // Mapping between registers and array indices must match that used in
38081cb0ef41Sopenharmony_ci  // InterpreterAssembler::ExportParametersAndRegisterFile.
38091cb0ef41Sopenharmony_ci  for (int i = 0; i < environment()->register_count(); ++i) {
38101cb0ef41Sopenharmony_ci    if (liveness == nullptr || liveness->RegisterIsLive(i)) {
38111cb0ef41Sopenharmony_ci      Node* value = NewNode(javascript()->GeneratorRestoreRegister(
38121cb0ef41Sopenharmony_ci                                parameter_count_without_receiver + i),
38131cb0ef41Sopenharmony_ci                            generator);
38141cb0ef41Sopenharmony_ci      environment()->BindRegister(interpreter::Register(i), value);
38151cb0ef41Sopenharmony_ci    }
38161cb0ef41Sopenharmony_ci  }
38171cb0ef41Sopenharmony_ci
38181cb0ef41Sopenharmony_ci  // Update the accumulator with the generator's input_or_debug_pos.
38191cb0ef41Sopenharmony_ci  Node* input_or_debug_pos =
38201cb0ef41Sopenharmony_ci      NewNode(javascript()->GeneratorRestoreInputOrDebugPos(), generator);
38211cb0ef41Sopenharmony_ci  environment()->BindAccumulator(input_or_debug_pos);
38221cb0ef41Sopenharmony_ci}
38231cb0ef41Sopenharmony_ci
38241cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitWide() {
38251cb0ef41Sopenharmony_ci  // Consumed by the BytecodeArrayIterator.
38261cb0ef41Sopenharmony_ci  UNREACHABLE();
38271cb0ef41Sopenharmony_ci}
38281cb0ef41Sopenharmony_ci
38291cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitExtraWide() {
38301cb0ef41Sopenharmony_ci  // Consumed by the BytecodeArrayIterator.
38311cb0ef41Sopenharmony_ci  UNREACHABLE();
38321cb0ef41Sopenharmony_ci}
38331cb0ef41Sopenharmony_ci
38341cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::VisitIllegal() {
38351cb0ef41Sopenharmony_ci  // Not emitted in valid bytecode.
38361cb0ef41Sopenharmony_ci  UNREACHABLE();
38371cb0ef41Sopenharmony_ci}
38381cb0ef41Sopenharmony_ci
38391cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
38401cb0ef41Sopenharmony_ci  auto it = merge_environments_.find(current_offset);
38411cb0ef41Sopenharmony_ci  if (it != merge_environments_.end()) {
38421cb0ef41Sopenharmony_ci    mark_as_needing_eager_checkpoint(true);
38431cb0ef41Sopenharmony_ci    if (environment() != nullptr) {
38441cb0ef41Sopenharmony_ci      it->second->Merge(environment(),
38451cb0ef41Sopenharmony_ci                        bytecode_analysis().GetInLivenessFor(current_offset));
38461cb0ef41Sopenharmony_ci    }
38471cb0ef41Sopenharmony_ci    set_environment(it->second);
38481cb0ef41Sopenharmony_ci  }
38491cb0ef41Sopenharmony_ci}
38501cb0ef41Sopenharmony_ci
38511cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
38521cb0ef41Sopenharmony_ci  if (bytecode_analysis().IsLoopHeader(current_offset)) {
38531cb0ef41Sopenharmony_ci    mark_as_needing_eager_checkpoint(true);
38541cb0ef41Sopenharmony_ci    const LoopInfo& loop_info =
38551cb0ef41Sopenharmony_ci        bytecode_analysis().GetLoopInfoFor(current_offset);
38561cb0ef41Sopenharmony_ci    const BytecodeLivenessState* liveness =
38571cb0ef41Sopenharmony_ci        bytecode_analysis().GetInLivenessFor(current_offset);
38581cb0ef41Sopenharmony_ci
38591cb0ef41Sopenharmony_ci    const auto& resume_jump_targets = loop_info.resume_jump_targets();
38601cb0ef41Sopenharmony_ci    bool generate_suspend_switch = !resume_jump_targets.empty();
38611cb0ef41Sopenharmony_ci
38621cb0ef41Sopenharmony_ci    // Add loop header.
38631cb0ef41Sopenharmony_ci    environment()->PrepareForLoop(loop_info.assignments(), liveness);
38641cb0ef41Sopenharmony_ci
38651cb0ef41Sopenharmony_ci    // Store a copy of the environment so we can connect merged back edge inputs
38661cb0ef41Sopenharmony_ci    // to the loop header.
38671cb0ef41Sopenharmony_ci    merge_environments_[current_offset] = environment()->Copy();
38681cb0ef41Sopenharmony_ci
38691cb0ef41Sopenharmony_ci    // If this loop contains resumes, create a new switch just after the loop
38701cb0ef41Sopenharmony_ci    // for those resumes.
38711cb0ef41Sopenharmony_ci    if (generate_suspend_switch) {
38721cb0ef41Sopenharmony_ci      BuildSwitchOnGeneratorState(loop_info.resume_jump_targets(), true);
38731cb0ef41Sopenharmony_ci
38741cb0ef41Sopenharmony_ci      // TODO(leszeks): At this point we know we are executing rather than
38751cb0ef41Sopenharmony_ci      // resuming, so we should be able to prune off the phis in the environment
38761cb0ef41Sopenharmony_ci      // related to the resume path.
38771cb0ef41Sopenharmony_ci
38781cb0ef41Sopenharmony_ci      // Set the generator state to a known constant.
38791cb0ef41Sopenharmony_ci      environment()->BindGeneratorState(
38801cb0ef41Sopenharmony_ci          jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
38811cb0ef41Sopenharmony_ci    }
38821cb0ef41Sopenharmony_ci  }
38831cb0ef41Sopenharmony_ci}
38841cb0ef41Sopenharmony_ci
38851cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
38861cb0ef41Sopenharmony_ci  BuildLoopExitsForBranch(target_offset);
38871cb0ef41Sopenharmony_ci  Environment*& merge_environment = merge_environments_[target_offset];
38881cb0ef41Sopenharmony_ci
38891cb0ef41Sopenharmony_ci  if (merge_environment == nullptr) {
38901cb0ef41Sopenharmony_ci    // Append merge nodes to the environment. We may merge here with another
38911cb0ef41Sopenharmony_ci    // environment. So add a place holder for merge nodes. We may add redundant
38921cb0ef41Sopenharmony_ci    // but will be eliminated in a later pass.
38931cb0ef41Sopenharmony_ci    NewMerge();
38941cb0ef41Sopenharmony_ci    merge_environment = environment();
38951cb0ef41Sopenharmony_ci  } else {
38961cb0ef41Sopenharmony_ci    // Merge any values which are live coming into the successor.
38971cb0ef41Sopenharmony_ci    merge_environment->Merge(
38981cb0ef41Sopenharmony_ci        environment(), bytecode_analysis().GetInLivenessFor(target_offset));
38991cb0ef41Sopenharmony_ci  }
39001cb0ef41Sopenharmony_ci  set_environment(nullptr);
39011cb0ef41Sopenharmony_ci}
39021cb0ef41Sopenharmony_ci
39031cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
39041cb0ef41Sopenharmony_ci  exit_controls_.push_back(exit);
39051cb0ef41Sopenharmony_ci  set_environment(nullptr);
39061cb0ef41Sopenharmony_ci}
39071cb0ef41Sopenharmony_ci
39081cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
39091cb0ef41Sopenharmony_ci  int origin_offset = bytecode_iterator().current_offset();
39101cb0ef41Sopenharmony_ci  // Only build loop exits for forward edges.
39111cb0ef41Sopenharmony_ci  if (target_offset > origin_offset) {
39121cb0ef41Sopenharmony_ci    BuildLoopExitsUntilLoop(
39131cb0ef41Sopenharmony_ci        bytecode_analysis().GetLoopOffsetFor(target_offset),
39141cb0ef41Sopenharmony_ci        bytecode_analysis().GetInLivenessFor(target_offset));
39151cb0ef41Sopenharmony_ci  }
39161cb0ef41Sopenharmony_ci}
39171cb0ef41Sopenharmony_ci
39181cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildLoopExitsUntilLoop(
39191cb0ef41Sopenharmony_ci    int loop_offset, const BytecodeLivenessState* liveness) {
39201cb0ef41Sopenharmony_ci  int origin_offset = bytecode_iterator().current_offset();
39211cb0ef41Sopenharmony_ci  int current_loop = bytecode_analysis().GetLoopOffsetFor(origin_offset);
39221cb0ef41Sopenharmony_ci  // The limit_offset is the stop offset for building loop exists, used for OSR.
39231cb0ef41Sopenharmony_ci  // It prevents the creations of loopexits for loops which do not exist.
39241cb0ef41Sopenharmony_ci  loop_offset = std::max(loop_offset, currently_peeled_loop_offset_);
39251cb0ef41Sopenharmony_ci
39261cb0ef41Sopenharmony_ci  while (loop_offset < current_loop) {
39271cb0ef41Sopenharmony_ci    Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
39281cb0ef41Sopenharmony_ci    const LoopInfo& loop_info =
39291cb0ef41Sopenharmony_ci        bytecode_analysis().GetLoopInfoFor(current_loop);
39301cb0ef41Sopenharmony_ci    environment()->PrepareForLoopExit(loop_node, loop_info.assignments(),
39311cb0ef41Sopenharmony_ci                                      liveness);
39321cb0ef41Sopenharmony_ci    current_loop = loop_info.parent_offset();
39331cb0ef41Sopenharmony_ci  }
39341cb0ef41Sopenharmony_ci}
39351cb0ef41Sopenharmony_ci
39361cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildLoopExitsForFunctionExit(
39371cb0ef41Sopenharmony_ci    const BytecodeLivenessState* liveness) {
39381cb0ef41Sopenharmony_ci  BuildLoopExitsUntilLoop(-1, liveness);
39391cb0ef41Sopenharmony_ci}
39401cb0ef41Sopenharmony_ci
39411cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJump() {
39421cb0ef41Sopenharmony_ci  MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
39431cb0ef41Sopenharmony_ci}
39441cb0ef41Sopenharmony_ci
39451cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
39461cb0ef41Sopenharmony_ci  NewBranch(condition, BranchHint::kNone);
39471cb0ef41Sopenharmony_ci  {
39481cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
39491cb0ef41Sopenharmony_ci    NewIfTrue();
39501cb0ef41Sopenharmony_ci    MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
39511cb0ef41Sopenharmony_ci  }
39521cb0ef41Sopenharmony_ci  NewIfFalse();
39531cb0ef41Sopenharmony_ci}
39541cb0ef41Sopenharmony_ci
39551cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
39561cb0ef41Sopenharmony_ci  NewBranch(condition, BranchHint::kNone);
39571cb0ef41Sopenharmony_ci  {
39581cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
39591cb0ef41Sopenharmony_ci    NewIfFalse();
39601cb0ef41Sopenharmony_ci    MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
39611cb0ef41Sopenharmony_ci  }
39621cb0ef41Sopenharmony_ci  NewIfTrue();
39631cb0ef41Sopenharmony_ci}
39641cb0ef41Sopenharmony_ci
39651cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
39661cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
39671cb0ef41Sopenharmony_ci  Node* condition =
39681cb0ef41Sopenharmony_ci      NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
39691cb0ef41Sopenharmony_ci  BuildJumpIf(condition);
39701cb0ef41Sopenharmony_ci}
39711cb0ef41Sopenharmony_ci
39721cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
39731cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
39741cb0ef41Sopenharmony_ci  Node* condition =
39751cb0ef41Sopenharmony_ci      NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
39761cb0ef41Sopenharmony_ci  BuildJumpIfNot(condition);
39771cb0ef41Sopenharmony_ci}
39781cb0ef41Sopenharmony_ci
39791cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfFalse() {
39801cb0ef41Sopenharmony_ci  NewBranch(environment()->LookupAccumulator(), BranchHint::kNone);
39811cb0ef41Sopenharmony_ci  {
39821cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
39831cb0ef41Sopenharmony_ci    NewIfFalse();
39841cb0ef41Sopenharmony_ci    environment()->BindAccumulator(jsgraph()->FalseConstant());
39851cb0ef41Sopenharmony_ci    MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
39861cb0ef41Sopenharmony_ci  }
39871cb0ef41Sopenharmony_ci  NewIfTrue();
39881cb0ef41Sopenharmony_ci  environment()->BindAccumulator(jsgraph()->TrueConstant());
39891cb0ef41Sopenharmony_ci}
39901cb0ef41Sopenharmony_ci
39911cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfTrue() {
39921cb0ef41Sopenharmony_ci  NewBranch(environment()->LookupAccumulator(), BranchHint::kNone);
39931cb0ef41Sopenharmony_ci  {
39941cb0ef41Sopenharmony_ci    SubEnvironment sub_environment(this);
39951cb0ef41Sopenharmony_ci    NewIfTrue();
39961cb0ef41Sopenharmony_ci    environment()->BindAccumulator(jsgraph()->TrueConstant());
39971cb0ef41Sopenharmony_ci    MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
39981cb0ef41Sopenharmony_ci  }
39991cb0ef41Sopenharmony_ci  NewIfFalse();
40001cb0ef41Sopenharmony_ci  environment()->BindAccumulator(jsgraph()->FalseConstant());
40011cb0ef41Sopenharmony_ci}
40021cb0ef41Sopenharmony_ci
40031cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
40041cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
40051cb0ef41Sopenharmony_ci  Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
40061cb0ef41Sopenharmony_ci  BuildJumpIf(condition);
40071cb0ef41Sopenharmony_ci}
40081cb0ef41Sopenharmony_ci
40091cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfToBooleanFalse() {
40101cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
40111cb0ef41Sopenharmony_ci  Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
40121cb0ef41Sopenharmony_ci  BuildJumpIfNot(condition);
40131cb0ef41Sopenharmony_ci}
40141cb0ef41Sopenharmony_ci
40151cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfNotHole() {
40161cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
40171cb0ef41Sopenharmony_ci  Node* condition = NewNode(simplified()->ReferenceEqual(), accumulator,
40181cb0ef41Sopenharmony_ci                            jsgraph()->TheHoleConstant());
40191cb0ef41Sopenharmony_ci  BuildJumpIfNot(condition);
40201cb0ef41Sopenharmony_ci}
40211cb0ef41Sopenharmony_ci
40221cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::BuildJumpIfJSReceiver() {
40231cb0ef41Sopenharmony_ci  Node* accumulator = environment()->LookupAccumulator();
40241cb0ef41Sopenharmony_ci  Node* condition = NewNode(simplified()->ObjectIsReceiver(), accumulator);
40251cb0ef41Sopenharmony_ci  BuildJumpIf(condition);
40261cb0ef41Sopenharmony_ci}
40271cb0ef41Sopenharmony_ci
40281cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
40291cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedUnaryOp(const Operator* op,
40301cb0ef41Sopenharmony_ci                                                Node* operand,
40311cb0ef41Sopenharmony_ci                                                FeedbackSlot slot) {
40321cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
40331cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
40341cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
40351cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceUnaryOperation(op, operand, effect, control,
40361cb0ef41Sopenharmony_ci                                                slot);
40371cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
40381cb0ef41Sopenharmony_ci  return result;
40391cb0ef41Sopenharmony_ci}
40401cb0ef41Sopenharmony_ci
40411cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
40421cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedBinaryOp(const Operator* op, Node* left,
40431cb0ef41Sopenharmony_ci                                                 Node* right,
40441cb0ef41Sopenharmony_ci                                                 FeedbackSlot slot) {
40451cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
40461cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
40471cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
40481cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceBinaryOperation(op, left, right, effect,
40491cb0ef41Sopenharmony_ci                                                 control, slot);
40501cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
40511cb0ef41Sopenharmony_ci  return result;
40521cb0ef41Sopenharmony_ci}
40531cb0ef41Sopenharmony_ci
40541cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
40551cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedForInNext(Node* receiver,
40561cb0ef41Sopenharmony_ci                                                  Node* cache_array,
40571cb0ef41Sopenharmony_ci                                                  Node* cache_type, Node* index,
40581cb0ef41Sopenharmony_ci                                                  FeedbackSlot slot) {
40591cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
40601cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
40611cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
40621cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceForInNextOperation(
40631cb0ef41Sopenharmony_ci          receiver, cache_array, cache_type, index, effect, control, slot);
40641cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
40651cb0ef41Sopenharmony_ci  return result;
40661cb0ef41Sopenharmony_ci}
40671cb0ef41Sopenharmony_ci
40681cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
40691cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedForInPrepare(Node* enumerator,
40701cb0ef41Sopenharmony_ci                                                     FeedbackSlot slot) {
40711cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
40721cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
40731cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
40741cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceForInPrepareOperation(enumerator, effect,
40751cb0ef41Sopenharmony_ci                                                       control, slot);
40761cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
40771cb0ef41Sopenharmony_ci  return result;
40781cb0ef41Sopenharmony_ci}
40791cb0ef41Sopenharmony_ci
40801cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
40811cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedToNumber(Node* value,
40821cb0ef41Sopenharmony_ci                                                 FeedbackSlot slot) {
40831cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
40841cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
40851cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
40861cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceToNumberOperation(value, effect, control,
40871cb0ef41Sopenharmony_ci                                                   slot);
40881cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
40891cb0ef41Sopenharmony_ci  return result;
40901cb0ef41Sopenharmony_ci}
40911cb0ef41Sopenharmony_ci
40921cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult BytecodeGraphBuilder::TryBuildSimplifiedCall(
40931cb0ef41Sopenharmony_ci    const Operator* op, Node* const* args, int arg_count, FeedbackSlot slot) {
40941cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
40951cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
40961cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
40971cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceCallOperation(op, args, arg_count, effect,
40981cb0ef41Sopenharmony_ci                                               control, slot);
40991cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
41001cb0ef41Sopenharmony_ci  return result;
41011cb0ef41Sopenharmony_ci}
41021cb0ef41Sopenharmony_ci
41031cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
41041cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedConstruct(const Operator* op,
41051cb0ef41Sopenharmony_ci                                                  Node* const* args,
41061cb0ef41Sopenharmony_ci                                                  int arg_count,
41071cb0ef41Sopenharmony_ci                                                  FeedbackSlot slot) {
41081cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
41091cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
41101cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
41111cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceConstructOperation(op, args, arg_count, effect,
41121cb0ef41Sopenharmony_ci                                                    control, slot);
41131cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
41141cb0ef41Sopenharmony_ci  return result;
41151cb0ef41Sopenharmony_ci}
41161cb0ef41Sopenharmony_ci
41171cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
41181cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedGetIterator(const Operator* op,
41191cb0ef41Sopenharmony_ci                                                    Node* receiver,
41201cb0ef41Sopenharmony_ci                                                    FeedbackSlot load_slot,
41211cb0ef41Sopenharmony_ci                                                    FeedbackSlot call_slot) {
41221cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
41231cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
41241cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult early_reduction =
41251cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceGetIteratorOperation(
41261cb0ef41Sopenharmony_ci          op, receiver, effect, control, load_slot, call_slot);
41271cb0ef41Sopenharmony_ci  ApplyEarlyReduction(early_reduction);
41281cb0ef41Sopenharmony_ci  return early_reduction;
41291cb0ef41Sopenharmony_ci}
41301cb0ef41Sopenharmony_ci
41311cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
41321cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op,
41331cb0ef41Sopenharmony_ci                                                  FeedbackSlot slot) {
41341cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
41351cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
41361cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult early_reduction =
41371cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceLoadNamedOperation(op, effect, control, slot);
41381cb0ef41Sopenharmony_ci  ApplyEarlyReduction(early_reduction);
41391cb0ef41Sopenharmony_ci  return early_reduction;
41401cb0ef41Sopenharmony_ci}
41411cb0ef41Sopenharmony_ci
41421cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
41431cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(const Operator* op,
41441cb0ef41Sopenharmony_ci                                                  Node* receiver, Node* key,
41451cb0ef41Sopenharmony_ci                                                  FeedbackSlot slot) {
41461cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
41471cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
41481cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
41491cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceLoadKeyedOperation(op, receiver, key, effect,
41501cb0ef41Sopenharmony_ci                                                    control, slot);
41511cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
41521cb0ef41Sopenharmony_ci  return result;
41531cb0ef41Sopenharmony_ci}
41541cb0ef41Sopenharmony_ci
41551cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
41561cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedStoreNamed(const Operator* op,
41571cb0ef41Sopenharmony_ci                                                   Node* receiver, Node* value,
41581cb0ef41Sopenharmony_ci                                                   FeedbackSlot slot) {
41591cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
41601cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
41611cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
41621cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceStoreNamedOperation(op, receiver, value,
41631cb0ef41Sopenharmony_ci                                                     effect, control, slot);
41641cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
41651cb0ef41Sopenharmony_ci  return result;
41661cb0ef41Sopenharmony_ci}
41671cb0ef41Sopenharmony_ci
41681cb0ef41Sopenharmony_ciJSTypeHintLowering::LoweringResult
41691cb0ef41Sopenharmony_ciBytecodeGraphBuilder::TryBuildSimplifiedStoreKeyed(const Operator* op,
41701cb0ef41Sopenharmony_ci                                                   Node* receiver, Node* key,
41711cb0ef41Sopenharmony_ci                                                   Node* value,
41721cb0ef41Sopenharmony_ci                                                   FeedbackSlot slot) {
41731cb0ef41Sopenharmony_ci  Node* effect = environment()->GetEffectDependency();
41741cb0ef41Sopenharmony_ci  Node* control = environment()->GetControlDependency();
41751cb0ef41Sopenharmony_ci  JSTypeHintLowering::LoweringResult result =
41761cb0ef41Sopenharmony_ci      type_hint_lowering().ReduceStoreKeyedOperation(op, receiver, key, value,
41771cb0ef41Sopenharmony_ci                                                     effect, control, slot);
41781cb0ef41Sopenharmony_ci  ApplyEarlyReduction(result);
41791cb0ef41Sopenharmony_ci  return result;
41801cb0ef41Sopenharmony_ci}
41811cb0ef41Sopenharmony_ci
41821cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::ApplyEarlyReduction(
41831cb0ef41Sopenharmony_ci    JSTypeHintLowering::LoweringResult reduction) {
41841cb0ef41Sopenharmony_ci  if (reduction.IsExit()) {
41851cb0ef41Sopenharmony_ci    MergeControlToLeaveFunction(reduction.control());
41861cb0ef41Sopenharmony_ci  } else if (reduction.IsSideEffectFree()) {
41871cb0ef41Sopenharmony_ci    environment()->UpdateEffectDependency(reduction.effect());
41881cb0ef41Sopenharmony_ci    environment()->UpdateControlDependency(reduction.control());
41891cb0ef41Sopenharmony_ci  } else {
41901cb0ef41Sopenharmony_ci    DCHECK(!reduction.Changed());
41911cb0ef41Sopenharmony_ci    // At the moment, we assume side-effect free reduction. To support
41921cb0ef41Sopenharmony_ci    // side-effects, we would have to invalidate the eager checkpoint,
41931cb0ef41Sopenharmony_ci    // so that deoptimization does not repeat the side effect.
41941cb0ef41Sopenharmony_ci  }
41951cb0ef41Sopenharmony_ci}
41961cb0ef41Sopenharmony_ci
41971cb0ef41Sopenharmony_ciNode** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
41981cb0ef41Sopenharmony_ci  if (size > input_buffer_size_) {
41991cb0ef41Sopenharmony_ci    size = size + kInputBufferSizeIncrement + input_buffer_size_;
42001cb0ef41Sopenharmony_ci    input_buffer_ = local_zone()->NewArray<Node*>(size);
42011cb0ef41Sopenharmony_ci    input_buffer_size_ = size;
42021cb0ef41Sopenharmony_ci  }
42031cb0ef41Sopenharmony_ci  return input_buffer_;
42041cb0ef41Sopenharmony_ci}
42051cb0ef41Sopenharmony_ci
42061cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::ExitThenEnterExceptionHandlers(int current_offset) {
42071cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
42081cb0ef41Sopenharmony_ci  HandlerTable table(bytecode_array().handler_table_address(),
42091cb0ef41Sopenharmony_ci                     bytecode_array().handler_table_size(),
42101cb0ef41Sopenharmony_ci                     HandlerTable::kRangeBasedEncoding);
42111cb0ef41Sopenharmony_ci
42121cb0ef41Sopenharmony_ci  // Potentially exit exception handlers.
42131cb0ef41Sopenharmony_ci  while (!exception_handlers_.empty()) {
42141cb0ef41Sopenharmony_ci    int current_end = exception_handlers_.top().end_offset_;
42151cb0ef41Sopenharmony_ci    if (current_offset < current_end) break;  // Still covered by range.
42161cb0ef41Sopenharmony_ci    exception_handlers_.pop();
42171cb0ef41Sopenharmony_ci  }
42181cb0ef41Sopenharmony_ci
42191cb0ef41Sopenharmony_ci  // Potentially enter exception handlers.
42201cb0ef41Sopenharmony_ci  int num_entries = table.NumberOfRangeEntries();
42211cb0ef41Sopenharmony_ci  while (current_exception_handler_ < num_entries) {
42221cb0ef41Sopenharmony_ci    int next_start = table.GetRangeStart(current_exception_handler_);
42231cb0ef41Sopenharmony_ci    if (current_offset < next_start) break;  // Not yet covered by range.
42241cb0ef41Sopenharmony_ci    int next_end = table.GetRangeEnd(current_exception_handler_);
42251cb0ef41Sopenharmony_ci    int next_handler = table.GetRangeHandler(current_exception_handler_);
42261cb0ef41Sopenharmony_ci    int context_register = table.GetRangeData(current_exception_handler_);
42271cb0ef41Sopenharmony_ci    exception_handlers_.push(
42281cb0ef41Sopenharmony_ci        {next_start, next_end, next_handler, context_register});
42291cb0ef41Sopenharmony_ci    current_exception_handler_++;
42301cb0ef41Sopenharmony_ci  }
42311cb0ef41Sopenharmony_ci}
42321cb0ef41Sopenharmony_ci
42331cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
42341cb0ef41Sopenharmony_ci                                     Node* const* value_inputs,
42351cb0ef41Sopenharmony_ci                                     bool incomplete) {
42361cb0ef41Sopenharmony_ci  DCHECK_EQ(op->ValueInputCount(), value_input_count);
42371cb0ef41Sopenharmony_ci  // Parameter nodes must be created through GetParameter.
42381cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(
42391cb0ef41Sopenharmony_ci      op->opcode() == IrOpcode::kParameter,
42401cb0ef41Sopenharmony_ci      (nullptr == cached_parameters_[static_cast<std::size_t>(
42411cb0ef41Sopenharmony_ci                      ParameterIndexOf(op) - ParameterInfo::kMinIndex)]));
42421cb0ef41Sopenharmony_ci
42431cb0ef41Sopenharmony_ci  bool has_context = OperatorProperties::HasContextInput(op);
42441cb0ef41Sopenharmony_ci  bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
42451cb0ef41Sopenharmony_ci  bool has_control = op->ControlInputCount() == 1;
42461cb0ef41Sopenharmony_ci  bool has_effect = op->EffectInputCount() == 1;
42471cb0ef41Sopenharmony_ci
42481cb0ef41Sopenharmony_ci  DCHECK_LT(op->ControlInputCount(), 2);
42491cb0ef41Sopenharmony_ci  DCHECK_LT(op->EffectInputCount(), 2);
42501cb0ef41Sopenharmony_ci
42511cb0ef41Sopenharmony_ci  Node* result = nullptr;
42521cb0ef41Sopenharmony_ci  if (!has_context && !has_frame_state && !has_control && !has_effect) {
42531cb0ef41Sopenharmony_ci    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
42541cb0ef41Sopenharmony_ci  } else {
42551cb0ef41Sopenharmony_ci    bool inside_handler = !exception_handlers_.empty();
42561cb0ef41Sopenharmony_ci    int input_count_with_deps = value_input_count;
42571cb0ef41Sopenharmony_ci    if (has_context) ++input_count_with_deps;
42581cb0ef41Sopenharmony_ci    if (has_frame_state) ++input_count_with_deps;
42591cb0ef41Sopenharmony_ci    if (has_control) ++input_count_with_deps;
42601cb0ef41Sopenharmony_ci    if (has_effect) ++input_count_with_deps;
42611cb0ef41Sopenharmony_ci    Node** buffer = EnsureInputBufferSize(input_count_with_deps);
42621cb0ef41Sopenharmony_ci    if (value_input_count > 0) {
42631cb0ef41Sopenharmony_ci      memcpy(buffer, value_inputs, kSystemPointerSize * value_input_count);
42641cb0ef41Sopenharmony_ci    }
42651cb0ef41Sopenharmony_ci    Node** current_input = buffer + value_input_count;
42661cb0ef41Sopenharmony_ci    if (has_context) {
42671cb0ef41Sopenharmony_ci      *current_input++ = OperatorProperties::NeedsExactContext(op)
42681cb0ef41Sopenharmony_ci                             ? environment()->Context()
42691cb0ef41Sopenharmony_ci                             : native_context_node();
42701cb0ef41Sopenharmony_ci    }
42711cb0ef41Sopenharmony_ci    if (has_frame_state) {
42721cb0ef41Sopenharmony_ci      // The frame state will be inserted later. Here we misuse the {Dead} node
42731cb0ef41Sopenharmony_ci      // as a sentinel to be later overwritten with the real frame state by the
42741cb0ef41Sopenharmony_ci      // calls to {PrepareFrameState} within individual visitor methods.
42751cb0ef41Sopenharmony_ci      *current_input++ = jsgraph()->Dead();
42761cb0ef41Sopenharmony_ci    }
42771cb0ef41Sopenharmony_ci    if (has_effect) {
42781cb0ef41Sopenharmony_ci      *current_input++ = environment()->GetEffectDependency();
42791cb0ef41Sopenharmony_ci    }
42801cb0ef41Sopenharmony_ci    if (has_control) {
42811cb0ef41Sopenharmony_ci      *current_input++ = environment()->GetControlDependency();
42821cb0ef41Sopenharmony_ci    }
42831cb0ef41Sopenharmony_ci    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
42841cb0ef41Sopenharmony_ci    // Update the current control dependency for control-producing nodes.
42851cb0ef41Sopenharmony_ci    if (result->op()->ControlOutputCount() > 0) {
42861cb0ef41Sopenharmony_ci      environment()->UpdateControlDependency(result);
42871cb0ef41Sopenharmony_ci    }
42881cb0ef41Sopenharmony_ci    // Update the current effect dependency for effect-producing nodes.
42891cb0ef41Sopenharmony_ci    if (result->op()->EffectOutputCount() > 0) {
42901cb0ef41Sopenharmony_ci      environment()->UpdateEffectDependency(result);
42911cb0ef41Sopenharmony_ci    }
42921cb0ef41Sopenharmony_ci    // Add implicit exception continuation for throwing nodes.
42931cb0ef41Sopenharmony_ci    if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
42941cb0ef41Sopenharmony_ci      int handler_offset = exception_handlers_.top().handler_offset_;
42951cb0ef41Sopenharmony_ci      int context_index = exception_handlers_.top().context_register_;
42961cb0ef41Sopenharmony_ci      interpreter::Register context_register(context_index);
42971cb0ef41Sopenharmony_ci      Environment* success_env = environment()->Copy();
42981cb0ef41Sopenharmony_ci      const Operator* if_exception = common()->IfException();
42991cb0ef41Sopenharmony_ci      Node* effect = environment()->GetEffectDependency();
43001cb0ef41Sopenharmony_ci      Node* on_exception = graph()->NewNode(if_exception, effect, result);
43011cb0ef41Sopenharmony_ci      Node* context = environment()->LookupRegister(context_register);
43021cb0ef41Sopenharmony_ci      environment()->UpdateControlDependency(on_exception);
43031cb0ef41Sopenharmony_ci      environment()->UpdateEffectDependency(on_exception);
43041cb0ef41Sopenharmony_ci      environment()->BindAccumulator(on_exception);
43051cb0ef41Sopenharmony_ci      environment()->SetContext(context);
43061cb0ef41Sopenharmony_ci      MergeIntoSuccessorEnvironment(handler_offset);
43071cb0ef41Sopenharmony_ci      set_environment(success_env);
43081cb0ef41Sopenharmony_ci    }
43091cb0ef41Sopenharmony_ci    // Add implicit success continuation for throwing nodes.
43101cb0ef41Sopenharmony_ci    if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
43111cb0ef41Sopenharmony_ci      const Operator* if_success = common()->IfSuccess();
43121cb0ef41Sopenharmony_ci      Node* on_success = graph()->NewNode(if_success, result);
43131cb0ef41Sopenharmony_ci      environment()->UpdateControlDependency(on_success);
43141cb0ef41Sopenharmony_ci    }
43151cb0ef41Sopenharmony_ci    // Ensure checkpoints are created after operations with side-effects.
43161cb0ef41Sopenharmony_ci    if (has_effect && !result->op()->HasProperty(Operator::kNoWrite)) {
43171cb0ef41Sopenharmony_ci      mark_as_needing_eager_checkpoint(true);
43181cb0ef41Sopenharmony_ci    }
43191cb0ef41Sopenharmony_ci  }
43201cb0ef41Sopenharmony_ci
43211cb0ef41Sopenharmony_ci  return result;
43221cb0ef41Sopenharmony_ci}
43231cb0ef41Sopenharmony_ci
43241cb0ef41Sopenharmony_ci
43251cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
43261cb0ef41Sopenharmony_ci  const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
43271cb0ef41Sopenharmony_ci  Node** buffer = EnsureInputBufferSize(count + 1);
43281cb0ef41Sopenharmony_ci  MemsetPointer(buffer, input, count);
43291cb0ef41Sopenharmony_ci  buffer[count] = control;
43301cb0ef41Sopenharmony_ci  return graph()->NewNode(phi_op, count + 1, buffer, true);
43311cb0ef41Sopenharmony_ci}
43321cb0ef41Sopenharmony_ci
43331cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
43341cb0ef41Sopenharmony_ci                                         Node* control) {
43351cb0ef41Sopenharmony_ci  const Operator* phi_op = common()->EffectPhi(count);
43361cb0ef41Sopenharmony_ci  Node** buffer = EnsureInputBufferSize(count + 1);
43371cb0ef41Sopenharmony_ci  MemsetPointer(buffer, input, count);
43381cb0ef41Sopenharmony_ci  buffer[count] = control;
43391cb0ef41Sopenharmony_ci  return graph()->NewNode(phi_op, count + 1, buffer, true);
43401cb0ef41Sopenharmony_ci}
43411cb0ef41Sopenharmony_ci
43421cb0ef41Sopenharmony_ci
43431cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
43441cb0ef41Sopenharmony_ci  int inputs = control->op()->ControlInputCount() + 1;
43451cb0ef41Sopenharmony_ci  if (control->opcode() == IrOpcode::kLoop) {
43461cb0ef41Sopenharmony_ci    // Control node for loop exists, add input.
43471cb0ef41Sopenharmony_ci    const Operator* op = common()->Loop(inputs);
43481cb0ef41Sopenharmony_ci    control->AppendInput(graph_zone(), other);
43491cb0ef41Sopenharmony_ci    NodeProperties::ChangeOp(control, op);
43501cb0ef41Sopenharmony_ci  } else if (control->opcode() == IrOpcode::kMerge) {
43511cb0ef41Sopenharmony_ci    // Control node for merge exists, add input.
43521cb0ef41Sopenharmony_ci    const Operator* op = common()->Merge(inputs);
43531cb0ef41Sopenharmony_ci    control->AppendInput(graph_zone(), other);
43541cb0ef41Sopenharmony_ci    NodeProperties::ChangeOp(control, op);
43551cb0ef41Sopenharmony_ci  } else {
43561cb0ef41Sopenharmony_ci    // Control node is a singleton, introduce a merge.
43571cb0ef41Sopenharmony_ci    const Operator* op = common()->Merge(inputs);
43581cb0ef41Sopenharmony_ci    Node* merge_inputs[] = {control, other};
43591cb0ef41Sopenharmony_ci    control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
43601cb0ef41Sopenharmony_ci  }
43611cb0ef41Sopenharmony_ci  return control;
43621cb0ef41Sopenharmony_ci}
43631cb0ef41Sopenharmony_ci
43641cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
43651cb0ef41Sopenharmony_ci                                        Node* control) {
43661cb0ef41Sopenharmony_ci  int inputs = control->op()->ControlInputCount();
43671cb0ef41Sopenharmony_ci  if (value->opcode() == IrOpcode::kEffectPhi &&
43681cb0ef41Sopenharmony_ci      NodeProperties::GetControlInput(value) == control) {
43691cb0ef41Sopenharmony_ci    // Phi already exists, add input.
43701cb0ef41Sopenharmony_ci    value->InsertInput(graph_zone(), inputs - 1, other);
43711cb0ef41Sopenharmony_ci    NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
43721cb0ef41Sopenharmony_ci  } else if (value != other) {
43731cb0ef41Sopenharmony_ci    // Phi does not exist yet, introduce one.
43741cb0ef41Sopenharmony_ci    value = NewEffectPhi(inputs, value, control);
43751cb0ef41Sopenharmony_ci    value->ReplaceInput(inputs - 1, other);
43761cb0ef41Sopenharmony_ci  }
43771cb0ef41Sopenharmony_ci  return value;
43781cb0ef41Sopenharmony_ci}
43791cb0ef41Sopenharmony_ci
43801cb0ef41Sopenharmony_ciNode* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
43811cb0ef41Sopenharmony_ci                                       Node* control) {
43821cb0ef41Sopenharmony_ci  int inputs = control->op()->ControlInputCount();
43831cb0ef41Sopenharmony_ci  if (value->opcode() == IrOpcode::kPhi &&
43841cb0ef41Sopenharmony_ci      NodeProperties::GetControlInput(value) == control) {
43851cb0ef41Sopenharmony_ci    // Phi already exists, add input.
43861cb0ef41Sopenharmony_ci    value->InsertInput(graph_zone(), inputs - 1, other);
43871cb0ef41Sopenharmony_ci    NodeProperties::ChangeOp(
43881cb0ef41Sopenharmony_ci        value, common()->Phi(MachineRepresentation::kTagged, inputs));
43891cb0ef41Sopenharmony_ci  } else if (value != other) {
43901cb0ef41Sopenharmony_ci    // Phi does not exist yet, introduce one.
43911cb0ef41Sopenharmony_ci    value = NewPhi(inputs, value, control);
43921cb0ef41Sopenharmony_ci    value->ReplaceInput(inputs - 1, other);
43931cb0ef41Sopenharmony_ci  }
43941cb0ef41Sopenharmony_ci  return value;
43951cb0ef41Sopenharmony_ci}
43961cb0ef41Sopenharmony_ci
43971cb0ef41Sopenharmony_civoid BytecodeGraphBuilder::UpdateSourcePosition(int offset) {
43981cb0ef41Sopenharmony_ci  if (source_position_iterator().done()) return;
43991cb0ef41Sopenharmony_ci  if (source_position_iterator().code_offset() == offset) {
44001cb0ef41Sopenharmony_ci    source_positions_->SetCurrentPosition(SourcePosition(
44011cb0ef41Sopenharmony_ci        source_position_iterator().source_position().ScriptOffset(),
44021cb0ef41Sopenharmony_ci        start_position_.InliningId()));
44031cb0ef41Sopenharmony_ci    source_position_iterator().Advance();
44041cb0ef41Sopenharmony_ci  } else {
44051cb0ef41Sopenharmony_ci    DCHECK_GT(source_position_iterator().code_offset(), offset);
44061cb0ef41Sopenharmony_ci  }
44071cb0ef41Sopenharmony_ci}
44081cb0ef41Sopenharmony_ci
44091cb0ef41Sopenharmony_civoid BuildGraphFromBytecode(JSHeapBroker* broker, Zone* local_zone,
44101cb0ef41Sopenharmony_ci                            SharedFunctionInfoRef const& shared_info,
44111cb0ef41Sopenharmony_ci                            FeedbackCellRef const& feedback_cell,
44121cb0ef41Sopenharmony_ci                            BytecodeOffset osr_offset, JSGraph* jsgraph,
44131cb0ef41Sopenharmony_ci                            CallFrequency const& invocation_frequency,
44141cb0ef41Sopenharmony_ci                            SourcePositionTable* source_positions,
44151cb0ef41Sopenharmony_ci                            int inlining_id, CodeKind code_kind,
44161cb0ef41Sopenharmony_ci                            BytecodeGraphBuilderFlags flags,
44171cb0ef41Sopenharmony_ci                            TickCounter* tick_counter,
44181cb0ef41Sopenharmony_ci                            ObserveNodeInfo const& observe_node_info) {
44191cb0ef41Sopenharmony_ci  BytecodeGraphBuilder builder(
44201cb0ef41Sopenharmony_ci      broker, local_zone, broker->target_native_context(), shared_info,
44211cb0ef41Sopenharmony_ci      feedback_cell, osr_offset, jsgraph, invocation_frequency,
44221cb0ef41Sopenharmony_ci      source_positions, inlining_id, code_kind, flags, tick_counter,
44231cb0ef41Sopenharmony_ci      observe_node_info);
44241cb0ef41Sopenharmony_ci  builder.CreateGraph();
44251cb0ef41Sopenharmony_ci}
44261cb0ef41Sopenharmony_ci
44271cb0ef41Sopenharmony_ci}  // namespace compiler
44281cb0ef41Sopenharmony_ci}  // namespace internal
44291cb0ef41Sopenharmony_ci}  // namespace v8
4430