5 #ifndef V8_COMPILER_LINKAGE_H_ 6 #define V8_COMPILER_LINKAGE_H_ 8 #include "src/base/compiler-specific.h" 9 #include "src/base/flags.h" 10 #include "src/compiler/frame.h" 11 #include "src/compiler/operator.h" 12 #include "src/globals.h" 13 #include "src/interface-descriptors.h" 14 #include "src/machine-type.h" 15 #include "src/reglist.h" 16 #include "src/runtime/runtime.h" 17 #include "src/signature.h" 18 #include "src/turbo-assembler.h" 19 #include "src/zone/zone.h" 24 class CallInterfaceDescriptor;
25 class OptimizedCompilationInfo;
29 const RegList kNoCalleeSaved = 0;
38 return bit_field_ == other.bit_field_;
42 return !(*
this == other);
63 DCHECK(slot >= 0 && slot < LinkageLocation::MAX_STACK_SLOT);
68 return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
69 StandardFrameConstants::kCallerPCOffset) /
71 MachineType::Pointer());
75 return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
76 StandardFrameConstants::kCallerFPOffset) /
78 MachineType::Pointer());
82 DCHECK(V8_EMBEDDED_CONSTANT_POOL);
83 return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
84 StandardFrameConstants::kConstantPoolOffset) /
86 MachineType::AnyTagged());
90 return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
91 StandardFrameConstants::kFunctionOffset) /
93 MachineType::AnyTagged());
98 if (!caller_location.IsRegister()) {
100 caller_location.GetLocation() + stack_param_delta,
101 caller_location.GetType());
103 return caller_location;
106 MachineType GetType()
const {
return machine_type_; }
108 int GetSize()
const {
109 return 1 << ElementSizeLog2Of(GetType().representation());
112 int GetSizeInPointers()
const {
114 return (GetSize() + kPointerSize - 1) / kPointerSize;
117 int32_t GetLocation()
const {
120 return static_cast<int32_t
>(bit_field_ & LocationField::kMask) >>
121 LocationField::kShift;
124 bool IsRegister()
const {
return TypeField::decode(bit_field_) == REGISTER; }
125 bool IsAnyRegister()
const {
126 return IsRegister() && GetLocation() == ANY_REGISTER;
128 bool IsCallerFrameSlot()
const {
return !IsRegister() && GetLocation() < 0; }
129 bool IsCalleeFrameSlot()
const {
return !IsRegister() && GetLocation() >= 0; }
131 int32_t AsRegister()
const {
132 DCHECK(IsRegister());
133 return GetLocation();
135 int32_t AsCallerFrameSlot()
const {
136 DCHECK(IsCallerFrameSlot());
137 return GetLocation();
139 int32_t AsCalleeFrameSlot()
const {
140 DCHECK(IsCalleeFrameSlot());
141 return GetLocation();
145 enum LocationType { REGISTER, STACK_SLOT };
147 class TypeField :
public BitField<LocationType, 0, 1> {};
148 class LocationField :
public BitField<int32_t, TypeField::kNext, 31> {};
150 static constexpr int32_t ANY_REGISTER = -1;
151 static constexpr int32_t MAX_STACK_SLOT = 32767;
155 bit_field_ = TypeField::encode(
type) |
156 ((location << LocationField::kShift) & LocationField::kMask);
157 machine_type_ = machine_type;
169 :
public NON_EXPORTED_BASE(ZoneObject) {
177 kCallWasmImportWrapper
182 kNeedsFrameState = 1u << 0,
183 kHasExceptionHandler = 1u << 1,
184 kCanUseRoots = 1u << 2,
186 kInitializeRootRegister = 1u << 3,
188 kNoAllocate = 1u << 4,
190 kPushArgumentCount = 1u << 5,
192 kRetpoline = 1u << 6,
195 kFixedTargetRegister = 1u << 7,
196 kAllowCallThroughSlot = 1u << 8
203 RegList callee_saved_registers,
205 const char* debug_name =
"",
206 const RegList allocatable_registers = 0,
207 size_t stack_return_count = 0)
209 target_type_(target_type),
210 target_loc_(target_loc),
211 location_sig_(location_sig),
212 stack_param_count_(stack_param_count),
213 stack_return_count_(stack_return_count),
214 properties_(properties),
215 callee_saved_registers_(callee_saved_registers),
216 callee_saved_fp_registers_(callee_saved_fp_registers),
217 allocatable_registers_(allocatable_registers),
219 debug_name_(debug_name) {}
222 Kind kind()
const {
return kind_; }
225 bool IsCFunctionCall()
const {
return kind_ == kCallAddress; }
228 bool IsJSFunctionCall()
const {
return kind_ == kCallJSFunction; }
231 bool IsWasmFunctionCall()
const {
return kind_ == kCallWasmFunction; }
234 bool IsWasmImportWrapper()
const {
return kind_ == kCallWasmImportWrapper; }
236 bool RequiresFrameAsIncoming()
const {
237 return IsCFunctionCall() || IsJSFunctionCall() || IsWasmFunctionCall();
241 size_t ReturnCount()
const {
return location_sig_->return_count(); }
244 size_t ParameterCount()
const {
return location_sig_->parameter_count(); }
247 size_t StackParameterCount()
const {
return stack_param_count_; }
250 size_t StackReturnCount()
const {
return stack_return_count_; }
253 size_t JSParameterCount()
const {
254 DCHECK(IsJSFunctionCall());
255 return stack_param_count_;
261 size_t InputCount()
const {
return 1 + location_sig_->parameter_count(); }
263 size_t FrameStateCount()
const {
return NeedsFrameState() ? 1 : 0; }
265 Flags flags()
const {
return flags_; }
267 bool NeedsFrameState()
const {
return flags() & kNeedsFrameState; }
268 bool PushArgumentCount()
const {
return flags() & kPushArgumentCount; }
269 bool InitializeRootRegister()
const {
270 return flags() & kInitializeRootRegister;
274 return location_sig_->GetReturn(index);
278 if (index == 0)
return target_loc_;
279 return location_sig_->GetParam(index - 1);
285 return location_sig_->GetReturn(index).GetType();
289 if (index == 0)
return target_type_;
290 return location_sig_->GetParam(index - 1).GetType();
294 return location_sig_->GetParam(index).GetType();
301 RegList CalleeSavedRegisters()
const {
return callee_saved_registers_; }
304 RegList CalleeSavedFPRegisters()
const {
return callee_saved_fp_registers_; }
306 const char* debug_name()
const {
return debug_name_; }
308 bool UsesOnlyRegisters()
const;
313 int GetFirstUnusedStackSlot()
const;
315 int GetStackParameterDelta(
const CallDescriptor* tail_caller)
const;
317 bool CanTailCall(
const Node* call)
const;
319 int CalculateFixedFrameSize()
const;
321 RegList AllocatableRegisters()
const {
return allocatable_registers_; }
323 bool HasRestrictedAllocatableRegisters()
const {
324 return allocatable_registers_ != 0;
327 void set_save_fp_mode(SaveFPRegsMode mode) { save_fp_mode_ = mode; }
329 SaveFPRegsMode get_save_fp_mode()
const {
return save_fp_mode_; }
333 SaveFPRegsMode save_fp_mode_ = kSaveFPRegs;
339 const size_t stack_param_count_;
340 const size_t stack_return_count_;
342 const RegList callee_saved_registers_;
343 const RegList callee_saved_fp_registers_;
346 const RegList allocatable_registers_;
348 const char*
const debug_name_;
355 std::ostream& operator<<(std::ostream& os,
const CallDescriptor& d);
356 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
357 const CallDescriptor::Kind& k);
373 class V8_EXPORT_PRIVATE
Linkage :
public NON_EXPORTED_BASE(ZoneObject) {
382 CallDescriptor* GetIncomingDescriptor()
const {
return incoming_; }
388 Zone* zone, Runtime::FunctionId
function,
int js_parameter_count,
392 Zone* zone,
int return_count,
int js_parameter_count,
400 StubCallMode stub_mode = StubCallMode::kCallOnHeapBuiltin);
404 int stack_parameter_count);
412 bool set_initialize_root_flag =
false);
416 return incoming_->GetInputLocation(index + 1);
421 return incoming_->GetInputType(index + 1);
426 return incoming_->GetReturnLocation(index);
430 MachineType GetReturnType(
size_t index = 0)
const {
431 return incoming_->GetReturnType(index);
434 bool ParameterHasSecondaryLocation(
int index)
const;
437 static bool NeedsFrameStateInput(Runtime::FunctionId
function);
443 static int GetStubCallContextParamIndex(
int parameter_count) {
444 return parameter_count + 0;
448 static int GetJSCallNewTargetParamIndex(
int parameter_count) {
449 return parameter_count + 0;
453 static int GetJSCallArgCountParamIndex(
int parameter_count) {
454 return parameter_count + 1;
458 static int GetJSCallContextParamIndex(
int parameter_count) {
459 return parameter_count + 2;
463 static const int kJSCallClosureParamIndex = -1;
466 static const int kOsrContextSpillSlotIndex = -1;
469 static const int kOsrAccumulatorRegisterIndex = -1;
474 DISALLOW_COPY_AND_ASSIGN(
Linkage);
481 #endif // V8_COMPILER_LINKAGE_H_