Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 1 | // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef V8_COMPILER_LINKAGE_H_ |
| 6 | #define V8_COMPILER_LINKAGE_H_ |
| 7 | |
| 8 | #include "src/base/flags.h" |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 9 | #include "src/compiler/frame.h" |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 10 | #include "src/compiler/operator.h" |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 11 | #include "src/frames.h" |
| 12 | #include "src/machine-type.h" |
| 13 | #include "src/runtime/runtime.h" |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 14 | #include "src/zone.h" |
| 15 | |
| 16 | namespace v8 { |
| 17 | namespace internal { |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 18 | |
| 19 | class CallInterfaceDescriptor; |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 20 | class CompilationInfo; |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 21 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 22 | namespace compiler { |
| 23 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 24 | const RegList kNoCalleeSaved = 0; |
| 25 | |
| 26 | class Node; |
| 27 | class OsrHelper; |
| 28 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 29 | // Describes the location for a parameter or a return value to a call. |
| 30 | class LinkageLocation { |
| 31 | public: |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 32 | bool operator==(const LinkageLocation& other) const { |
| 33 | return bit_field_ == other.bit_field_; |
| 34 | } |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 35 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 36 | bool operator!=(const LinkageLocation& other) const { |
| 37 | return !(*this == other); |
| 38 | } |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 39 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 40 | static LinkageLocation ForAnyRegister() { |
| 41 | return LinkageLocation(REGISTER, ANY_REGISTER); |
| 42 | } |
| 43 | |
| 44 | static LinkageLocation ForRegister(int32_t reg) { |
| 45 | DCHECK(reg >= 0); |
| 46 | return LinkageLocation(REGISTER, reg); |
| 47 | } |
| 48 | |
| 49 | static LinkageLocation ForCallerFrameSlot(int32_t slot) { |
| 50 | DCHECK(slot < 0); |
| 51 | return LinkageLocation(STACK_SLOT, slot); |
| 52 | } |
| 53 | |
| 54 | static LinkageLocation ForCalleeFrameSlot(int32_t slot) { |
| 55 | // TODO(titzer): bailout instead of crashing here. |
| 56 | DCHECK(slot >= 0 && slot < LinkageLocation::MAX_STACK_SLOT); |
| 57 | return LinkageLocation(STACK_SLOT, slot); |
| 58 | } |
| 59 | |
| 60 | static LinkageLocation ForSavedCallerReturnAddress() { |
| 61 | return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset - |
| 62 | StandardFrameConstants::kCallerPCOffset) / |
| 63 | kPointerSize); |
| 64 | } |
| 65 | |
| 66 | static LinkageLocation ForSavedCallerFramePtr() { |
| 67 | return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset - |
| 68 | StandardFrameConstants::kCallerFPOffset) / |
| 69 | kPointerSize); |
| 70 | } |
| 71 | |
| 72 | static LinkageLocation ForSavedCallerConstantPool() { |
| 73 | DCHECK(V8_EMBEDDED_CONSTANT_POOL); |
| 74 | return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset - |
| 75 | StandardFrameConstants::kConstantPoolOffset) / |
| 76 | kPointerSize); |
| 77 | } |
| 78 | |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 79 | static LinkageLocation ForSavedCallerFunction() { |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 80 | return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset - |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 81 | StandardFrameConstants::kFunctionOffset) / |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 82 | kPointerSize); |
| 83 | } |
| 84 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 85 | static LinkageLocation ConvertToTailCallerLocation( |
| 86 | LinkageLocation caller_location, int stack_param_delta) { |
| 87 | if (!caller_location.IsRegister()) { |
| 88 | return LinkageLocation(STACK_SLOT, |
| 89 | caller_location.GetLocation() - stack_param_delta); |
| 90 | } |
| 91 | return caller_location; |
| 92 | } |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 93 | |
| 94 | private: |
| 95 | friend class CallDescriptor; |
| 96 | friend class OperandGenerator; |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 97 | |
| 98 | enum LocationType { REGISTER, STACK_SLOT }; |
| 99 | |
| 100 | class TypeField : public BitField<LocationType, 0, 1> {}; |
| 101 | class LocationField : public BitField<int32_t, TypeField::kNext, 31> {}; |
| 102 | |
| 103 | static const int32_t ANY_REGISTER = -1; |
| 104 | static const int32_t MAX_STACK_SLOT = 32767; |
| 105 | |
| 106 | LinkageLocation(LocationType type, int32_t location) { |
| 107 | bit_field_ = TypeField::encode(type) | |
| 108 | ((location << LocationField::kShift) & LocationField::kMask); |
| 109 | } |
| 110 | |
| 111 | int32_t GetLocation() const { |
| 112 | return static_cast<int32_t>(bit_field_ & LocationField::kMask) >> |
| 113 | LocationField::kShift; |
| 114 | } |
| 115 | |
| 116 | bool IsRegister() const { return TypeField::decode(bit_field_) == REGISTER; } |
| 117 | bool IsAnyRegister() const { |
| 118 | return IsRegister() && GetLocation() == ANY_REGISTER; |
| 119 | } |
| 120 | bool IsCallerFrameSlot() const { return !IsRegister() && GetLocation() < 0; } |
| 121 | bool IsCalleeFrameSlot() const { return !IsRegister() && GetLocation() >= 0; } |
| 122 | |
| 123 | int32_t AsRegister() const { |
| 124 | DCHECK(IsRegister()); |
| 125 | return GetLocation(); |
| 126 | } |
| 127 | int32_t AsCallerFrameSlot() const { |
| 128 | DCHECK(IsCallerFrameSlot()); |
| 129 | return GetLocation(); |
| 130 | } |
| 131 | int32_t AsCalleeFrameSlot() const { |
| 132 | DCHECK(IsCalleeFrameSlot()); |
| 133 | return GetLocation(); |
| 134 | } |
| 135 | |
| 136 | int32_t bit_field_; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 137 | }; |
| 138 | |
| 139 | typedef Signature<LinkageLocation> LocationSignature; |
| 140 | |
| 141 | // Describes a call to various parts of the compiler. Every call has the notion |
| 142 | // of a "target", which is the first input to the call. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 143 | class CallDescriptor final : public ZoneObject { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 144 | public: |
| 145 | // Describes the kind of this call, which determines the target. |
| 146 | enum Kind { |
| 147 | kCallCodeObject, // target is a Code object |
| 148 | kCallJSFunction, // target is a JSFunction object |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 149 | kCallAddress // target is a machine pointer |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 150 | }; |
| 151 | |
| 152 | enum Flag { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 153 | kNoFlags = 0u, |
| 154 | kNeedsFrameState = 1u << 0, |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 155 | kHasExceptionHandler = 1u << 1, |
| 156 | kHasLocalCatchHandler = 1u << 2, |
| 157 | kSupportsTailCalls = 1u << 3, |
| 158 | kCanUseRoots = 1u << 4, |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 159 | // (arm64 only) native stack should be used for arguments. |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 160 | kUseNativeStack = 1u << 5, |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 161 | // (arm64 only) call instruction has to restore JSSP or CSP. |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 162 | kRestoreJSSP = 1u << 6, |
| 163 | kRestoreCSP = 1u << 7, |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 164 | // Causes the code generator to initialize the root register. |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 165 | kInitializeRootRegister = 1u << 8, |
| 166 | // Does not ever try to allocate space on our heap. |
| 167 | kNoAllocate = 1u << 9 |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 168 | }; |
| 169 | typedef base::Flags<Flag> Flags; |
| 170 | |
| 171 | CallDescriptor(Kind kind, MachineType target_type, LinkageLocation target_loc, |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 172 | const MachineSignature* machine_sig, |
| 173 | LocationSignature* location_sig, size_t stack_param_count, |
| 174 | Operator::Properties properties, |
| 175 | RegList callee_saved_registers, |
| 176 | RegList callee_saved_fp_registers, Flags flags, |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 177 | const char* debug_name = "") |
| 178 | : kind_(kind), |
| 179 | target_type_(target_type), |
| 180 | target_loc_(target_loc), |
| 181 | machine_sig_(machine_sig), |
| 182 | location_sig_(location_sig), |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 183 | stack_param_count_(stack_param_count), |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 184 | properties_(properties), |
| 185 | callee_saved_registers_(callee_saved_registers), |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 186 | callee_saved_fp_registers_(callee_saved_fp_registers), |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 187 | flags_(flags), |
| 188 | debug_name_(debug_name) { |
| 189 | DCHECK(machine_sig->return_count() == location_sig->return_count()); |
| 190 | DCHECK(machine_sig->parameter_count() == location_sig->parameter_count()); |
| 191 | } |
| 192 | |
| 193 | // Returns the kind of this call. |
| 194 | Kind kind() const { return kind_; } |
| 195 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 196 | // Returns {true} if this descriptor is a call to a C function. |
| 197 | bool IsCFunctionCall() const { return kind_ == kCallAddress; } |
| 198 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 199 | // Returns {true} if this descriptor is a call to a JSFunction. |
| 200 | bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; } |
| 201 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 202 | bool RequiresFrameAsIncoming() const { |
| 203 | return IsCFunctionCall() || IsJSFunctionCall(); |
| 204 | } |
| 205 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 206 | // The number of return values from this call. |
| 207 | size_t ReturnCount() const { return machine_sig_->return_count(); } |
| 208 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 209 | // The number of C parameters to this call. |
| 210 | size_t CParameterCount() const { return machine_sig_->parameter_count(); } |
| 211 | |
| 212 | // The number of stack parameters to the call. |
| 213 | size_t StackParameterCount() const { return stack_param_count_; } |
| 214 | |
| 215 | // The number of parameters to the JS function call. |
| 216 | size_t JSParameterCount() const { |
| 217 | DCHECK(IsJSFunctionCall()); |
| 218 | return stack_param_count_; |
| 219 | } |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 220 | |
| 221 | // The total number of inputs to this call, which includes the target, |
| 222 | // receiver, context, etc. |
| 223 | // TODO(titzer): this should input the framestate input too. |
| 224 | size_t InputCount() const { return 1 + machine_sig_->parameter_count(); } |
| 225 | |
| 226 | size_t FrameStateCount() const { return NeedsFrameState() ? 1 : 0; } |
| 227 | |
| 228 | Flags flags() const { return flags_; } |
| 229 | |
| 230 | bool NeedsFrameState() const { return flags() & kNeedsFrameState; } |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 231 | bool SupportsTailCalls() const { return flags() & kSupportsTailCalls; } |
| 232 | bool UseNativeStack() const { return flags() & kUseNativeStack; } |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 233 | bool InitializeRootRegister() const { |
| 234 | return flags() & kInitializeRootRegister; |
| 235 | } |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 236 | |
| 237 | LinkageLocation GetReturnLocation(size_t index) const { |
| 238 | return location_sig_->GetReturn(index); |
| 239 | } |
| 240 | |
| 241 | LinkageLocation GetInputLocation(size_t index) const { |
| 242 | if (index == 0) return target_loc_; |
| 243 | return location_sig_->GetParam(index - 1); |
| 244 | } |
| 245 | |
| 246 | const MachineSignature* GetMachineSignature() const { return machine_sig_; } |
| 247 | |
| 248 | MachineType GetReturnType(size_t index) const { |
| 249 | return machine_sig_->GetReturn(index); |
| 250 | } |
| 251 | |
| 252 | MachineType GetInputType(size_t index) const { |
| 253 | if (index == 0) return target_type_; |
| 254 | return machine_sig_->GetParam(index - 1); |
| 255 | } |
| 256 | |
| 257 | // Operator properties describe how this call can be optimized, if at all. |
| 258 | Operator::Properties properties() const { return properties_; } |
| 259 | |
| 260 | // Get the callee-saved registers, if any, across this call. |
| 261 | RegList CalleeSavedRegisters() const { return callee_saved_registers_; } |
| 262 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 263 | // Get the callee-saved FP registers, if any, across this call. |
| 264 | RegList CalleeSavedFPRegisters() const { return callee_saved_fp_registers_; } |
| 265 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 266 | const char* debug_name() const { return debug_name_; } |
| 267 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 268 | bool UsesOnlyRegisters() const; |
| 269 | |
| 270 | bool HasSameReturnLocationsAs(const CallDescriptor* other) const; |
| 271 | |
| 272 | bool CanTailCall(const Node* call, int* stack_param_delta) const; |
| 273 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 274 | private: |
| 275 | friend class Linkage; |
| 276 | |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 277 | const Kind kind_; |
| 278 | const MachineType target_type_; |
| 279 | const LinkageLocation target_loc_; |
| 280 | const MachineSignature* const machine_sig_; |
| 281 | const LocationSignature* const location_sig_; |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 282 | const size_t stack_param_count_; |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 283 | const Operator::Properties properties_; |
| 284 | const RegList callee_saved_registers_; |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 285 | const RegList callee_saved_fp_registers_; |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 286 | const Flags flags_; |
| 287 | const char* const debug_name_; |
| 288 | |
| 289 | DISALLOW_COPY_AND_ASSIGN(CallDescriptor); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 290 | }; |
| 291 | |
| 292 | DEFINE_OPERATORS_FOR_FLAGS(CallDescriptor::Flags) |
| 293 | |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 294 | std::ostream& operator<<(std::ostream& os, const CallDescriptor& d); |
| 295 | std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 296 | |
| 297 | // Defines the linkage for a compilation, including the calling conventions |
| 298 | // for incoming parameters and return value(s) as well as the outgoing calling |
| 299 | // convention for any kind of call. Linkage is generally architecture-specific. |
| 300 | // |
| 301 | // Can be used to translate {arg_index} (i.e. index of the call node input) as |
| 302 | // well as {param_index} (i.e. as stored in parameter nodes) into an operator |
| 303 | // representing the architecture-specific location. The following call node |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 304 | // layouts are supported (where {n} is the number of value inputs): |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 305 | // |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 306 | // #0 #1 #2 [...] #n |
| 307 | // Call[CodeStub] code, arg 1, arg 2, [...], context |
| 308 | // Call[JSFunction] function, rcvr, arg 1, [...], new, #arg, context |
| 309 | // Call[Runtime] CEntryStub, arg 1, arg 2, [...], fun, #arg, context |
| 310 | // Call[BytecodeDispatch] address, arg 1, arg 2, [...] |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 311 | class Linkage : public ZoneObject { |
| 312 | public: |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 313 | explicit Linkage(CallDescriptor* incoming) : incoming_(incoming) {} |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 314 | |
| 315 | static CallDescriptor* ComputeIncoming(Zone* zone, CompilationInfo* info); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 316 | |
| 317 | // The call descriptor for this compilation unit describes the locations |
| 318 | // of incoming parameters and the outgoing return value(s). |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 319 | CallDescriptor* GetIncomingDescriptor() const { return incoming_; } |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 320 | static CallDescriptor* GetJSCallDescriptor(Zone* zone, bool is_osr, |
| 321 | int parameter_count, |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 322 | CallDescriptor::Flags flags); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 323 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 324 | static CallDescriptor* GetRuntimeCallDescriptor( |
| 325 | Zone* zone, Runtime::FunctionId function, int parameter_count, |
| 326 | Operator::Properties properties, CallDescriptor::Flags flags); |
| 327 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 328 | static CallDescriptor* GetStubCallDescriptor( |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 329 | Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, |
| 330 | int stack_parameter_count, CallDescriptor::Flags flags, |
| 331 | Operator::Properties properties = Operator::kNoProperties, |
| 332 | MachineType return_type = MachineType::AnyTagged(), |
| 333 | size_t return_count = 1); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 334 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 335 | static CallDescriptor* GetAllocateCallDescriptor(Zone* zone); |
| 336 | static CallDescriptor* GetBytecodeDispatchCallDescriptor( |
| 337 | Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, |
| 338 | int stack_parameter_count); |
| 339 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 340 | // Creates a call descriptor for simplified C calls that is appropriate |
| 341 | // for the host platform. This simplified calling convention only supports |
| 342 | // integers and pointers of one word size each, i.e. no floating point, |
| 343 | // structs, pointers to members, etc. |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 344 | static CallDescriptor* GetSimplifiedCDescriptor( |
| 345 | Zone* zone, const MachineSignature* sig, |
| 346 | bool set_initialize_root_flag = false); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 347 | |
| 348 | // Get the location of an (incoming) parameter to this function. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 349 | LinkageLocation GetParameterLocation(int index) const { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 350 | return incoming_->GetInputLocation(index + 1); // + 1 to skip target. |
| 351 | } |
| 352 | |
| 353 | // Get the machine type of an (incoming) parameter to this function. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 354 | MachineType GetParameterType(int index) const { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 355 | return incoming_->GetInputType(index + 1); // + 1 to skip target. |
| 356 | } |
| 357 | |
| 358 | // Get the location where this function should place its return value. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 359 | LinkageLocation GetReturnLocation(size_t index = 0) const { |
| 360 | return incoming_->GetReturnLocation(index); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 361 | } |
| 362 | |
| 363 | // Get the machine type of this function's return value. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 364 | MachineType GetReturnType(size_t index = 0) const { |
| 365 | return incoming_->GetReturnType(index); |
| 366 | } |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 367 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 368 | bool ParameterHasSecondaryLocation(int index) const; |
| 369 | LinkageLocation GetParameterSecondaryLocation(int index) const; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 370 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 371 | static bool NeedsFrameStateInput(Runtime::FunctionId function); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 372 | |
| 373 | // Get the location where an incoming OSR value is stored. |
| 374 | LinkageLocation GetOsrValueLocation(int index) const; |
| 375 | |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 376 | // A special {Parameter} index for Stub Calls that represents context. |
| 377 | static int GetStubCallContextParamIndex(int parameter_count) { |
| 378 | return parameter_count + 0; // Parameter (arity + 0) is special. |
| 379 | } |
| 380 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 381 | // A special {Parameter} index for JSCalls that represents the new target. |
| 382 | static int GetJSCallNewTargetParamIndex(int parameter_count) { |
| 383 | return parameter_count + 0; // Parameter (arity + 0) is special. |
| 384 | } |
| 385 | |
| 386 | // A special {Parameter} index for JSCalls that represents the argument count. |
| 387 | static int GetJSCallArgCountParamIndex(int parameter_count) { |
| 388 | return parameter_count + 1; // Parameter (arity + 1) is special. |
| 389 | } |
| 390 | |
| 391 | // A special {Parameter} index for JSCalls that represents the context. |
| 392 | static int GetJSCallContextParamIndex(int parameter_count) { |
| 393 | return parameter_count + 2; // Parameter (arity + 2) is special. |
| 394 | } |
| 395 | |
| 396 | // A special {Parameter} index for JSCalls that represents the closure. |
| 397 | static const int kJSCallClosureParamIndex = -1; |
| 398 | |
| 399 | // A special {OsrValue} index to indicate the context spill slot. |
| 400 | static const int kOsrContextSpillSlotIndex = -1; |
| 401 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 402 | private: |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 403 | CallDescriptor* const incoming_; |
| 404 | |
| 405 | DISALLOW_COPY_AND_ASSIGN(Linkage); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 406 | }; |
| 407 | |
| 408 | } // namespace compiler |
| 409 | } // namespace internal |
| 410 | } // namespace v8 |
| 411 | |
| 412 | #endif // V8_COMPILER_LINKAGE_H_ |