LCOV - code coverage report
Current view: top level - src/compiler - linkage.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 98 113 86.7 %
Date: 2017-04-26 Functions: 17 19 89.5 %

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

Generated by: LCOV version 1.10