Line data Source code
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 : #include "src/compiler/linkage.h"
6 :
7 : #include "src/assembler-inl.h"
8 : #include "src/compiler/common-operator.h"
9 : #include "src/compiler/frame.h"
10 : #include "src/compiler/node.h"
11 : #include "src/compiler/osr.h"
12 : #include "src/compiler/pipeline.h"
13 : #include "src/macro-assembler.h"
14 : #include "src/optimized-compilation-info.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 : namespace compiler {
19 :
20 : namespace {
21 :
22 : inline LinkageLocation regloc(Register reg, MachineType type) {
23 : return LinkageLocation::ForRegister(reg.code(), type);
24 : }
25 :
26 : } // namespace
27 :
28 :
29 32 : std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) {
30 32 : switch (k) {
31 : case CallDescriptor::kCallCodeObject:
32 32 : os << "Code";
33 32 : break;
34 : case CallDescriptor::kCallJSFunction:
35 0 : os << "JS";
36 0 : break;
37 : case CallDescriptor::kCallAddress:
38 0 : os << "Addr";
39 0 : break;
40 : case CallDescriptor::kCallWasmFunction:
41 0 : os << "WasmFunction";
42 0 : break;
43 : case CallDescriptor::kCallWasmImportWrapper:
44 0 : os << "WasmImportWrapper";
45 0 : break;
46 : case CallDescriptor::kCallBuiltinPointer:
47 0 : os << "BuiltinPointer";
48 0 : break;
49 : }
50 32 : return os;
51 : }
52 :
53 :
54 32 : std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) {
55 : // TODO(svenpanne) Output properties etc. and be less cryptic.
56 96 : return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount()
57 : << "s" << d.StackParameterCount() << "i" << d.InputCount() << "f"
58 32 : << d.FrameStateCount();
59 : }
60 :
61 9632 : MachineSignature* CallDescriptor::GetMachineSignature(Zone* zone) const {
62 : size_t param_count = ParameterCount();
63 : size_t return_count = ReturnCount();
64 9632 : MachineType* types = zone->NewArray<MachineType>(param_count + return_count);
65 : int current = 0;
66 28896 : for (size_t i = 0; i < return_count; ++i) {
67 19264 : types[current++] = GetReturnType(i);
68 : }
69 48160 : for (size_t i = 0; i < param_count; ++i) {
70 38528 : types[current++] = GetParameterType(i);
71 : }
72 9632 : return new (zone) MachineSignature(return_count, param_count, types);
73 : }
74 :
75 0 : bool CallDescriptor::HasSameReturnLocationsAs(
76 : const CallDescriptor* other) const {
77 13 : if (ReturnCount() != other->ReturnCount()) return false;
78 35 : for (size_t i = 0; i < ReturnCount(); ++i) {
79 12 : if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false;
80 : }
81 : return true;
82 : }
83 :
84 359504 : int CallDescriptor::GetFirstUnusedStackSlot() const {
85 : int slots_above_sp = 0;
86 4318792 : for (size_t i = 0; i < InputCount(); ++i) {
87 : LinkageLocation operand = GetInputLocation(i);
88 1979644 : if (!operand.IsRegister()) {
89 : int new_candidate =
90 123258 : -operand.GetLocation() + operand.GetSizeInPointers() - 1;
91 123258 : if (new_candidate > slots_above_sp) {
92 : slots_above_sp = new_candidate;
93 : }
94 : }
95 : }
96 359504 : return slots_above_sp;
97 : }
98 :
99 119839 : int CallDescriptor::GetStackParameterDelta(
100 : CallDescriptor const* tail_caller) const {
101 119839 : int callee_slots_above_sp = GetFirstUnusedStackSlot();
102 119839 : int tail_caller_slots_above_sp = tail_caller->GetFirstUnusedStackSlot();
103 119839 : int stack_param_delta = callee_slots_above_sp - tail_caller_slots_above_sp;
104 : if (kPadArguments) {
105 : // Adjust stack delta when it is odd.
106 : if (stack_param_delta % 2 != 0) {
107 : if (callee_slots_above_sp % 2 != 0) {
108 : // The delta is odd due to the callee - we will need to add one slot
109 : // of padding.
110 : ++stack_param_delta;
111 : } else {
112 : // The delta is odd because of the caller. We already have one slot of
113 : // padding that we can reuse for arguments, so we will need one fewer
114 : // slot.
115 : --stack_param_delta;
116 : }
117 : }
118 : }
119 119839 : return stack_param_delta;
120 : }
121 :
122 1434892 : int CallDescriptor::GetTaggedParameterSlots() const {
123 : int result = 0;
124 7930872 : for (size_t i = 0; i < InputCount(); ++i) {
125 : LinkageLocation operand = GetInputLocation(i);
126 3328866 : if (!operand.IsRegister() && operand.GetType().IsTagged()) {
127 2790 : ++result;
128 : }
129 : }
130 1434892 : return result;
131 : }
132 :
133 13 : bool CallDescriptor::CanTailCall(const Node* node) const {
134 26 : return HasSameReturnLocationsAs(CallDescriptorOf(node->op()));
135 : }
136 :
137 5302532 : int CallDescriptor::CalculateFixedFrameSize() const {
138 5302532 : switch (kind_) {
139 : case kCallJSFunction:
140 : return PushArgumentCount()
141 : ? OptimizedBuiltinFrameConstants::kFixedSlotCount
142 1290657 : : StandardFrameConstants::kFixedSlotCount;
143 : case kCallAddress:
144 : return CommonFrameConstants::kFixedSlotCountAboveFp +
145 : CommonFrameConstants::kCPSlotCount;
146 : case kCallCodeObject:
147 : case kCallBuiltinPointer:
148 214646 : return TypedFrameConstants::kFixedSlotCount;
149 : case kCallWasmFunction:
150 : case kCallWasmImportWrapper:
151 1988768 : return WasmCompiledFrameConstants::kFixedSlotCount;
152 : }
153 0 : UNREACHABLE();
154 : }
155 :
156 464132 : CallDescriptor* Linkage::ComputeIncoming(Zone* zone,
157 : OptimizedCompilationInfo* info) {
158 : DCHECK(!info->IsNotOptimizedFunctionOrWasmFunction());
159 464132 : if (!info->closure().is_null()) {
160 : // If we are compiling a JS function, use a JS call descriptor,
161 : // plus the receiver.
162 : SharedFunctionInfo shared = info->closure()->shared();
163 1392399 : return GetJSCallDescriptor(zone, info->is_osr(),
164 : 1 + shared->internal_formal_parameter_count(),
165 464133 : CallDescriptor::kCanUseRoots);
166 : }
167 : return nullptr; // TODO(titzer): ?
168 : }
169 :
170 :
171 : // static
172 13022806 : bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) {
173 13022806 : switch (function) {
174 : // Most runtime functions need a FrameState. A few chosen ones that we know
175 : // not to call into arbitrary JavaScript, not to throw, and not to lazily
176 : // deoptimize are whitelisted here and can be called without a FrameState.
177 : case Runtime::kAbort:
178 : case Runtime::kAllocateInOldGeneration:
179 : case Runtime::kCreateIterResultObject:
180 : case Runtime::kIncBlockCounter:
181 : case Runtime::kIsFunction:
182 : case Runtime::kNewClosure:
183 : case Runtime::kNewClosure_Tenured:
184 : case Runtime::kNewFunctionContext:
185 : case Runtime::kPushBlockContext:
186 : case Runtime::kPushCatchContext:
187 : case Runtime::kReThrow:
188 : case Runtime::kStringEqual:
189 : case Runtime::kStringLessThan:
190 : case Runtime::kStringLessThanOrEqual:
191 : case Runtime::kStringGreaterThan:
192 : case Runtime::kStringGreaterThanOrEqual:
193 : case Runtime::kToFastProperties: // TODO(conradw): Is it safe?
194 : case Runtime::kTraceEnter:
195 : case Runtime::kTraceExit:
196 : return false;
197 :
198 : // Some inline intrinsics are also safe to call without a FrameState.
199 : case Runtime::kInlineCreateIterResultObject:
200 : case Runtime::kInlineGeneratorClose:
201 : case Runtime::kInlineGeneratorGetResumeMode:
202 : case Runtime::kInlineCreateJSGeneratorObject:
203 : case Runtime::kInlineIsArray:
204 : case Runtime::kInlineIsJSReceiver:
205 : case Runtime::kInlineIsRegExp:
206 : case Runtime::kInlineIsSmi:
207 : case Runtime::kInlineIsTypedArray:
208 : return false;
209 :
210 : default:
211 : break;
212 : }
213 :
214 : // For safety, default to needing a FrameState unless whitelisted.
215 12424395 : return true;
216 : }
217 :
218 :
219 0 : bool CallDescriptor::UsesOnlyRegisters() const {
220 0 : for (size_t i = 0; i < InputCount(); ++i) {
221 0 : if (!GetInputLocation(i).IsRegister()) return false;
222 : }
223 0 : for (size_t i = 0; i < ReturnCount(); ++i) {
224 0 : if (!GetReturnLocation(i).IsRegister()) return false;
225 : }
226 : return true;
227 : }
228 :
229 :
230 1402577 : CallDescriptor* Linkage::GetRuntimeCallDescriptor(
231 : Zone* zone, Runtime::FunctionId function_id, int js_parameter_count,
232 : Operator::Properties properties, CallDescriptor::Flags flags) {
233 1402577 : const Runtime::Function* function = Runtime::FunctionForId(function_id);
234 1402578 : const int return_count = function->result_size;
235 1402578 : const char* debug_name = function->name;
236 :
237 1402578 : if (!Linkage::NeedsFrameStateInput(function_id)) {
238 : flags = static_cast<CallDescriptor::Flags>(
239 : flags & ~CallDescriptor::kNeedsFrameState);
240 : }
241 :
242 : return GetCEntryStubCallDescriptor(zone, return_count, js_parameter_count,
243 1402591 : debug_name, properties, flags);
244 : }
245 :
246 1405533 : CallDescriptor* Linkage::GetCEntryStubCallDescriptor(
247 : Zone* zone, int return_count, int js_parameter_count,
248 : const char* debug_name, Operator::Properties properties,
249 : CallDescriptor::Flags flags) {
250 : const size_t function_count = 1;
251 : const size_t num_args_count = 1;
252 : const size_t context_count = 1;
253 : const size_t parameter_count = function_count +
254 : static_cast<size_t>(js_parameter_count) +
255 1405533 : num_args_count + context_count;
256 :
257 : LocationSignature::Builder locations(zone, static_cast<size_t>(return_count),
258 1405533 : static_cast<size_t>(parameter_count));
259 :
260 : // Add returns.
261 1405533 : if (locations.return_count_ > 0) {
262 : locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged()));
263 : }
264 1405533 : if (locations.return_count_ > 1) {
265 : locations.AddReturn(regloc(kReturnRegister1, MachineType::AnyTagged()));
266 : }
267 1405533 : if (locations.return_count_ > 2) {
268 : locations.AddReturn(regloc(kReturnRegister2, MachineType::AnyTagged()));
269 : }
270 :
271 : // All parameters to the runtime call go on the stack.
272 4724785 : for (int i = 0; i < js_parameter_count; i++) {
273 1659626 : locations.AddParam(LinkageLocation::ForCallerFrameSlot(
274 : i - js_parameter_count, MachineType::AnyTagged()));
275 : }
276 : // Add runtime function itself.
277 : locations.AddParam(
278 : regloc(kRuntimeCallFunctionRegister, MachineType::Pointer()));
279 :
280 : // Add runtime call argument count.
281 : locations.AddParam(
282 : regloc(kRuntimeCallArgCountRegister, MachineType::Int32()));
283 :
284 : // Add context.
285 : locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged()));
286 :
287 : // The target for runtime calls is a code object.
288 : MachineType target_type = MachineType::AnyTagged();
289 : LinkageLocation target_loc =
290 : LinkageLocation::ForAnyRegister(MachineType::AnyTagged());
291 : return new (zone) CallDescriptor( // --
292 : CallDescriptor::kCallCodeObject, // kind
293 : target_type, // target MachineType
294 : target_loc, // target location
295 : locations.Build(), // location_sig
296 : js_parameter_count, // stack_parameter_count
297 : properties, // properties
298 : kNoCalleeSaved, // callee-saved
299 : kNoCalleeSaved, // callee-saved fp
300 : flags, // flags
301 2811071 : debug_name); // debug name
302 : }
303 :
304 645681 : CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
305 : int js_parameter_count,
306 : CallDescriptor::Flags flags) {
307 : const size_t return_count = 1;
308 : const size_t context_count = 1;
309 : const size_t new_target_count = 1;
310 : const size_t num_args_count = 1;
311 : const size_t parameter_count =
312 645681 : js_parameter_count + new_target_count + num_args_count + context_count;
313 :
314 : LocationSignature::Builder locations(zone, return_count, parameter_count);
315 :
316 : // All JS calls have exactly one return value.
317 : locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged()));
318 :
319 : // All parameters to JS calls go on the stack.
320 4297797 : for (int i = 0; i < js_parameter_count; i++) {
321 1826055 : int spill_slot_index = i - js_parameter_count;
322 : locations.AddParam(LinkageLocation::ForCallerFrameSlot(
323 : spill_slot_index, MachineType::AnyTagged()));
324 : }
325 :
326 : // Add JavaScript call new target value.
327 : locations.AddParam(
328 : regloc(kJavaScriptCallNewTargetRegister, MachineType::AnyTagged()));
329 :
330 : // Add JavaScript call argument count.
331 : locations.AddParam(
332 : regloc(kJavaScriptCallArgCountRegister, MachineType::Int32()));
333 :
334 : // Add context.
335 : locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged()));
336 :
337 : // The target for JS function calls is the JSFunction object.
338 : MachineType target_type = MachineType::AnyTagged();
339 : // When entering into an OSR function from unoptimized code the JSFunction
340 : // is not in a register, but it is on the stack in the marker spill slot.
341 : LinkageLocation target_loc =
342 : is_osr ? LinkageLocation::ForSavedCallerFunction()
343 645687 : : regloc(kJSFunctionRegister, MachineType::AnyTagged());
344 : return new (zone) CallDescriptor( // --
345 : CallDescriptor::kCallJSFunction, // kind
346 : target_type, // target MachineType
347 : target_loc, // target location
348 : locations.Build(), // location_sig
349 : js_parameter_count, // stack_parameter_count
350 : Operator::kNoProperties, // properties
351 : kNoCalleeSaved, // callee-saved
352 : kNoCalleeSaved, // callee-saved fp
353 : flags, // flags
354 1291369 : "js-call");
355 : }
356 :
357 : // TODO(turbofan): cache call descriptors for code stub calls.
358 : // TODO(jgruber): Clean up stack parameter count handling. The descriptor
359 : // already knows the formal stack parameter count and ideally only additional
360 : // stack parameters should be passed into this method. All call-sites should
361 : // be audited for correctness (e.g. many used to assume a stack parameter count
362 : // of 0).
363 3242477 : CallDescriptor* Linkage::GetStubCallDescriptor(
364 : Zone* zone, const CallInterfaceDescriptor& descriptor,
365 : int stack_parameter_count, CallDescriptor::Flags flags,
366 : Operator::Properties properties, StubCallMode stub_mode) {
367 : const int register_parameter_count = descriptor.GetRegisterParameterCount();
368 : const int js_parameter_count =
369 3242477 : register_parameter_count + stack_parameter_count;
370 3242477 : const int context_count = descriptor.HasContextParameter() ? 1 : 0;
371 : const size_t parameter_count =
372 3242477 : static_cast<size_t>(js_parameter_count + context_count);
373 :
374 : DCHECK_GE(stack_parameter_count, descriptor.GetStackParameterCount());
375 :
376 3242477 : size_t return_count = descriptor.GetReturnCount();
377 : LocationSignature::Builder locations(zone, return_count, parameter_count);
378 :
379 : // Add returns.
380 3242509 : if (locations.return_count_ > 0) {
381 : locations.AddReturn(regloc(kReturnRegister0, descriptor.GetReturnType(0)));
382 : }
383 3242509 : if (locations.return_count_ > 1) {
384 : locations.AddReturn(regloc(kReturnRegister1, descriptor.GetReturnType(1)));
385 : }
386 3242509 : if (locations.return_count_ > 2) {
387 : locations.AddReturn(regloc(kReturnRegister2, descriptor.GetReturnType(2)));
388 : }
389 :
390 : // Add parameters in registers and on the stack.
391 20073431 : for (int i = 0; i < js_parameter_count; i++) {
392 8415461 : if (i < register_parameter_count) {
393 : // The first parameters go in registers.
394 : Register reg = descriptor.GetRegisterParameter(i);
395 : MachineType type = descriptor.GetParameterType(i);
396 : locations.AddParam(regloc(reg, type));
397 : } else {
398 : // The rest of the parameters go on the stack.
399 1374544 : int stack_slot = i - register_parameter_count - stack_parameter_count;
400 : locations.AddParam(LinkageLocation::ForCallerFrameSlot(
401 : stack_slot, MachineType::AnyTagged()));
402 : }
403 : }
404 : // Add context.
405 3242509 : if (context_count) {
406 : locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged()));
407 : }
408 :
409 : // The target for stub calls depends on the requested mode.
410 : CallDescriptor::Kind kind;
411 : MachineType target_type;
412 3242509 : switch (stub_mode) {
413 : case StubCallMode::kCallCodeObject:
414 : kind = CallDescriptor::kCallCodeObject;
415 : target_type = MachineType::AnyTagged();
416 3105862 : break;
417 : case StubCallMode::kCallWasmRuntimeStub:
418 : kind = CallDescriptor::kCallWasmFunction;
419 : target_type = MachineType::Pointer();
420 134831 : break;
421 : case StubCallMode::kCallBuiltinPointer:
422 : kind = CallDescriptor::kCallBuiltinPointer;
423 : target_type = MachineType::AnyTagged();
424 1816 : break;
425 : }
426 :
427 : LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type);
428 : return new (zone) CallDescriptor( // --
429 : kind, // kind
430 : target_type, // target MachineType
431 : target_loc, // target location
432 : locations.Build(), // location_sig
433 : stack_parameter_count, // stack_parameter_count
434 : properties, // properties
435 : kNoCalleeSaved, // callee-saved registers
436 : kNoCalleeSaved, // callee-saved fp
437 : CallDescriptor::kCanUseRoots | flags, // flags
438 : descriptor.DebugName(), // debug name
439 12969984 : descriptor.allocatable_registers());
440 : }
441 :
442 : // static
443 43680 : CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor(
444 : Zone* zone, const CallInterfaceDescriptor& descriptor,
445 : int stack_parameter_count) {
446 : const int register_parameter_count = descriptor.GetRegisterParameterCount();
447 43680 : const int parameter_count = register_parameter_count + stack_parameter_count;
448 :
449 : DCHECK_EQ(descriptor.GetReturnCount(), 1);
450 43680 : LocationSignature::Builder locations(zone, 1, parameter_count);
451 :
452 : locations.AddReturn(regloc(kReturnRegister0, descriptor.GetReturnType(0)));
453 :
454 : // Add parameters in registers and on the stack.
455 393120 : for (int i = 0; i < parameter_count; i++) {
456 174720 : if (i < register_parameter_count) {
457 : // The first parameters go in registers.
458 : Register reg = descriptor.GetRegisterParameter(i);
459 : MachineType type = descriptor.GetParameterType(i);
460 : locations.AddParam(regloc(reg, type));
461 : } else {
462 : // The rest of the parameters go on the stack.
463 0 : int stack_slot = i - register_parameter_count - stack_parameter_count;
464 : locations.AddParam(LinkageLocation::ForCallerFrameSlot(
465 : stack_slot, MachineType::AnyTagged()));
466 : }
467 : }
468 :
469 : // The target for interpreter dispatches is a code entry address.
470 : MachineType target_type = MachineType::Pointer();
471 : LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type);
472 : const CallDescriptor::Flags kFlags =
473 : CallDescriptor::kCanUseRoots | CallDescriptor::kFixedTargetRegister;
474 : return new (zone) CallDescriptor( // --
475 : CallDescriptor::kCallAddress, // kind
476 : target_type, // target MachineType
477 : target_loc, // target location
478 : locations.Build(), // location_sig
479 : stack_parameter_count, // stack_parameter_count
480 : Operator::kNoProperties, // properties
481 : kNoCalleeSaved, // callee-saved registers
482 : kNoCalleeSaved, // callee-saved fp
483 : kFlags, // flags
484 131040 : descriptor.DebugName());
485 : }
486 :
487 21392 : LinkageLocation Linkage::GetOsrValueLocation(int index) const {
488 21392 : CHECK(incoming_->IsJSFunctionCall());
489 21392 : int parameter_count = static_cast<int>(incoming_->JSParameterCount() - 1);
490 : int first_stack_slot = OsrHelper::FirstStackSlotIndex(parameter_count);
491 :
492 21392 : if (index == kOsrContextSpillSlotIndex) {
493 : // Context. Use the parameter location of the context spill slot.
494 : // Parameter (arity + 2) is special for the context of the function frame.
495 : // >> context_index = target + receiver + params + new_target + #args
496 4647 : int context_index = 1 + 1 + parameter_count + 1 + 1;
497 4647 : return incoming_->GetInputLocation(context_index);
498 16745 : } else if (index >= first_stack_slot) {
499 : // Local variable stored in this (callee) stack.
500 : int spill_index =
501 9542 : index - first_stack_slot + StandardFrameConstants::kFixedSlotCount;
502 : return LinkageLocation::ForCalleeFrameSlot(spill_index,
503 : MachineType::AnyTagged());
504 : } else {
505 : // Parameter. Use the assigned location from the incoming call descriptor.
506 7203 : int parameter_index = 1 + index; // skip index 0, which is the target.
507 7203 : return incoming_->GetInputLocation(parameter_index);
508 : }
509 : }
510 :
511 : namespace {
512 : inline bool IsTaggedReg(const LinkageLocation& loc, Register reg) {
513 6517521 : return loc.IsRegister() && loc.AsRegister() == reg.code() &&
514 : loc.GetType().representation() ==
515 : MachineRepresentation::kTaggedPointer;
516 : }
517 : } // namespace
518 :
519 3738686 : bool Linkage::ParameterHasSecondaryLocation(int index) const {
520 : // TODO(titzer): this should be configurable, not call-type specific.
521 3738686 : if (incoming_->IsJSFunctionCall()) {
522 1757738 : LinkageLocation loc = GetParameterLocation(index);
523 3515481 : return IsTaggedReg(loc, kJSFunctionRegister) ||
524 : IsTaggedReg(loc, kContextRegister);
525 : }
526 1980948 : if (incoming_->IsWasmFunctionCall()) {
527 797481 : LinkageLocation loc = GetParameterLocation(index);
528 : return IsTaggedReg(loc, kWasmInstanceRegister);
529 : }
530 : return false;
531 : }
532 :
533 554688 : LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const {
534 : // TODO(titzer): these constants are necessary due to offset/slot# mismatch
535 : static const int kJSContextSlot = 2 + StandardFrameConstants::kCPSlotCount;
536 : static const int kJSFunctionSlot = 3 + StandardFrameConstants::kCPSlotCount;
537 : static const int kWasmInstanceSlot = 3 + StandardFrameConstants::kCPSlotCount;
538 :
539 : DCHECK(ParameterHasSecondaryLocation(index));
540 554688 : LinkageLocation loc = GetParameterLocation(index);
541 :
542 : // TODO(titzer): this should be configurable, not call-type specific.
543 554749 : if (incoming_->IsJSFunctionCall()) {
544 0 : if (IsTaggedReg(loc, kJSFunctionRegister)) {
545 : return LinkageLocation::ForCalleeFrameSlot(kJSFunctionSlot,
546 : MachineType::AnyTagged());
547 : } else {
548 : DCHECK(IsTaggedReg(loc, kContextRegister));
549 : return LinkageLocation::ForCalleeFrameSlot(kJSContextSlot,
550 : MachineType::AnyTagged());
551 : }
552 : }
553 554749 : if (incoming_->IsWasmFunctionCall()) {
554 : DCHECK(IsTaggedReg(loc, kWasmInstanceRegister));
555 : return LinkageLocation::ForCalleeFrameSlot(kWasmInstanceSlot,
556 : MachineType::AnyTagged());
557 : }
558 0 : UNREACHABLE();
559 : return LinkageLocation::ForCalleeFrameSlot(0, MachineType::AnyTagged());
560 : }
561 :
562 :
563 : } // namespace compiler
564 : } // namespace internal
565 121996 : } // namespace v8
|