5#ifndef V8_COMPILER_LINKAGE_H_
6#define V8_COMPILER_LINKAGE_H_
31class CallInterfaceDescriptor;
32class OptimizedCompilationInfo;
51#if V8_ENABLE_WEBASSEMBLY
52 kCallWasmCapiFunction,
54 kCallWasmFunctionIndirect,
56 kCallWasmImportWrapper,
63 static constexpr int kFlagsBitsEncodedInInstructionCode = 10;
66 kNeedsFrameState = 1u << 0,
67 kHasExceptionHandler = 1u << 1,
68 kCanUseRoots = 1u << 2,
70 kInitializeRootRegister = 1u << 3,
72 kNoAllocate = 1u << 4,
75 kFixedTargetRegister = 1u << 5,
76 kCallerSavedRegisters = 1u << 6,
79 kCallerSavedFPRegisters = 1u << 7,
95 kIsTailCallForTierUp = 1u << 8,
99 kNoFunctionDescriptor = 1u << 9,
110 RegList callee_saved_registers,
112 const char* debug_name =
"",
114 const RegList allocatable_registers = {},
115 size_t return_slot_count = 0,
119 target_type_(target_type),
120 target_loc_(target_loc),
121 location_sig_(location_sig),
122 param_slot_count_(param_slot_count),
123 return_slot_count_(return_slot_count),
124 properties_(properties),
125 callee_saved_registers_(callee_saved_registers),
126 callee_saved_fp_registers_(callee_saved_fp_registers),
127 allocatable_registers_(allocatable_registers),
129 stack_order_(stack_order),
130 debug_name_(debug_name),
131 signature_hash_(signature_hash) {
132#ifdef V8_ENABLE_WEBASSEMBLY
133 if (
kind == Kind::kCallWasmFunctionIndirect) {
134 CHECK_NE(signature_hash, kInvalidWasmSignatureHash);
148 uint64_t signature_hash()
const;
166#if V8_ENABLE_WEBASSEMBLY
169 bool IsDirectWasmFunctionCall()
const {
return kind_ == kCallWasmFunction; }
173 bool IsIndirectWasmFunctionCall()
const {
174 return kind_ == kCallWasmFunctionIndirect;
179 bool IsAnyWasmFunctionCall()
const {
180 return IsDirectWasmFunctionCall() || IsIndirectWasmFunctionCall();
184 bool IsWasmImportWrapper()
const {
return kind_ == kCallWasmImportWrapper; }
187 bool IsWasmCapiFunction()
const {
return kind_ == kCallWasmCapiFunction; }
193 if (IsCFunctionCall() || IsJSFunctionCall())
return true;
194#if V8_ENABLE_WEBASSEMBLY
195 if (IsAnyWasmFunctionCall())
return true;
204 size_t ReturnCount()
const {
return location_sig_->return_count(); }
213 if (!gp_param_count_) {
214 ComputeParamCounts();
216 return gp_param_count_.value();
221 if (!fp_param_count_) {
222 ComputeParamCounts();
224 return fp_param_count_.value();
235 DCHECK(IsJSFunctionCall());
236 return param_slot_count_;
240 switch (GetStackArgumentOrder()) {
241 case StackArgumentOrder::kDefault:
242 return -slot_index - 1;
243 case StackArgumentOrder::kJS:
244 return slot_index +
static_cast<int>(ParameterSlotCount());
251 size_t InputCount()
const {
return 1 + location_sig_->parameter_count(); }
259 return flags() & kInitializeRootRegister;
262 return flags() & kCallerSavedRegisters;
265 return flags() & kCallerSavedFPRegisters;
271 return location_sig_->GetReturn(index);
275 if (index == 0)
return target_loc_;
276 return location_sig_->GetParam(index - 1);
282 return location_sig_->GetReturn(index).GetType();
286 if (index == 0)
return target_type_;
287 return location_sig_->GetParam(index - 1).GetType();
291 return location_sig_->GetParam(index).GetType();
304 return callee_saved_fp_registers_;
311 int GetStackParameterDelta(
const CallDescriptor* tail_caller)
const;
316 int GetOffsetToFirstUnusedStackSlot()
const;
322 int GetOffsetToReturns()
const;
325 uint32_t GetTaggedParameterSlots()
const;
329 int CalculateFixedFrameSize(
CodeKind code_kind)
const;
334 return !allocatable_registers_.is_empty();
340 void ComputeParamCounts()
const;
373#if V8_ENABLE_WEBASSEMBLY
411 Operator::kNoProperties );
419 Zone* zone,
int return_count,
int js_parameter_count,
428 StubCallMode stub_mode = StubCallMode::kCallCodeObject);
432 int stack_parameter_count);
445 return incoming_->GetInputLocation(index + 1);
450 return incoming_->GetInputType(index + 1);
455 return incoming_->GetReturnLocation(index);
460 return incoming_->GetReturnType(index);
463 bool ParameterHasSecondaryLocation(
int index)
const;
486#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
489 static constexpr int GetJSCallDispatchHandleParamIndex(
int parameter_count) {
496#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
505 static_assert(kJSCallClosureParamIndex == -1);
508 static const int kOsrContextSpillSlotIndex = -1;
511 static const int kOsrAccumulatorRegisterIndex = -1;
520#undef NO_INLINE_FOR_ARM64_MSVC
#define DEFINE_OPERATORS_FOR_FLAGS(Type)
const CodeEntrypointTag tag_
bool InitializeRootRegister() const
size_t ReturnSlotCount() const
size_t JSParameterCount() const
CodeEntrypointTag tag() const
CallDescriptor(Kind kind, CodeEntrypointTag tag, MachineType target_type, LinkageLocation target_loc, LocationSignature *location_sig, size_t param_slot_count, Operator::Properties properties, RegList callee_saved_registers, DoubleRegList callee_saved_fp_registers, Flags flags, const char *debug_name="", StackArgumentOrder stack_order=StackArgumentOrder::kDefault, const RegList allocatable_registers={}, size_t return_slot_count=0, uint64_t signature_hash=kInvalidWasmSignatureHash)
const LocationSignature *const location_sig_
RegList CalleeSavedRegisters() const
std::optional< size_t > gp_param_count_
const StackArgumentOrder stack_order_
bool NeedsCallerSavedFPRegisters() const
CallDescriptor & operator=(const CallDescriptor &)=delete
bool HasRestrictedAllocatableRegisters() const
int GetStackIndexFromSlot(int slot_index) const
RegList AllocatableRegisters() const
const Operator::Properties properties_
bool NoFunctionDescriptor() const
bool IsBuiltinPointerCall() const
MachineType GetInputType(size_t index) const
const MachineType target_type_
const size_t param_slot_count_
size_t FPParameterCount() const
bool RequiresEntrypointTagForCall() const
DoubleRegList CalleeSavedFPRegisters() const
size_t FrameStateCount() const
std::optional< size_t > fp_param_count_
size_t ParameterCount() const
size_t ParameterSlotCount() const
bool IsCFunctionCall() const
bool NeedsCallerSavedRegisters() const
bool RequiresFrameAsIncoming() const
MachineType GetParameterType(size_t index) const
const char *const debug_name_
const DoubleRegList callee_saved_fp_registers_
size_t ReturnCount() const
const LinkageLocation target_loc_
CallDescriptor(const CallDescriptor &)=delete
StackArgumentOrder GetStackArgumentOrder() const
bool IsJSFunctionCall() const
bool NeedsFrameState() const
MachineType GetReturnType(size_t index) const
size_t InputCount() const
const RegList callee_saved_registers_
LinkageLocation GetReturnLocation(size_t index) const
bool IsCodeObjectCall() const
Operator::Properties properties() const
bool IsTailCallForTierUp() const
LinkageLocation GetInputLocation(size_t index) const
size_t GPParameterCount() const
const char * debug_name() const
const size_t return_slot_count_
const RegList allocatable_registers_
uint32_t shifted_tag() const
Linkage(const Linkage &)=delete
CallDescriptor *const incoming_
static constexpr int GetJSCallNewTargetParamIndex(int parameter_count)
static constexpr int GetJSCallContextParamIndex(int parameter_count)
Linkage & operator=(const Linkage &)=delete
LinkageLocation GetReturnLocation(size_t index=0) const
static constexpr int GetJSCallArgCountParamIndex(int parameter_count)
static int GetStubCallContextParamIndex(int parameter_count)
Linkage(CallDescriptor *incoming)
MachineType GetParameterType(int index) const
LinkageLocation GetParameterLocation(int index) const
MachineType GetReturnType(size_t index=0) const
CallDescriptor * GetIncomingDescriptor() const
other heap size flags(e.g. initial_heap_size) take precedence") DEFINE_SIZE_T( max_shared_heap_size
constexpr RegList kNoCalleeSaved
std::ostream & operator<<(std::ostream &os, AccessMode access_mode)
constexpr DoubleRegList kNoCalleeSavedFp
constexpr int kJSCallClosureParameterIndex
constexpr uint64_t kInvalidWasmSignatureHash
constexpr int kCodeEntrypointTagShift
#define NON_EXPORTED_BASE(code)
#define CHECK_NE(lhs, rhs)
#define DCHECK(condition)
#define V8_EXPORT_PRIVATE