LCOV - code coverage report
Current view: top level - src/compiler - linkage.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 98 120 81.7 %
Date: 2017-10-20 Functions: 16 19 84.2 %

          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/code-stubs.h"
       9             : #include "src/compilation-info.h"
      10             : #include "src/compiler/common-operator.h"
      11             : #include "src/compiler/frame.h"
      12             : #include "src/compiler/node.h"
      13             : #include "src/compiler/osr.h"
      14             : #include "src/compiler/pipeline.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : namespace compiler {
      19             : 
      20             : namespace {
      21             : 
      22             : LinkageLocation regloc(Register reg, MachineType type) {
      23             :   return LinkageLocation::ForRegister(reg.code(), type);
      24             : }
      25             : 
      26             : }  // namespace
      27             : 
      28             : 
      29           0 : std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) {
      30           0 :   switch (k) {
      31             :     case CallDescriptor::kCallCodeObject:
      32           0 :       os << "Code";
      33           0 :       break;
      34             :     case CallDescriptor::kCallJSFunction:
      35           0 :       os << "JS";
      36           0 :       break;
      37             :     case CallDescriptor::kCallAddress:
      38           0 :       os << "Addr";
      39           0 :       break;
      40             :   }
      41           0 :   return os;
      42             : }
      43             : 
      44             : 
      45           0 : std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) {
      46             :   // TODO(svenpanne) Output properties etc. and be less cryptic.
      47           0 :   return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount()
      48           0 :             << "s" << d.StackParameterCount() << "i" << d.InputCount() << "f"
      49           0 :             << d.FrameStateCount() << "t" << d.SupportsTailCalls();
      50             : }
      51             : 
      52       57792 : MachineSignature* CallDescriptor::GetMachineSignature(Zone* zone) const {
      53             :   size_t param_count = ParameterCount();
      54             :   size_t return_count = ReturnCount();
      55       14448 :   MachineType* types = zone->NewArray<MachineType>(param_count + return_count);
      56             :   int current = 0;
      57       28896 :   for (size_t i = 0; i < return_count; ++i) {
      58       28896 :     types[current++] = GetReturnType(i);
      59             :   }
      60       28896 :   for (size_t i = 0; i < param_count; ++i) {
      61       57792 :     types[current++] = GetParameterType(i);
      62             :   }
      63       14448 :   return new (zone) MachineSignature(return_count, param_count, types);
      64             : }
      65             : 
      66          13 : bool CallDescriptor::HasSameReturnLocationsAs(
      67          26 :     const CallDescriptor* other) const {
      68          13 :   if (ReturnCount() != other->ReturnCount()) return false;
      69          11 :   for (size_t i = 0; i < ReturnCount(); ++i) {
      70          12 :     if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false;
      71             :   }
      72             :   return true;
      73             : }
      74             : 
      75      186565 : int CallDescriptor::GetStackParameterDelta(
      76     2017658 :     CallDescriptor const* tail_caller) const {
      77             :   int callee_slots_above_sp = 0;
      78     2006846 :   for (size_t i = 0; i < InputCount(); ++i) {
      79      816858 :     LinkageLocation operand = GetInputLocation(i);
      80      816858 :     if (!operand.IsRegister()) {
      81             :       int new_candidate =
      82       52695 :           -operand.GetLocation() + operand.GetSizeInPointers() - 1;
      83       52695 :       if (new_candidate > callee_slots_above_sp) {
      84             :         callee_slots_above_sp = new_candidate;
      85             :       }
      86             :     }
      87             :   }
      88             :   int tail_caller_slots_above_sp = 0;
      89      186565 :   if (tail_caller != nullptr) {
      90     1841905 :     for (size_t i = 0; i < tail_caller->InputCount(); ++i) {
      91      827670 :       LinkageLocation operand = tail_caller->GetInputLocation(i);
      92      827670 :       if (!operand.IsRegister()) {
      93             :         int new_candidate =
      94        2973 :             -operand.GetLocation() + operand.GetSizeInPointers() - 1;
      95        2973 :         if (new_candidate > tail_caller_slots_above_sp) {
      96             :           tail_caller_slots_above_sp = new_candidate;
      97             :         }
      98             :       }
      99             :     }
     100             :   }
     101      186565 :   return callee_slots_above_sp - tail_caller_slots_above_sp;
     102             : }
     103             : 
     104          13 : bool CallDescriptor::CanTailCall(const Node* node) const {
     105          13 :   return HasSameReturnLocationsAs(CallDescriptorOf(node->op()));
     106             : }
     107             : 
     108     2376247 : int CallDescriptor::CalculateFixedFrameSize() const {
     109     2376247 :   switch (kind_) {
     110             :     case kCallJSFunction:
     111             :       return PushArgumentCount()
     112             :                  ? OptimizedBuiltinFrameConstants::kFixedSlotCount
     113     1239451 :                  : StandardFrameConstants::kFixedSlotCount;
     114             :       break;
     115             :     case kCallAddress:
     116             :       return CommonFrameConstants::kFixedSlotCountAboveFp +
     117             :              CommonFrameConstants::kCPSlotCount;
     118             :       break;
     119             :     case kCallCodeObject:
     120      678994 :       return TypedFrameConstants::kFixedSlotCount;
     121             :   }
     122           0 :   UNREACHABLE();
     123             : }
     124             : 
     125      443411 : CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
     126             :   DCHECK(!info->IsStub());
     127      443411 :   if (!info->closure().is_null()) {
     128             :     // If we are compiling a JS function, use a JS call descriptor,
     129             :     // plus the receiver.
     130             :     SharedFunctionInfo* shared = info->closure()->shared();
     131             :     return GetJSCallDescriptor(zone, info->is_osr(),
     132             :                                1 + shared->internal_formal_parameter_count(),
     133      886822 :                                CallDescriptor::kNoFlags);
     134             :   }
     135             :   return nullptr;  // TODO(titzer): ?
     136             : }
     137             : 
     138             : 
     139             : // static
     140     9158456 : bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) {
     141     9158456 :   switch (function) {
     142             :     // Most runtime functions need a FrameState. A few chosen ones that we know
     143             :     // not to call into arbitrary JavaScript, not to throw, and not to lazily
     144             :     // deoptimize are whitelisted here and can be called without a FrameState.
     145             :     case Runtime::kAbort:
     146             :     case Runtime::kAllocateInTargetSpace:
     147             :     case Runtime::kConvertReceiver:
     148             :     case Runtime::kCreateIterResultObject:
     149             :     case Runtime::kGeneratorGetContinuation:
     150             :     case Runtime::kIncBlockCounter:
     151             :     case Runtime::kIsFunction:
     152             :     case Runtime::kNewClosure:
     153             :     case Runtime::kNewClosure_Tenured:
     154             :     case Runtime::kNewFunctionContext:
     155             :     case Runtime::kPushBlockContext:
     156             :     case Runtime::kPushCatchContext:
     157             :     case Runtime::kReThrow:
     158             :     case Runtime::kStringCompare:
     159             :     case Runtime::kStringEqual:
     160             :     case Runtime::kStringNotEqual:
     161             :     case Runtime::kStringLessThan:
     162             :     case Runtime::kStringLessThanOrEqual:
     163             :     case Runtime::kStringGreaterThan:
     164             :     case Runtime::kStringGreaterThanOrEqual:
     165             :     case Runtime::kToFastProperties:  // TODO(conradw): Is it safe?
     166             :     case Runtime::kTraceEnter:
     167             :     case Runtime::kTraceExit:
     168             :       return false;
     169             : 
     170             :     // Some inline intrinsics are also safe to call without a FrameState.
     171             :     case Runtime::kInlineClassOf:
     172             :     case Runtime::kInlineCreateIterResultObject:
     173             :     case Runtime::kInlineGeneratorClose:
     174             :     case Runtime::kInlineGeneratorGetContext:
     175             :     case Runtime::kInlineGeneratorGetInputOrDebugPos:
     176             :     case Runtime::kInlineGeneratorGetResumeMode:
     177             :     case Runtime::kInlineCreateJSGeneratorObject:
     178             :     case Runtime::kInlineIsArray:
     179             :     case Runtime::kInlineIsJSMap:
     180             :     case Runtime::kInlineIsJSSet:
     181             :     case Runtime::kInlineIsJSWeakMap:
     182             :     case Runtime::kInlineIsJSWeakSet:
     183             :     case Runtime::kInlineIsJSReceiver:
     184             :     case Runtime::kInlineIsRegExp:
     185             :     case Runtime::kInlineIsSmi:
     186             :     case Runtime::kInlineIsTypedArray:
     187             :       return false;
     188             : 
     189             :     default:
     190             :       break;
     191             :   }
     192             : 
     193             :   // For safety, default to needing a FrameState unless whitelisted.
     194     8143841 :   return true;
     195             : }
     196             : 
     197             : 
     198           0 : bool CallDescriptor::UsesOnlyRegisters() const {
     199           0 :   for (size_t i = 0; i < InputCount(); ++i) {
     200           0 :     if (!GetInputLocation(i).IsRegister()) return false;
     201             :   }
     202           0 :   for (size_t i = 0; i < ReturnCount(); ++i) {
     203           0 :     if (!GetReturnLocation(i).IsRegister()) return false;
     204             :   }
     205             :   return true;
     206             : }
     207             : 
     208             : 
     209     1085295 : CallDescriptor* Linkage::GetRuntimeCallDescriptor(
     210             :     Zone* zone, Runtime::FunctionId function_id, int js_parameter_count,
     211             :     Operator::Properties properties, CallDescriptor::Flags flags) {
     212     1085295 :   const Runtime::Function* function = Runtime::FunctionForId(function_id);
     213     1085298 :   const int return_count = function->result_size;
     214     1085298 :   const char* debug_name = function->name;
     215             : 
     216     1085298 :   if (!Linkage::NeedsFrameStateInput(function_id)) {
     217             :     flags = static_cast<CallDescriptor::Flags>(
     218             :         flags & ~CallDescriptor::kNeedsFrameState);
     219             :   }
     220             : 
     221             :   return GetCEntryStubCallDescriptor(zone, return_count, js_parameter_count,
     222     1085298 :                                      debug_name, properties, flags);
     223             : }
     224             : 
     225     1093214 : CallDescriptor* Linkage::GetCEntryStubCallDescriptor(
     226             :     Zone* zone, int return_count, int js_parameter_count,
     227             :     const char* debug_name, Operator::Properties properties,
     228             :     CallDescriptor::Flags flags) {
     229             :   const size_t function_count = 1;
     230             :   const size_t num_args_count = 1;
     231             :   const size_t context_count = 1;
     232             :   const size_t parameter_count = function_count +
     233             :                                  static_cast<size_t>(js_parameter_count) +
     234     1093214 :                                  num_args_count + context_count;
     235             : 
     236             :   LocationSignature::Builder locations(zone, static_cast<size_t>(return_count),
     237     1093214 :                                        static_cast<size_t>(parameter_count));
     238             : 
     239             :   // Add returns.
     240     1093216 :   if (locations.return_count_ > 0) {
     241             :     locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged()));
     242             :   }
     243     1093216 :   if (locations.return_count_ > 1) {
     244         392 :     locations.AddReturn(regloc(kReturnRegister1, MachineType::AnyTagged()));
     245             :   }
     246     1093216 :   if (locations.return_count_ > 2) {
     247           0 :     locations.AddReturn(regloc(kReturnRegister2, MachineType::AnyTagged()));
     248             :   }
     249             : 
     250             :   // All parameters to the runtime call go on the stack.
     251     1470438 :   for (int i = 0; i < js_parameter_count; i++) {
     252             :     locations.AddParam(LinkageLocation::ForCallerFrameSlot(
     253     1470438 :         i - js_parameter_count, MachineType::AnyTagged()));
     254             :   }
     255             :   // Add runtime function itself.
     256             :   locations.AddParam(
     257             :       regloc(kRuntimeCallFunctionRegister, MachineType::Pointer()));
     258             : 
     259             :   // Add runtime call argument count.
     260             :   locations.AddParam(
     261             :       regloc(kRuntimeCallArgCountRegister, MachineType::Int32()));
     262             : 
     263             :   // Add context.
     264             :   locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged()));
     265             : 
     266             :   // The target for runtime calls is a code object.
     267             :   MachineType target_type = MachineType::AnyTagged();
     268             :   LinkageLocation target_loc =
     269             :       LinkageLocation::ForAnyRegister(MachineType::AnyTagged());
     270             :   return new (zone) CallDescriptor(     // --
     271             :       CallDescriptor::kCallCodeObject,  // kind
     272             :       target_type,                      // target MachineType
     273             :       target_loc,                       // target location
     274             :       locations.Build(),                // location_sig
     275             :       js_parameter_count,               // stack_parameter_count
     276             :       properties,                       // properties
     277             :       kNoCalleeSaved,                   // callee-saved
     278             :       kNoCalleeSaved,                   // callee-saved fp
     279             :       flags,                            // flags
     280     2186436 :       debug_name);                      // debug name
     281             : }
     282             : 
     283      761418 : CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
     284             :                                              int js_parameter_count,
     285             :                                              CallDescriptor::Flags flags) {
     286             :   const size_t return_count = 1;
     287             :   const size_t context_count = 1;
     288             :   const size_t new_target_count = 1;
     289             :   const size_t num_args_count = 1;
     290             :   const size_t parameter_count =
     291      761418 :       js_parameter_count + new_target_count + num_args_count + context_count;
     292             : 
     293             :   LocationSignature::Builder locations(zone, return_count, parameter_count);
     294             : 
     295             :   // All JS calls have exactly one return value.
     296             :   locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged()));
     297             : 
     298             :   // All parameters to JS calls go on the stack.
     299     3004407 :   for (int i = 0; i < js_parameter_count; i++) {
     300     2242989 :     int spill_slot_index = i - js_parameter_count;
     301             :     locations.AddParam(LinkageLocation::ForCallerFrameSlot(
     302             :         spill_slot_index, MachineType::AnyTagged()));
     303             :   }
     304             : 
     305             :   // Add JavaScript call new target value.
     306             :   locations.AddParam(
     307             :       regloc(kJavaScriptCallNewTargetRegister, MachineType::AnyTagged()));
     308             : 
     309             :   // Add JavaScript call argument count.
     310             :   locations.AddParam(
     311             :       regloc(kJavaScriptCallArgCountRegister, MachineType::Int32()));
     312             : 
     313             :   // Add context.
     314             :   locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged()));
     315             : 
     316             :   // The target for JS function calls is the JSFunction object.
     317             :   MachineType target_type = MachineType::AnyTagged();
     318             :   // When entering into an OSR function from unoptimized code the JSFunction
     319             :   // is not in a register, but it is on the stack in the marker spill slot.
     320             :   LinkageLocation target_loc =
     321             :       is_osr ? LinkageLocation::ForSavedCallerFunction()
     322      761418 :              : regloc(kJSFunctionRegister, MachineType::AnyTagged());
     323             :   return new (zone) CallDescriptor(     // --
     324             :       CallDescriptor::kCallJSFunction,  // kind
     325             :       target_type,                      // target MachineType
     326             :       target_loc,                       // target location
     327             :       locations.Build(),                // location_sig
     328             :       js_parameter_count,               // stack_parameter_count
     329             :       Operator::kNoProperties,          // properties
     330             :       kNoCalleeSaved,                   // callee-saved
     331             :       kNoCalleeSaved,                   // callee-saved fp
     332             :       CallDescriptor::kCanUseRoots |    // flags
     333             :           flags,                        // flags
     334     1522838 :       "js-call");
     335             : }
     336             : 
     337             : // TODO(all): Add support for return representations/locations to
     338             : // CallInterfaceDescriptor.
     339             : // TODO(turbofan): cache call descriptors for code stub calls.
     340     2715719 : CallDescriptor* Linkage::GetStubCallDescriptor(
     341             :     Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
     342             :     int stack_parameter_count, CallDescriptor::Flags flags,
     343             :     Operator::Properties properties, MachineType return_type,
     344             :     size_t return_count, Linkage::ContextSpecification context_spec) {
     345             :   const int register_parameter_count = descriptor.GetRegisterParameterCount();
     346             :   const int js_parameter_count =
     347     2715719 :       register_parameter_count + stack_parameter_count;
     348     2715719 :   const int context_count = context_spec == kPassContext ? 1 : 0;
     349             :   const size_t parameter_count =
     350     2715719 :       static_cast<size_t>(js_parameter_count + context_count);
     351             : 
     352             :   LocationSignature::Builder locations(zone, return_count, parameter_count);
     353             : 
     354             :   // Add returns.
     355     2715736 :   if (locations.return_count_ > 0) {
     356             :     locations.AddReturn(regloc(kReturnRegister0, return_type));
     357             :   }
     358     2715736 :   if (locations.return_count_ > 1) {
     359          96 :     locations.AddReturn(regloc(kReturnRegister1, return_type));
     360             :   }
     361     2715736 :   if (locations.return_count_ > 2) {
     362           0 :     locations.AddReturn(regloc(kReturnRegister2, return_type));
     363             :   }
     364             : 
     365             :   // Add parameters in registers and on the stack.
     366     8661786 :   for (int i = 0; i < js_parameter_count; i++) {
     367     8661786 :     if (i < register_parameter_count) {
     368             :       // The first parameters go in registers.
     369             :       Register reg = descriptor.GetRegisterParameter(i);
     370             :       MachineType type = descriptor.GetParameterType(i);
     371             :       locations.AddParam(regloc(reg, type));
     372             :     } else {
     373             :       // The rest of the parameters go on the stack.
     374     1360218 :       int stack_slot = i - register_parameter_count - stack_parameter_count;
     375             :       locations.AddParam(LinkageLocation::ForCallerFrameSlot(
     376             :           stack_slot, MachineType::AnyTagged()));
     377             :     }
     378             :   }
     379             :   // Add context.
     380     2715736 :   if (context_count) {
     381             :     locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged()));
     382             :   }
     383             : 
     384             :   // The target for stub calls is a code object.
     385             :   MachineType target_type = MachineType::AnyTagged();
     386             :   LinkageLocation target_loc =
     387             :       LinkageLocation::ForAnyRegister(MachineType::AnyTagged());
     388             :   return new (zone) CallDescriptor(     // --
     389             :       CallDescriptor::kCallCodeObject,  // kind
     390             :       target_type,                      // target MachineType
     391             :       target_loc,                       // target location
     392             :       locations.Build(),                // location_sig
     393             :       stack_parameter_count,            // stack_parameter_count
     394             :       properties,                       // properties
     395             :       kNoCalleeSaved,                   // callee-saved registers
     396             :       kNoCalleeSaved,                   // callee-saved fp
     397             :       CallDescriptor::kCanUseRoots |    // flags
     398             :           flags,                        // flags
     399    10862950 :       descriptor.DebugName(isolate), descriptor.allocatable_registers());
     400             : }
     401             : 
     402             : // static
     403       73123 : CallDescriptor* Linkage::GetAllocateCallDescriptor(Zone* zone) {
     404             :   LocationSignature::Builder locations(zone, 1, 1);
     405             : 
     406             :   locations.AddParam(regloc(kAllocateSizeRegister, MachineType::Int32()));
     407             : 
     408       73123 :   locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged()));
     409             : 
     410             :   // The target for allocate calls is a code object.
     411             :   MachineType target_type = MachineType::AnyTagged();
     412             :   LinkageLocation target_loc =
     413             :       LinkageLocation::ForAnyRegister(MachineType::AnyTagged());
     414             :   return new (zone) CallDescriptor(     // --
     415             :       CallDescriptor::kCallCodeObject,  // kind
     416             :       target_type,                      // target MachineType
     417             :       target_loc,                       // target location
     418             :       locations.Build(),                // location_sig
     419             :       0,                                // stack_parameter_count
     420             :       Operator::kNoThrow,               // properties
     421             :       kNoCalleeSaved,                   // callee-saved registers
     422             :       kNoCalleeSaved,                   // callee-saved fp
     423             :       CallDescriptor::kCanUseRoots,     // flags
     424      146246 :       "Allocate");
     425             : }
     426             : 
     427             : // static
     428       16616 : CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor(
     429             :     Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
     430             :     int stack_parameter_count) {
     431             :   const int register_parameter_count = descriptor.GetRegisterParameterCount();
     432       16616 :   const int parameter_count = register_parameter_count + stack_parameter_count;
     433             : 
     434       16616 :   LocationSignature::Builder locations(zone, 0, parameter_count);
     435             : 
     436             :   // Add parameters in registers and on the stack.
     437       83080 :   for (int i = 0; i < parameter_count; i++) {
     438       66464 :     if (i < register_parameter_count) {
     439             :       // The first parameters go in registers.
     440             :       Register reg = descriptor.GetRegisterParameter(i);
     441             :       MachineType type = descriptor.GetParameterType(i);
     442             :       locations.AddParam(regloc(reg, type));
     443             :     } else {
     444             :       // The rest of the parameters go on the stack.
     445           0 :       int stack_slot = i - register_parameter_count - stack_parameter_count;
     446             :       locations.AddParam(LinkageLocation::ForCallerFrameSlot(
     447             :           stack_slot, MachineType::AnyTagged()));
     448             :     }
     449             :   }
     450             : 
     451             :   // The target for interpreter dispatches is a code entry address.
     452             :   MachineType target_type = MachineType::Pointer();
     453             :   LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type);
     454             :   return new (zone) CallDescriptor(            // --
     455             :       CallDescriptor::kCallAddress,            // kind
     456             :       target_type,                             // target MachineType
     457             :       target_loc,                              // target location
     458             :       locations.Build(),                       // location_sig
     459             :       stack_parameter_count,                   // stack_parameter_count
     460             :       Operator::kNoProperties,                 // properties
     461             :       kNoCalleeSaved,                          // callee-saved registers
     462             :       kNoCalleeSaved,                          // callee-saved fp
     463             :       CallDescriptor::kCanUseRoots |           // flags
     464             :           CallDescriptor::kSupportsTailCalls,  // flags
     465       49848 :       descriptor.DebugName(isolate));
     466             : }
     467             : 
     468       24445 : LinkageLocation Linkage::GetOsrValueLocation(int index) const {
     469       24445 :   CHECK(incoming_->IsJSFunctionCall());
     470       24445 :   int parameter_count = static_cast<int>(incoming_->JSParameterCount() - 1);
     471             :   int first_stack_slot = OsrHelper::FirstStackSlotIndex(parameter_count);
     472             : 
     473       24445 :   if (index == kOsrContextSpillSlotIndex) {
     474             :     // Context. Use the parameter location of the context spill slot.
     475             :     // Parameter (arity + 2) is special for the context of the function frame.
     476             :     // >> context_index = target + receiver + params + new_target + #args
     477        5809 :     int context_index = 1 + 1 + parameter_count + 1 + 1;
     478        5809 :     return incoming_->GetInputLocation(context_index);
     479       18636 :   } else if (index >= first_stack_slot) {
     480             :     // Local variable stored in this (callee) stack.
     481             :     int spill_index =
     482        9849 :         index - first_stack_slot + StandardFrameConstants::kFixedSlotCount;
     483             :     return LinkageLocation::ForCalleeFrameSlot(spill_index,
     484             :                                                MachineType::AnyTagged());
     485             :   } else {
     486             :     // Parameter. Use the assigned location from the incoming call descriptor.
     487        8787 :     int parameter_index = 1 + index;  // skip index 0, which is the target.
     488        8787 :     return incoming_->GetInputLocation(parameter_index);
     489             :   }
     490             : }
     491             : 
     492             : 
     493     2453496 : bool Linkage::ParameterHasSecondaryLocation(int index) const {
     494     2453496 :   if (!incoming_->IsJSFunctionCall()) return false;
     495             :   LinkageLocation loc = GetParameterLocation(index);
     496     1520671 :   return (loc == regloc(kJSFunctionRegister, MachineType::AnyTagged()) ||
     497     1520671 :           loc == regloc(kContextRegister, MachineType::AnyTagged()));
     498             : }
     499             : 
     500      493943 : LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const {
     501             :   DCHECK(ParameterHasSecondaryLocation(index));
     502             :   LinkageLocation loc = GetParameterLocation(index);
     503             : 
     504      493943 :   if (loc == regloc(kJSFunctionRegister, MachineType::AnyTagged())) {
     505             :     return LinkageLocation::ForCalleeFrameSlot(Frame::kJSFunctionSlot,
     506             :                                                MachineType::AnyTagged());
     507             :   } else {
     508             :     DCHECK(loc == regloc(kContextRegister, MachineType::AnyTagged()));
     509             :     return LinkageLocation::ForCalleeFrameSlot(Frame::kContextSlot,
     510             :                                                MachineType::AnyTagged());
     511             :   }
     512             : }
     513             : 
     514             : 
     515             : }  // namespace compiler
     516             : }  // namespace internal
     517             : }  // namespace v8

Generated by: LCOV version 1.10