LCOV - code coverage report
Current view: top level - test/unittests/compiler - linkage-tail-call-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 187 187 100.0 %
Date: 2019-04-19 Functions: 29 42 69.0 %

          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/common-operator.h"
       6             : #include "src/compiler/graph.h"
       7             : #include "src/compiler/linkage.h"
       8             : #include "src/compiler/node.h"
       9             : #include "test/unittests/test-utils.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : namespace compiler {
      14             : 
      15             : namespace {
      16             : 
      17             : MachineType kMachineTypes[] = {
      18             :     MachineType::AnyTagged(), MachineType::AnyTagged(),
      19             :     MachineType::AnyTagged(), MachineType::AnyTagged(),
      20             :     MachineType::AnyTagged(), MachineType::AnyTagged(),
      21             :     MachineType::AnyTagged(), MachineType::AnyTagged()};
      22             : }
      23             : 
      24          26 : class LinkageTailCall : public TestWithZone {
      25             :  protected:
      26          25 :   CallDescriptor* NewStandardCallDescriptor(LocationSignature* locations) {
      27             :     DCHECK(arraysize(kMachineTypes) >=
      28             :            locations->return_count() + locations->parameter_count());
      29             :     USE(kMachineTypes);
      30             :     return new (zone()) CallDescriptor(
      31             :         CallDescriptor::kCallCodeObject, MachineType::AnyTagged(),
      32             :         LinkageLocation::ForAnyRegister(MachineType::Pointer()),
      33             :         locations,                 // location_sig
      34             :         0,                         // js_parameter_count
      35             :         Operator::kNoProperties,   // properties
      36             :         0,                         // callee-saved
      37             :         0,                         // callee-saved fp
      38             :         CallDescriptor::kNoFlags,  // flags,
      39          25 :         "");
      40             :   }
      41             : 
      42             :   LinkageLocation StackLocation(int loc) {
      43             :     return LinkageLocation::ForCallerFrameSlot(-loc, MachineType::Pointer());
      44             :   }
      45             : 
      46             :   LinkageLocation RegisterLocation(int loc) {
      47             :     return LinkageLocation::ForRegister(loc, MachineType::Pointer());
      48             :   }
      49             : };
      50             : 
      51             : 
      52       15419 : TEST_F(LinkageTailCall, EmptyToEmpty) {
      53           1 :   LocationSignature locations(0, 0, nullptr);
      54           1 :   CallDescriptor* desc = NewStandardCallDescriptor(&locations);
      55           1 :   CommonOperatorBuilder common(zone());
      56           1 :   const Operator* op = common.Call(desc);
      57           1 :   Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
      58           2 :   EXPECT_TRUE(desc->CanTailCall(node));
      59           1 :   const CallDescriptor* callee = CallDescriptorOf(node->op());
      60           1 :   int stack_param_delta = callee->GetStackParameterDelta(desc);
      61           2 :   EXPECT_EQ(0, stack_param_delta);
      62           1 : }
      63             : 
      64             : 
      65       15419 : TEST_F(LinkageTailCall, SameReturn) {
      66             :   // Caller
      67           1 :   LinkageLocation location_array[] = {RegisterLocation(0)};
      68             :   LocationSignature locations1(1, 0, location_array);
      69           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
      70             : 
      71             :   // Callee
      72           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
      73             : 
      74           1 :   CommonOperatorBuilder common(zone());
      75           1 :   const Operator* op = common.Call(desc2);
      76           1 :   Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
      77           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
      78           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
      79           2 :   EXPECT_EQ(0, stack_param_delta);
      80           1 : }
      81             : 
      82             : 
      83       15419 : TEST_F(LinkageTailCall, DifferingReturn) {
      84             :   // Caller
      85           1 :   LinkageLocation location_array1[] = {RegisterLocation(0)};
      86             :   LocationSignature locations1(1, 0, location_array1);
      87           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
      88             : 
      89             :   // Callee
      90           1 :   LinkageLocation location_array2[] = {RegisterLocation(1)};
      91             :   LocationSignature locations2(1, 0, location_array2);
      92           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
      93             : 
      94           1 :   CommonOperatorBuilder common(zone());
      95           1 :   const Operator* op = common.Call(desc2);
      96           1 :   Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
      97           2 :   EXPECT_TRUE(!desc1->CanTailCall(node));
      98           1 : }
      99             : 
     100             : 
     101       15419 : TEST_F(LinkageTailCall, MoreRegisterParametersCallee) {
     102             :   // Caller
     103           1 :   LinkageLocation location_array1[] = {RegisterLocation(0)};
     104             :   LocationSignature locations1(1, 0, location_array1);
     105           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     106             : 
     107             :   // Callee
     108             :   LinkageLocation location_array2[] = {RegisterLocation(0),
     109           1 :                                        RegisterLocation(0)};
     110             :   LocationSignature locations2(1, 1, location_array2);
     111           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
     112             : 
     113           1 :   CommonOperatorBuilder common(zone());
     114           1 :   const Operator* op = common.Call(desc2);
     115           1 :   Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
     116           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     117           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     118           2 :   EXPECT_EQ(0, stack_param_delta);
     119           1 : }
     120             : 
     121             : 
     122       15419 : TEST_F(LinkageTailCall, MoreRegisterParametersCaller) {
     123             :   // Caller
     124             :   LinkageLocation location_array1[] = {RegisterLocation(0),
     125           1 :                                        RegisterLocation(0)};
     126             :   LocationSignature locations1(1, 1, location_array1);
     127           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     128             : 
     129             :   // Callee
     130           1 :   LinkageLocation location_array2[] = {RegisterLocation(0)};
     131             :   LocationSignature locations2(1, 0, location_array2);
     132           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
     133             : 
     134           1 :   CommonOperatorBuilder common(zone());
     135           1 :   const Operator* op = common.Call(desc2);
     136           1 :   Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
     137           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     138           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     139           2 :   EXPECT_EQ(0, stack_param_delta);
     140           1 : }
     141             : 
     142             : 
     143       15419 : TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCallee) {
     144             :   // Caller
     145           1 :   LinkageLocation location_array1[] = {RegisterLocation(0)};
     146             :   LocationSignature locations1(1, 0, location_array1);
     147           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     148             : 
     149             :   // Callee
     150             :   LinkageLocation location_array2[] = {RegisterLocation(0), RegisterLocation(0),
     151           1 :                                        RegisterLocation(1), StackLocation(1)};
     152             :   LocationSignature locations2(1, 3, location_array2);
     153           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
     154             : 
     155           1 :   CommonOperatorBuilder common(zone());
     156           1 :   const Operator* op = common.Call(desc2);
     157           1 :   Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
     158           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     159           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     160             :   // We might need to add one slot of padding to the callee arguments.
     161           1 :   int expected = kPadArguments ? 2 : 1;
     162           1 :   EXPECT_EQ(expected, stack_param_delta);
     163           1 : }
     164             : 
     165             : 
     166       15419 : TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCaller) {
     167             :   // Caller
     168             :   LinkageLocation location_array[] = {RegisterLocation(0), RegisterLocation(0),
     169           1 :                                       RegisterLocation(1), StackLocation(1)};
     170             :   LocationSignature locations1(1, 3, location_array);
     171           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     172             : 
     173             :   // Callee
     174           1 :   LinkageLocation location_array2[] = {RegisterLocation(0)};
     175             :   LocationSignature locations2(1, 0, location_array2);
     176           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
     177             : 
     178           1 :   CommonOperatorBuilder common(zone());
     179           1 :   const Operator* op = common.Call(desc2);
     180           1 :   Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
     181           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     182           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     183             :   // We might need to drop one slot of padding from the caller's arguments.
     184           1 :   int expected = kPadArguments ? -2 : -1;
     185           1 :   EXPECT_EQ(expected, stack_param_delta);
     186           1 : }
     187             : 
     188             : 
     189       15419 : TEST_F(LinkageTailCall, MatchingStackParameters) {
     190             :   // Caller
     191             :   LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
     192           1 :                                       StackLocation(2), StackLocation(1)};
     193             :   LocationSignature locations1(1, 3, location_array);
     194           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     195             : 
     196             :   // Caller
     197             :   LocationSignature locations2(1, 3, location_array);
     198           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
     199             : 
     200           1 :   CommonOperatorBuilder common(zone());
     201           1 :   Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
     202           1 :   Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
     203           1 :   Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
     204           1 :   Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
     205           1 :   Node* parameters[] = {p0, p1, p2, p3};
     206           1 :   const Operator* op = common.Call(desc2);
     207             :   Node* const node =
     208           1 :       Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
     209           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     210           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     211           2 :   EXPECT_EQ(0, stack_param_delta);
     212           1 : }
     213             : 
     214             : 
     215       15419 : TEST_F(LinkageTailCall, NonMatchingStackParameters) {
     216             :   // Caller
     217             :   LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
     218           1 :                                       StackLocation(2), StackLocation(1)};
     219             :   LocationSignature locations1(1, 3, location_array);
     220           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     221             : 
     222             :   // Caller
     223             :   LocationSignature locations2(1, 3, location_array);
     224           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
     225             : 
     226           1 :   CommonOperatorBuilder common(zone());
     227           1 :   Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
     228           1 :   Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
     229           1 :   Node* p2 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
     230           1 :   Node* p3 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
     231           1 :   Node* parameters[] = {p0, p1, p2, p3};
     232           1 :   const Operator* op = common.Call(desc2);
     233             :   Node* const node =
     234           1 :       Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
     235           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     236           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     237           2 :   EXPECT_EQ(0, stack_param_delta);
     238           1 : }
     239             : 
     240             : 
     241       15419 : TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegisters) {
     242             :   // Caller
     243             :   LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
     244             :                                       StackLocation(2),    StackLocation(1),
     245           1 :                                       RegisterLocation(0), RegisterLocation(1)};
     246             :   LocationSignature locations1(1, 5, location_array);
     247           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     248             : 
     249             :   // Caller
     250             :   LocationSignature locations2(1, 3, location_array);
     251           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
     252             : 
     253           1 :   CommonOperatorBuilder common(zone());
     254           1 :   Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
     255           1 :   Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
     256           1 :   Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
     257           1 :   Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
     258           1 :   Node* parameters[] = {p0, p1, p2, p3};
     259           1 :   const Operator* op = common.Call(desc2);
     260             :   Node* const node =
     261           1 :       Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
     262           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     263           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     264           2 :   EXPECT_EQ(0, stack_param_delta);
     265           1 : }
     266             : 
     267             : 
     268       15419 : TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegisters) {
     269             :   // Caller
     270             :   LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
     271             :                                       StackLocation(2),    StackLocation(1),
     272           1 :                                       RegisterLocation(0), RegisterLocation(1)};
     273             :   LocationSignature locations1(1, 3, location_array);
     274           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     275             : 
     276             :   // Caller
     277             :   LocationSignature locations2(1, 5, location_array);
     278           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
     279             : 
     280           1 :   CommonOperatorBuilder common(zone());
     281           1 :   Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
     282           1 :   Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
     283           1 :   Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
     284           1 :   Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
     285           1 :   Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false);
     286           1 :   Node* parameters[] = {p0, p1, p2, p3, p4};
     287           1 :   const Operator* op = common.Call(desc2);
     288             :   Node* const node =
     289           1 :       Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
     290           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     291           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     292           2 :   EXPECT_EQ(0, stack_param_delta);
     293           1 : }
     294             : 
     295             : 
     296       15419 : TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegistersAndStack) {
     297             :   // Caller
     298             :   LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
     299             :                                       StackLocation(2),    StackLocation(1),
     300           1 :                                       RegisterLocation(0), StackLocation(4)};
     301             :   LocationSignature locations1(1, 5, location_array);
     302           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     303             : 
     304             :   // Caller
     305             :   LocationSignature locations2(1, 3, location_array);
     306           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
     307             : 
     308           1 :   CommonOperatorBuilder common(zone());
     309           1 :   Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
     310           1 :   Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
     311           1 :   Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
     312           1 :   Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
     313           1 :   Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false);
     314           1 :   Node* parameters[] = {p0, p1, p2, p3, p4};
     315           1 :   const Operator* op = common.Call(desc2);
     316             :   Node* const node =
     317           1 :       Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
     318           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     319           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     320             :   // We might need to add one slot of padding to the callee arguments.
     321           1 :   int expected = kPadArguments ? 0 : -1;
     322           1 :   EXPECT_EQ(expected, stack_param_delta);
     323           1 : }
     324             : 
     325             : 
     326       15419 : TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegistersAndStack) {
     327             :   // Caller
     328             :   LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
     329             :                                       StackLocation(2),    RegisterLocation(0),
     330           1 :                                       RegisterLocation(1), StackLocation(4)};
     331             :   LocationSignature locations1(1, 3, location_array);
     332           1 :   CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
     333             : 
     334             :   // Caller
     335             :   LocationSignature locations2(1, 5, location_array);
     336           1 :   CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
     337             : 
     338           1 :   CommonOperatorBuilder common(zone());
     339           1 :   Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
     340           1 :   Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
     341           1 :   Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
     342           1 :   Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
     343           1 :   Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false);
     344           1 :   Node* parameters[] = {p0, p1, p2, p3, p4};
     345           1 :   const Operator* op = common.Call(desc2);
     346             :   Node* const node =
     347           1 :       Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
     348           2 :   EXPECT_TRUE(desc1->CanTailCall(node));
     349           1 :   int stack_param_delta = desc2->GetStackParameterDelta(desc1);
     350             :   // We might need to drop one slot of padding from the caller's arguments.
     351           1 :   int expected = kPadArguments ? 0 : 1;
     352           1 :   EXPECT_EQ(expected, stack_param_delta);
     353           1 : }
     354             : 
     355             : }  // namespace compiler
     356             : }  // namespace internal
     357        9249 : }  // namespace v8

Generated by: LCOV version 1.10