11cb0ef41Sopenharmony_ci// Copyright 2014 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#ifndef V8_COMPILER_LINKAGE_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_LINKAGE_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/compiler-specific.h"
91cb0ef41Sopenharmony_ci#include "src/base/flags.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/interface-descriptors.h"
111cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/register.h"
131cb0ef41Sopenharmony_ci#include "src/codegen/reglist.h"
141cb0ef41Sopenharmony_ci#include "src/codegen/signature.h"
151cb0ef41Sopenharmony_ci#include "src/common/globals.h"
161cb0ef41Sopenharmony_ci#include "src/compiler/frame.h"
171cb0ef41Sopenharmony_ci#include "src/compiler/operator.h"
181cb0ef41Sopenharmony_ci#include "src/execution/encoded-c-signature.h"
191cb0ef41Sopenharmony_ci#include "src/runtime/runtime.h"
201cb0ef41Sopenharmony_ci#include "src/zone/zone.h"
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#if !defined(__clang__) && defined(_M_ARM64)
231cb0ef41Sopenharmony_ci// _M_ARM64 is an MSVC-specific macro that clang-cl emulates.
241cb0ef41Sopenharmony_ci#define NO_INLINE_FOR_ARM64_MSVC __declspec(noinline)
251cb0ef41Sopenharmony_ci#else
261cb0ef41Sopenharmony_ci#define NO_INLINE_FOR_ARM64_MSVC
271cb0ef41Sopenharmony_ci#endif
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_cinamespace v8 {
301cb0ef41Sopenharmony_ciclass CFunctionInfo;
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cinamespace internal {
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciclass CallInterfaceDescriptor;
351cb0ef41Sopenharmony_ciclass OptimizedCompilationInfo;
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cinamespace compiler {
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ciconstexpr RegList kNoCalleeSaved;
401cb0ef41Sopenharmony_ciconstexpr DoubleRegList kNoCalleeSavedFp;
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ciclass OsrHelper;
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci// Describes the location for a parameter or a return value to a call.
451cb0ef41Sopenharmony_ciclass LinkageLocation {
461cb0ef41Sopenharmony_ci public:
471cb0ef41Sopenharmony_ci  bool operator==(const LinkageLocation& other) const {
481cb0ef41Sopenharmony_ci    return bit_field_ == other.bit_field_ &&
491cb0ef41Sopenharmony_ci           machine_type_ == other.machine_type_;
501cb0ef41Sopenharmony_ci  }
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  bool operator!=(const LinkageLocation& other) const {
531cb0ef41Sopenharmony_ci    return !(*this == other);
541cb0ef41Sopenharmony_ci  }
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  static bool IsSameLocation(const LinkageLocation& a,
571cb0ef41Sopenharmony_ci                             const LinkageLocation& b) {
581cb0ef41Sopenharmony_ci    // Different MachineTypes may end up at the same physical location. With the
591cb0ef41Sopenharmony_ci    // sub-type check we make sure that types like {AnyTagged} and
601cb0ef41Sopenharmony_ci    // {TaggedPointer} which would end up with the same physical location are
611cb0ef41Sopenharmony_ci    // considered equal here.
621cb0ef41Sopenharmony_ci    return (a.bit_field_ == b.bit_field_) &&
631cb0ef41Sopenharmony_ci           (IsSubtype(a.machine_type_.representation(),
641cb0ef41Sopenharmony_ci                      b.machine_type_.representation()) ||
651cb0ef41Sopenharmony_ci            IsSubtype(b.machine_type_.representation(),
661cb0ef41Sopenharmony_ci                      a.machine_type_.representation()));
671cb0ef41Sopenharmony_ci  }
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  static LinkageLocation ForAnyRegister(
701cb0ef41Sopenharmony_ci      MachineType type = MachineType::None()) {
711cb0ef41Sopenharmony_ci    return LinkageLocation(REGISTER, ANY_REGISTER, type);
721cb0ef41Sopenharmony_ci  }
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  static LinkageLocation ForRegister(int32_t reg,
751cb0ef41Sopenharmony_ci                                     MachineType type = MachineType::None()) {
761cb0ef41Sopenharmony_ci    DCHECK_LE(0, reg);
771cb0ef41Sopenharmony_ci    return LinkageLocation(REGISTER, reg, type);
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  static LinkageLocation ForCallerFrameSlot(int32_t slot, MachineType type) {
811cb0ef41Sopenharmony_ci    DCHECK_GT(0, slot);
821cb0ef41Sopenharmony_ci    return LinkageLocation(STACK_SLOT, slot, type);
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  static LinkageLocation ForCalleeFrameSlot(int32_t slot, MachineType type) {
861cb0ef41Sopenharmony_ci    // TODO(titzer): bailout instead of crashing here.
871cb0ef41Sopenharmony_ci    DCHECK(slot >= 0 && slot < LinkageLocation::MAX_STACK_SLOT);
881cb0ef41Sopenharmony_ci    return LinkageLocation(STACK_SLOT, slot, type);
891cb0ef41Sopenharmony_ci  }
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  static LinkageLocation ForSavedCallerReturnAddress() {
921cb0ef41Sopenharmony_ci    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
931cb0ef41Sopenharmony_ci                               StandardFrameConstants::kCallerPCOffset) /
941cb0ef41Sopenharmony_ci                                  kSystemPointerSize,
951cb0ef41Sopenharmony_ci                              MachineType::Pointer());
961cb0ef41Sopenharmony_ci  }
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  static LinkageLocation ForSavedCallerFramePtr() {
991cb0ef41Sopenharmony_ci    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
1001cb0ef41Sopenharmony_ci                               StandardFrameConstants::kCallerFPOffset) /
1011cb0ef41Sopenharmony_ci                                  kSystemPointerSize,
1021cb0ef41Sopenharmony_ci                              MachineType::Pointer());
1031cb0ef41Sopenharmony_ci  }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  static LinkageLocation ForSavedCallerConstantPool() {
1061cb0ef41Sopenharmony_ci    DCHECK(V8_EMBEDDED_CONSTANT_POOL);
1071cb0ef41Sopenharmony_ci    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
1081cb0ef41Sopenharmony_ci                               StandardFrameConstants::kConstantPoolOffset) /
1091cb0ef41Sopenharmony_ci                                  kSystemPointerSize,
1101cb0ef41Sopenharmony_ci                              MachineType::AnyTagged());
1111cb0ef41Sopenharmony_ci  }
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  static LinkageLocation ForSavedCallerFunction() {
1141cb0ef41Sopenharmony_ci    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
1151cb0ef41Sopenharmony_ci                               StandardFrameConstants::kFunctionOffset) /
1161cb0ef41Sopenharmony_ci                                  kSystemPointerSize,
1171cb0ef41Sopenharmony_ci                              MachineType::AnyTagged());
1181cb0ef41Sopenharmony_ci  }
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  static LinkageLocation ConvertToTailCallerLocation(
1211cb0ef41Sopenharmony_ci      LinkageLocation caller_location, int stack_param_delta) {
1221cb0ef41Sopenharmony_ci    if (!caller_location.IsRegister()) {
1231cb0ef41Sopenharmony_ci      return LinkageLocation(STACK_SLOT,
1241cb0ef41Sopenharmony_ci                             caller_location.GetLocation() + stack_param_delta,
1251cb0ef41Sopenharmony_ci                             caller_location.GetType());
1261cb0ef41Sopenharmony_ci    }
1271cb0ef41Sopenharmony_ci    return caller_location;
1281cb0ef41Sopenharmony_ci  }
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  MachineType GetType() const { return machine_type_; }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  int GetSizeInPointers() const {
1331cb0ef41Sopenharmony_ci    return ElementSizeInPointers(GetType().representation());
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  int32_t GetLocation() const {
1371cb0ef41Sopenharmony_ci    // We can't use LocationField::decode here because it doesn't work for
1381cb0ef41Sopenharmony_ci    // negative values!
1391cb0ef41Sopenharmony_ci    return static_cast<int32_t>(bit_field_ & LocationField::kMask) >>
1401cb0ef41Sopenharmony_ci           LocationField::kShift;
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  NO_INLINE_FOR_ARM64_MSVC bool IsRegister() const {
1441cb0ef41Sopenharmony_ci    return TypeField::decode(bit_field_) == REGISTER;
1451cb0ef41Sopenharmony_ci  }
1461cb0ef41Sopenharmony_ci  bool IsAnyRegister() const {
1471cb0ef41Sopenharmony_ci    return IsRegister() && GetLocation() == ANY_REGISTER;
1481cb0ef41Sopenharmony_ci  }
1491cb0ef41Sopenharmony_ci  bool IsCallerFrameSlot() const { return !IsRegister() && GetLocation() < 0; }
1501cb0ef41Sopenharmony_ci  bool IsCalleeFrameSlot() const { return !IsRegister() && GetLocation() >= 0; }
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  int32_t AsRegister() const {
1531cb0ef41Sopenharmony_ci    DCHECK(IsRegister());
1541cb0ef41Sopenharmony_ci    return GetLocation();
1551cb0ef41Sopenharmony_ci  }
1561cb0ef41Sopenharmony_ci  int32_t AsCallerFrameSlot() const {
1571cb0ef41Sopenharmony_ci    DCHECK(IsCallerFrameSlot());
1581cb0ef41Sopenharmony_ci    return GetLocation();
1591cb0ef41Sopenharmony_ci  }
1601cb0ef41Sopenharmony_ci  int32_t AsCalleeFrameSlot() const {
1611cb0ef41Sopenharmony_ci    DCHECK(IsCalleeFrameSlot());
1621cb0ef41Sopenharmony_ci    return GetLocation();
1631cb0ef41Sopenharmony_ci  }
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci private:
1661cb0ef41Sopenharmony_ci  enum LocationType { REGISTER, STACK_SLOT };
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  using TypeField = base::BitField<LocationType, 0, 1>;
1691cb0ef41Sopenharmony_ci  using LocationField = TypeField::Next<int32_t, 31>;
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  static constexpr int32_t ANY_REGISTER = -1;
1721cb0ef41Sopenharmony_ci  static constexpr int32_t MAX_STACK_SLOT = 32767;
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  LinkageLocation(LocationType type, int32_t location,
1751cb0ef41Sopenharmony_ci                  MachineType machine_type) {
1761cb0ef41Sopenharmony_ci    bit_field_ = TypeField::encode(type) |
1771cb0ef41Sopenharmony_ci                 // {location} can be -1 (ANY_REGISTER).
1781cb0ef41Sopenharmony_ci                 ((static_cast<uint32_t>(location) << LocationField::kShift) &
1791cb0ef41Sopenharmony_ci                  LocationField::kMask);
1801cb0ef41Sopenharmony_ci    machine_type_ = machine_type;
1811cb0ef41Sopenharmony_ci  }
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  int32_t bit_field_;
1841cb0ef41Sopenharmony_ci  MachineType machine_type_;
1851cb0ef41Sopenharmony_ci};
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ciusing LocationSignature = Signature<LinkageLocation>;
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci// Describes a call to various parts of the compiler. Every call has the notion
1901cb0ef41Sopenharmony_ci// of a "target", which is the first input to the call.
1911cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CallDescriptor final
1921cb0ef41Sopenharmony_ci    : public NON_EXPORTED_BASE(ZoneObject) {
1931cb0ef41Sopenharmony_ci public:
1941cb0ef41Sopenharmony_ci  // Describes the kind of this call, which determines the target.
1951cb0ef41Sopenharmony_ci  enum Kind {
1961cb0ef41Sopenharmony_ci    kCallCodeObject,         // target is a Code object
1971cb0ef41Sopenharmony_ci    kCallJSFunction,         // target is a JSFunction object
1981cb0ef41Sopenharmony_ci    kCallAddress,            // target is a machine pointer
1991cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY    // ↓ WebAssembly only
2001cb0ef41Sopenharmony_ci    kCallWasmCapiFunction,   // target is a Wasm C API function
2011cb0ef41Sopenharmony_ci    kCallWasmFunction,       // target is a wasm function
2021cb0ef41Sopenharmony_ci    kCallWasmImportWrapper,  // target is a wasm import wrapper
2031cb0ef41Sopenharmony_ci#endif                       // ↑ WebAssembly only
2041cb0ef41Sopenharmony_ci    kCallBuiltinPointer,     // target is a builtin pointer
2051cb0ef41Sopenharmony_ci  };
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci  // NOTE: The lowest 10 bits of the Flags field are encoded in InstructionCode
2081cb0ef41Sopenharmony_ci  // (for use in the code generator). All higher bits are lost.
2091cb0ef41Sopenharmony_ci  static constexpr int kFlagsBitsEncodedInInstructionCode = 10;
2101cb0ef41Sopenharmony_ci  enum Flag {
2111cb0ef41Sopenharmony_ci    kNoFlags = 0u,
2121cb0ef41Sopenharmony_ci    kNeedsFrameState = 1u << 0,
2131cb0ef41Sopenharmony_ci    kHasExceptionHandler = 1u << 1,
2141cb0ef41Sopenharmony_ci    kCanUseRoots = 1u << 2,
2151cb0ef41Sopenharmony_ci    // Causes the code generator to initialize the root register.
2161cb0ef41Sopenharmony_ci    kInitializeRootRegister = 1u << 3,
2171cb0ef41Sopenharmony_ci    // Does not ever try to allocate space on our heap.
2181cb0ef41Sopenharmony_ci    kNoAllocate = 1u << 4,
2191cb0ef41Sopenharmony_ci    // Use the kJavaScriptCallCodeStartRegister (fixed) register for the
2201cb0ef41Sopenharmony_ci    // indirect target address when calling.
2211cb0ef41Sopenharmony_ci    kFixedTargetRegister = 1u << 5,
2221cb0ef41Sopenharmony_ci    kCallerSavedRegisters = 1u << 6,
2231cb0ef41Sopenharmony_ci    // The kCallerSavedFPRegisters only matters (and set) when the more general
2241cb0ef41Sopenharmony_ci    // flag for kCallerSavedRegisters above is also set.
2251cb0ef41Sopenharmony_ci    kCallerSavedFPRegisters = 1u << 7,
2261cb0ef41Sopenharmony_ci    // Tail calls for tier up are special (in fact they are different enough
2271cb0ef41Sopenharmony_ci    // from normal tail calls to warrant a dedicated opcode; but they also have
2281cb0ef41Sopenharmony_ci    // enough similar aspects that reusing the TailCall opcode is pragmatic).
2291cb0ef41Sopenharmony_ci    // Specifically:
2301cb0ef41Sopenharmony_ci    //
2311cb0ef41Sopenharmony_ci    // 1. Caller and callee are both JS-linkage Code objects.
2321cb0ef41Sopenharmony_ci    // 2. JS runtime arguments are passed unchanged from caller to callee.
2331cb0ef41Sopenharmony_ci    // 3. JS runtime arguments are not attached as inputs to the TailCall node.
2341cb0ef41Sopenharmony_ci    // 4. Prior to the tail call, frame and register state is torn down to just
2351cb0ef41Sopenharmony_ci    //    before the caller frame was constructed.
2361cb0ef41Sopenharmony_ci    // 5. Unlike normal tail calls, arguments adaptor frames (if present) are
2371cb0ef41Sopenharmony_ci    //    *not* torn down.
2381cb0ef41Sopenharmony_ci    //
2391cb0ef41Sopenharmony_ci    // In other words, behavior is identical to a jmp instruction prior caller
2401cb0ef41Sopenharmony_ci    // frame construction.
2411cb0ef41Sopenharmony_ci    kIsTailCallForTierUp = 1u << 8,
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci    // AIX has a function descriptor by default but it can be disabled for a
2441cb0ef41Sopenharmony_ci    // certain CFunction call (only used for Kind::kCallAddress).
2451cb0ef41Sopenharmony_ci    kNoFunctionDescriptor = 1u << 9,
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci    // Flags past here are *not* encoded in InstructionCode and are thus not
2481cb0ef41Sopenharmony_ci    // accessible from the code generator. See also
2491cb0ef41Sopenharmony_ci    // kFlagsBitsEncodedInInstructionCode.
2501cb0ef41Sopenharmony_ci  };
2511cb0ef41Sopenharmony_ci  using Flags = base::Flags<Flag>;
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ci  CallDescriptor(Kind kind, MachineType target_type, LinkageLocation target_loc,
2541cb0ef41Sopenharmony_ci                 LocationSignature* location_sig, size_t param_slot_count,
2551cb0ef41Sopenharmony_ci                 Operator::Properties properties,
2561cb0ef41Sopenharmony_ci                 RegList callee_saved_registers,
2571cb0ef41Sopenharmony_ci                 DoubleRegList callee_saved_fp_registers, Flags flags,
2581cb0ef41Sopenharmony_ci                 const char* debug_name = "",
2591cb0ef41Sopenharmony_ci                 StackArgumentOrder stack_order = StackArgumentOrder::kDefault,
2601cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2611cb0ef41Sopenharmony_ci                 const wasm::FunctionSig* wasm_sig = nullptr,
2621cb0ef41Sopenharmony_ci#endif
2631cb0ef41Sopenharmony_ci                 const RegList allocatable_registers = {},
2641cb0ef41Sopenharmony_ci                 size_t return_slot_count = 0)
2651cb0ef41Sopenharmony_ci      : kind_(kind),
2661cb0ef41Sopenharmony_ci        target_type_(target_type),
2671cb0ef41Sopenharmony_ci        target_loc_(target_loc),
2681cb0ef41Sopenharmony_ci        location_sig_(location_sig),
2691cb0ef41Sopenharmony_ci        param_slot_count_(param_slot_count),
2701cb0ef41Sopenharmony_ci        return_slot_count_(return_slot_count),
2711cb0ef41Sopenharmony_ci        properties_(properties),
2721cb0ef41Sopenharmony_ci        callee_saved_registers_(callee_saved_registers),
2731cb0ef41Sopenharmony_ci        callee_saved_fp_registers_(callee_saved_fp_registers),
2741cb0ef41Sopenharmony_ci        allocatable_registers_(allocatable_registers),
2751cb0ef41Sopenharmony_ci        flags_(flags),
2761cb0ef41Sopenharmony_ci        stack_order_(stack_order),
2771cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2781cb0ef41Sopenharmony_ci        wasm_sig_(wasm_sig),
2791cb0ef41Sopenharmony_ci#endif
2801cb0ef41Sopenharmony_ci        debug_name_(debug_name) {
2811cb0ef41Sopenharmony_ci  }
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci  CallDescriptor(const CallDescriptor&) = delete;
2841cb0ef41Sopenharmony_ci  CallDescriptor& operator=(const CallDescriptor&) = delete;
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci  // Returns the kind of this call.
2871cb0ef41Sopenharmony_ci  Kind kind() const { return kind_; }
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci  // Returns {true} if this descriptor is a call to a C function.
2901cb0ef41Sopenharmony_ci  bool IsCFunctionCall() const { return kind_ == kCallAddress; }
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci  // Returns {true} if this descriptor is a call to a JSFunction.
2931cb0ef41Sopenharmony_ci  bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; }
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2961cb0ef41Sopenharmony_ci  // Returns {true} if this descriptor is a call to a WebAssembly function.
2971cb0ef41Sopenharmony_ci  bool IsWasmFunctionCall() const { return kind_ == kCallWasmFunction; }
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ci  // Returns {true} if this descriptor is a call to a WebAssembly function.
3001cb0ef41Sopenharmony_ci  bool IsWasmImportWrapper() const { return kind_ == kCallWasmImportWrapper; }
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ci  // Returns {true} if this descriptor is a call to a Wasm C API function.
3031cb0ef41Sopenharmony_ci  bool IsWasmCapiFunction() const { return kind_ == kCallWasmCapiFunction; }
3041cb0ef41Sopenharmony_ci
3051cb0ef41Sopenharmony_ci  // Returns the wasm signature for this call based on the real parameter types.
3061cb0ef41Sopenharmony_ci  const wasm::FunctionSig* wasm_sig() const { return wasm_sig_; }
3071cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci  bool RequiresFrameAsIncoming() const {
3101cb0ef41Sopenharmony_ci    if (IsCFunctionCall() || IsJSFunctionCall()) return true;
3111cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
3121cb0ef41Sopenharmony_ci    if (IsWasmFunctionCall()) return true;
3131cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
3141cb0ef41Sopenharmony_ci    if (CalleeSavedRegisters() != kNoCalleeSaved) return true;
3151cb0ef41Sopenharmony_ci    return false;
3161cb0ef41Sopenharmony_ci  }
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci  // The number of return values from this call.
3191cb0ef41Sopenharmony_ci  size_t ReturnCount() const { return location_sig_->return_count(); }
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_ci  // The number of C parameters to this call. The following invariant
3221cb0ef41Sopenharmony_ci  // should hold true:
3231cb0ef41Sopenharmony_ci  // ParameterCount() == GPParameterCount() + FPParameterCount()
3241cb0ef41Sopenharmony_ci  size_t ParameterCount() const { return location_sig_->parameter_count(); }
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_ci  // The number of general purpose C parameters to this call.
3271cb0ef41Sopenharmony_ci  size_t GPParameterCount() const {
3281cb0ef41Sopenharmony_ci    if (!gp_param_count_) {
3291cb0ef41Sopenharmony_ci      ComputeParamCounts();
3301cb0ef41Sopenharmony_ci    }
3311cb0ef41Sopenharmony_ci    return gp_param_count_.value();
3321cb0ef41Sopenharmony_ci  }
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ci  // The number of floating point C parameters to this call.
3351cb0ef41Sopenharmony_ci  size_t FPParameterCount() const {
3361cb0ef41Sopenharmony_ci    if (!fp_param_count_) {
3371cb0ef41Sopenharmony_ci      ComputeParamCounts();
3381cb0ef41Sopenharmony_ci    }
3391cb0ef41Sopenharmony_ci    return fp_param_count_.value();
3401cb0ef41Sopenharmony_ci  }
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ci  // The number of stack parameter slots to the call.
3431cb0ef41Sopenharmony_ci  size_t ParameterSlotCount() const { return param_slot_count_; }
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci  // The number of stack return value slots from the call.
3461cb0ef41Sopenharmony_ci  size_t ReturnSlotCount() const { return return_slot_count_; }
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ci  // The number of parameters to the JS function call.
3491cb0ef41Sopenharmony_ci  size_t JSParameterCount() const {
3501cb0ef41Sopenharmony_ci    DCHECK(IsJSFunctionCall());
3511cb0ef41Sopenharmony_ci    return param_slot_count_;
3521cb0ef41Sopenharmony_ci  }
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ci  int GetStackIndexFromSlot(int slot_index) const {
3551cb0ef41Sopenharmony_ci    switch (GetStackArgumentOrder()) {
3561cb0ef41Sopenharmony_ci      case StackArgumentOrder::kDefault:
3571cb0ef41Sopenharmony_ci        return -slot_index - 1;
3581cb0ef41Sopenharmony_ci      case StackArgumentOrder::kJS:
3591cb0ef41Sopenharmony_ci        return slot_index + static_cast<int>(ParameterSlotCount());
3601cb0ef41Sopenharmony_ci    }
3611cb0ef41Sopenharmony_ci  }
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci  // The total number of inputs to this call, which includes the target,
3641cb0ef41Sopenharmony_ci  // receiver, context, etc.
3651cb0ef41Sopenharmony_ci  // TODO(titzer): this should input the framestate input too.
3661cb0ef41Sopenharmony_ci  size_t InputCount() const { return 1 + location_sig_->parameter_count(); }
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci  size_t FrameStateCount() const { return NeedsFrameState() ? 1 : 0; }
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_ci  Flags flags() const { return flags_; }
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci  bool NeedsFrameState() const { return flags() & kNeedsFrameState; }
3731cb0ef41Sopenharmony_ci  bool InitializeRootRegister() const {
3741cb0ef41Sopenharmony_ci    return flags() & kInitializeRootRegister;
3751cb0ef41Sopenharmony_ci  }
3761cb0ef41Sopenharmony_ci  bool NeedsCallerSavedRegisters() const {
3771cb0ef41Sopenharmony_ci    return flags() & kCallerSavedRegisters;
3781cb0ef41Sopenharmony_ci  }
3791cb0ef41Sopenharmony_ci  bool NeedsCallerSavedFPRegisters() const {
3801cb0ef41Sopenharmony_ci    return flags() & kCallerSavedFPRegisters;
3811cb0ef41Sopenharmony_ci  }
3821cb0ef41Sopenharmony_ci  bool IsTailCallForTierUp() const { return flags() & kIsTailCallForTierUp; }
3831cb0ef41Sopenharmony_ci  bool NoFunctionDescriptor() const { return flags() & kNoFunctionDescriptor; }
3841cb0ef41Sopenharmony_ci
3851cb0ef41Sopenharmony_ci  LinkageLocation GetReturnLocation(size_t index) const {
3861cb0ef41Sopenharmony_ci    return location_sig_->GetReturn(index);
3871cb0ef41Sopenharmony_ci  }
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_ci  LinkageLocation GetInputLocation(size_t index) const {
3901cb0ef41Sopenharmony_ci    if (index == 0) return target_loc_;
3911cb0ef41Sopenharmony_ci    return location_sig_->GetParam(index - 1);
3921cb0ef41Sopenharmony_ci  }
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci  MachineSignature* GetMachineSignature(Zone* zone) const;
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ci  MachineType GetReturnType(size_t index) const {
3971cb0ef41Sopenharmony_ci    return location_sig_->GetReturn(index).GetType();
3981cb0ef41Sopenharmony_ci  }
3991cb0ef41Sopenharmony_ci
4001cb0ef41Sopenharmony_ci  MachineType GetInputType(size_t index) const {
4011cb0ef41Sopenharmony_ci    if (index == 0) return target_type_;
4021cb0ef41Sopenharmony_ci    return location_sig_->GetParam(index - 1).GetType();
4031cb0ef41Sopenharmony_ci  }
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci  MachineType GetParameterType(size_t index) const {
4061cb0ef41Sopenharmony_ci    return location_sig_->GetParam(index).GetType();
4071cb0ef41Sopenharmony_ci  }
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci  StackArgumentOrder GetStackArgumentOrder() const { return stack_order_; }
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_ci  // Operator properties describe how this call can be optimized, if at all.
4121cb0ef41Sopenharmony_ci  Operator::Properties properties() const { return properties_; }
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_ci  // Get the callee-saved registers, if any, across this call.
4151cb0ef41Sopenharmony_ci  RegList CalleeSavedRegisters() const { return callee_saved_registers_; }
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ci  // Get the callee-saved FP registers, if any, across this call.
4181cb0ef41Sopenharmony_ci  DoubleRegList CalleeSavedFPRegisters() const {
4191cb0ef41Sopenharmony_ci    return callee_saved_fp_registers_;
4201cb0ef41Sopenharmony_ci  }
4211cb0ef41Sopenharmony_ci
4221cb0ef41Sopenharmony_ci  const char* debug_name() const { return debug_name_; }
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci  // Difference between the number of parameter slots of *this* and
4251cb0ef41Sopenharmony_ci  // *tail_caller* (callee minus caller).
4261cb0ef41Sopenharmony_ci  int GetStackParameterDelta(const CallDescriptor* tail_caller) const;
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci  // Returns the offset to the area below the parameter slots on the stack,
4291cb0ef41Sopenharmony_ci  // relative to callee slot 0, the return address. If there are no parameter
4301cb0ef41Sopenharmony_ci  // slots, returns +1.
4311cb0ef41Sopenharmony_ci  int GetOffsetToFirstUnusedStackSlot() const;
4321cb0ef41Sopenharmony_ci
4331cb0ef41Sopenharmony_ci  // Returns the offset to the area above the return slots on the stack,
4341cb0ef41Sopenharmony_ci  // relative to callee slot 0, the return address. If there are no return
4351cb0ef41Sopenharmony_ci  // slots, returns the offset to the lowest slot of the parameter area.
4361cb0ef41Sopenharmony_ci  // If there are no parameter slots, returns 0.
4371cb0ef41Sopenharmony_ci  int GetOffsetToReturns() const;
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_ci  // Returns two 16-bit numbers packed together: (first slot << 16) | num_slots.
4401cb0ef41Sopenharmony_ci  uint32_t GetTaggedParameterSlots() const;
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci  bool CanTailCall(const CallDescriptor* callee) const;
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci  int CalculateFixedFrameSize(CodeKind code_kind) const;
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci  RegList AllocatableRegisters() const { return allocatable_registers_; }
4471cb0ef41Sopenharmony_ci
4481cb0ef41Sopenharmony_ci  bool HasRestrictedAllocatableRegisters() const {
4491cb0ef41Sopenharmony_ci    return !allocatable_registers_.is_empty();
4501cb0ef41Sopenharmony_ci  }
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci  EncodedCSignature ToEncodedCSignature() const;
4531cb0ef41Sopenharmony_ci
4541cb0ef41Sopenharmony_ci private:
4551cb0ef41Sopenharmony_ci  void ComputeParamCounts() const;
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci  friend class Linkage;
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_ci  const Kind kind_;
4601cb0ef41Sopenharmony_ci  const MachineType target_type_;
4611cb0ef41Sopenharmony_ci  const LinkageLocation target_loc_;
4621cb0ef41Sopenharmony_ci  const LocationSignature* const location_sig_;
4631cb0ef41Sopenharmony_ci  const size_t param_slot_count_;
4641cb0ef41Sopenharmony_ci  const size_t return_slot_count_;
4651cb0ef41Sopenharmony_ci  const Operator::Properties properties_;
4661cb0ef41Sopenharmony_ci  const RegList callee_saved_registers_;
4671cb0ef41Sopenharmony_ci  const DoubleRegList callee_saved_fp_registers_;
4681cb0ef41Sopenharmony_ci  // Non-zero value means restricting the set of allocatable registers for
4691cb0ef41Sopenharmony_ci  // register allocator to use.
4701cb0ef41Sopenharmony_ci  const RegList allocatable_registers_;
4711cb0ef41Sopenharmony_ci  const Flags flags_;
4721cb0ef41Sopenharmony_ci  const StackArgumentOrder stack_order_;
4731cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
4741cb0ef41Sopenharmony_ci  const wasm::FunctionSig* wasm_sig_;
4751cb0ef41Sopenharmony_ci#endif
4761cb0ef41Sopenharmony_ci  const char* const debug_name_;
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_ci  mutable base::Optional<size_t> gp_param_count_;
4791cb0ef41Sopenharmony_ci  mutable base::Optional<size_t> fp_param_count_;
4801cb0ef41Sopenharmony_ci};
4811cb0ef41Sopenharmony_ci
4821cb0ef41Sopenharmony_ciDEFINE_OPERATORS_FOR_FLAGS(CallDescriptor::Flags)
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, const CallDescriptor& d);
4851cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
4861cb0ef41Sopenharmony_ci                                           const CallDescriptor::Kind& k);
4871cb0ef41Sopenharmony_ci
4881cb0ef41Sopenharmony_ci// Defines the linkage for a compilation, including the calling conventions
4891cb0ef41Sopenharmony_ci// for incoming parameters and return value(s) as well as the outgoing calling
4901cb0ef41Sopenharmony_ci// convention for any kind of call. Linkage is generally architecture-specific.
4911cb0ef41Sopenharmony_ci//
4921cb0ef41Sopenharmony_ci// Can be used to translate {arg_index} (i.e. index of the call node input) as
4931cb0ef41Sopenharmony_ci// well as {param_index} (i.e. as stored in parameter nodes) into an operator
4941cb0ef41Sopenharmony_ci// representing the architecture-specific location. The following call node
4951cb0ef41Sopenharmony_ci// layouts are supported (where {n} is the number of value inputs):
4961cb0ef41Sopenharmony_ci//
4971cb0ef41Sopenharmony_ci//                        #0          #1     #2     [...]             #n
4981cb0ef41Sopenharmony_ci// Call[CodeStub]         code,       arg 1, arg 2, [...],            context
4991cb0ef41Sopenharmony_ci// Call[JSFunction]       function,   rcvr,  arg 1, [...], new, #arg, context
5001cb0ef41Sopenharmony_ci// Call[Runtime]          CEntry,     arg 1, arg 2, [...], fun, #arg, context
5011cb0ef41Sopenharmony_ci// Call[BytecodeDispatch] address,    arg 1, arg 2, [...]
5021cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE Linkage : public NON_EXPORTED_BASE(ZoneObject) {
5031cb0ef41Sopenharmony_ci public:
5041cb0ef41Sopenharmony_ci  explicit Linkage(CallDescriptor* incoming) : incoming_(incoming) {}
5051cb0ef41Sopenharmony_ci  Linkage(const Linkage&) = delete;
5061cb0ef41Sopenharmony_ci  Linkage& operator=(const Linkage&) = delete;
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ci  static CallDescriptor* ComputeIncoming(Zone* zone,
5091cb0ef41Sopenharmony_ci                                         OptimizedCompilationInfo* info);
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci  // The call descriptor for this compilation unit describes the locations
5121cb0ef41Sopenharmony_ci  // of incoming parameters and the outgoing return value(s).
5131cb0ef41Sopenharmony_ci  CallDescriptor* GetIncomingDescriptor() const { return incoming_; }
5141cb0ef41Sopenharmony_ci  static CallDescriptor* GetJSCallDescriptor(Zone* zone, bool is_osr,
5151cb0ef41Sopenharmony_ci                                             int parameter_count,
5161cb0ef41Sopenharmony_ci                                             CallDescriptor::Flags flags);
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci  static CallDescriptor* GetRuntimeCallDescriptor(
5191cb0ef41Sopenharmony_ci      Zone* zone, Runtime::FunctionId function, int js_parameter_count,
5201cb0ef41Sopenharmony_ci      Operator::Properties properties, CallDescriptor::Flags flags);
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci  static CallDescriptor* GetCEntryStubCallDescriptor(
5231cb0ef41Sopenharmony_ci      Zone* zone, int return_count, int js_parameter_count,
5241cb0ef41Sopenharmony_ci      const char* debug_name, Operator::Properties properties,
5251cb0ef41Sopenharmony_ci      CallDescriptor::Flags flags,
5261cb0ef41Sopenharmony_ci      StackArgumentOrder stack_order = StackArgumentOrder::kDefault);
5271cb0ef41Sopenharmony_ci
5281cb0ef41Sopenharmony_ci  static CallDescriptor* GetStubCallDescriptor(
5291cb0ef41Sopenharmony_ci      Zone* zone, const CallInterfaceDescriptor& descriptor,
5301cb0ef41Sopenharmony_ci      int stack_parameter_count, CallDescriptor::Flags flags,
5311cb0ef41Sopenharmony_ci      Operator::Properties properties = Operator::kNoProperties,
5321cb0ef41Sopenharmony_ci      StubCallMode stub_mode = StubCallMode::kCallCodeObject);
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci  static CallDescriptor* GetBytecodeDispatchCallDescriptor(
5351cb0ef41Sopenharmony_ci      Zone* zone, const CallInterfaceDescriptor& descriptor,
5361cb0ef41Sopenharmony_ci      int stack_parameter_count);
5371cb0ef41Sopenharmony_ci
5381cb0ef41Sopenharmony_ci  // Creates a call descriptor for simplified C calls that is appropriate
5391cb0ef41Sopenharmony_ci  // for the host platform. This simplified calling convention only supports
5401cb0ef41Sopenharmony_ci  // integers and pointers of one word size each, i.e. no floating point,
5411cb0ef41Sopenharmony_ci  // structs, pointers to members, etc.
5421cb0ef41Sopenharmony_ci  static CallDescriptor* GetSimplifiedCDescriptor(
5431cb0ef41Sopenharmony_ci      Zone* zone, const MachineSignature* sig,
5441cb0ef41Sopenharmony_ci      CallDescriptor::Flags flags = CallDescriptor::kNoFlags);
5451cb0ef41Sopenharmony_ci
5461cb0ef41Sopenharmony_ci  // Get the location of an (incoming) parameter to this function.
5471cb0ef41Sopenharmony_ci  LinkageLocation GetParameterLocation(int index) const {
5481cb0ef41Sopenharmony_ci    return incoming_->GetInputLocation(index + 1);  // + 1 to skip target.
5491cb0ef41Sopenharmony_ci  }
5501cb0ef41Sopenharmony_ci
5511cb0ef41Sopenharmony_ci  // Get the machine type of an (incoming) parameter to this function.
5521cb0ef41Sopenharmony_ci  MachineType GetParameterType(int index) const {
5531cb0ef41Sopenharmony_ci    return incoming_->GetInputType(index + 1);  // + 1 to skip target.
5541cb0ef41Sopenharmony_ci  }
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci  // Get the location where this function should place its return value.
5571cb0ef41Sopenharmony_ci  LinkageLocation GetReturnLocation(size_t index = 0) const {
5581cb0ef41Sopenharmony_ci    return incoming_->GetReturnLocation(index);
5591cb0ef41Sopenharmony_ci  }
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ci  // Get the machine type of this function's return value.
5621cb0ef41Sopenharmony_ci  MachineType GetReturnType(size_t index = 0) const {
5631cb0ef41Sopenharmony_ci    return incoming_->GetReturnType(index);
5641cb0ef41Sopenharmony_ci  }
5651cb0ef41Sopenharmony_ci
5661cb0ef41Sopenharmony_ci  bool ParameterHasSecondaryLocation(int index) const;
5671cb0ef41Sopenharmony_ci  LinkageLocation GetParameterSecondaryLocation(int index) const;
5681cb0ef41Sopenharmony_ci
5691cb0ef41Sopenharmony_ci  static bool NeedsFrameStateInput(Runtime::FunctionId function);
5701cb0ef41Sopenharmony_ci
5711cb0ef41Sopenharmony_ci  // Get the location where an incoming OSR value is stored.
5721cb0ef41Sopenharmony_ci  LinkageLocation GetOsrValueLocation(int index) const;
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci  // A special {Parameter} index for Stub Calls that represents context.
5751cb0ef41Sopenharmony_ci  static int GetStubCallContextParamIndex(int parameter_count) {
5761cb0ef41Sopenharmony_ci    return parameter_count + 0;  // Parameter (arity + 0) is special.
5771cb0ef41Sopenharmony_ci  }
5781cb0ef41Sopenharmony_ci
5791cb0ef41Sopenharmony_ci  // A special {Parameter} index for JSCalls that represents the new target.
5801cb0ef41Sopenharmony_ci  static constexpr int GetJSCallNewTargetParamIndex(int parameter_count) {
5811cb0ef41Sopenharmony_ci    return parameter_count + 0;  // Parameter (arity + 0) is special.
5821cb0ef41Sopenharmony_ci  }
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ci  // A special {Parameter} index for JSCalls that represents the argument count.
5851cb0ef41Sopenharmony_ci  static constexpr int GetJSCallArgCountParamIndex(int parameter_count) {
5861cb0ef41Sopenharmony_ci    return parameter_count + 1;  // Parameter (arity + 1) is special.
5871cb0ef41Sopenharmony_ci  }
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci  // A special {Parameter} index for JSCalls that represents the context.
5901cb0ef41Sopenharmony_ci  static constexpr int GetJSCallContextParamIndex(int parameter_count) {
5911cb0ef41Sopenharmony_ci    return parameter_count + 2;  // Parameter (arity + 2) is special.
5921cb0ef41Sopenharmony_ci  }
5931cb0ef41Sopenharmony_ci
5941cb0ef41Sopenharmony_ci  // A special {Parameter} index for JSCalls that represents the closure.
5951cb0ef41Sopenharmony_ci  static constexpr int kJSCallClosureParamIndex = -1;
5961cb0ef41Sopenharmony_ci
5971cb0ef41Sopenharmony_ci  // A special {OsrValue} index to indicate the context spill slot.
5981cb0ef41Sopenharmony_ci  static const int kOsrContextSpillSlotIndex = -1;
5991cb0ef41Sopenharmony_ci
6001cb0ef41Sopenharmony_ci  // A special {OsrValue} index to indicate the accumulator register.
6011cb0ef41Sopenharmony_ci  static const int kOsrAccumulatorRegisterIndex = -1;
6021cb0ef41Sopenharmony_ci
6031cb0ef41Sopenharmony_ci private:
6041cb0ef41Sopenharmony_ci  CallDescriptor* const incoming_;
6051cb0ef41Sopenharmony_ci};
6061cb0ef41Sopenharmony_ci
6071cb0ef41Sopenharmony_ci}  // namespace compiler
6081cb0ef41Sopenharmony_ci}  // namespace internal
6091cb0ef41Sopenharmony_ci}  // namespace v8
6101cb0ef41Sopenharmony_ci#undef NO_INLINE_FOR_ARM64_MSVC
6111cb0ef41Sopenharmony_ci
6121cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_LINKAGE_H_
613