Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: test/unittests/compiler/linkage-tail-call-unittest.cc

Issue 1245523002: [turbofan]: Fix tail calls edge cases and add tests (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@1220823004
Patch Set: Fix ASAN again Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/linkage.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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[] = {kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
18 kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
19 kMachAnyTagged, kMachAnyTagged};
20 }
21
22 class LinkageTailCall : public TestWithZone {
23 protected:
24 CallDescriptor* NewStandardCallDescriptor(LocationSignature* locations) {
25 DCHECK(arraysize(kMachineTypes) >=
26 locations->return_count() + locations->parameter_count());
27 MachineSignature* types = new (zone()) MachineSignature(
28 locations->return_count(), locations->parameter_count(), kMachineTypes);
29 return new (zone())
30 CallDescriptor(CallDescriptor::kCallCodeObject, kMachAnyTagged,
31 LinkageLocation::AnyRegister(),
32 types, // machine_sig
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 "");
40 }
41
42 LinkageLocation StackLocation(int loc) { return LinkageLocation(-loc); }
43
44 LinkageLocation RegisterLocation(int loc) { return LinkageLocation(loc); }
45 };
46
47
48 TEST_F(LinkageTailCall, EmptyToEmpty) {
49 LocationSignature locations(0, 0, nullptr);
50 CallDescriptor* desc = NewStandardCallDescriptor(&locations);
51 CommonOperatorBuilder common(zone());
52 const Operator* op = common.Call(desc);
53 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
54 EXPECT_TRUE(desc->CanTailCall(node));
55 }
56
57
58 TEST_F(LinkageTailCall, SameReturn) {
59 // Caller
60 LinkageLocation location_array[] = {RegisterLocation(0)};
61 LocationSignature locations1(1, 0, location_array);
62 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
63
64 // Callee
65 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
66
67 CommonOperatorBuilder common(zone());
68 const Operator* op = common.Call(desc2);
69 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
70 EXPECT_TRUE(desc1->CanTailCall(node));
71 }
72
73
74 TEST_F(LinkageTailCall, DifferingReturn) {
75 // Caller
76 LinkageLocation location_array1[] = {RegisterLocation(0)};
77 LocationSignature locations1(1, 0, location_array1);
78 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
79
80 // Callee
81 LinkageLocation location_array2[] = {RegisterLocation(1)};
82 LocationSignature locations2(1, 0, location_array2);
83 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
84
85 CommonOperatorBuilder common(zone());
86 const Operator* op = common.Call(desc2);
87 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
88 EXPECT_FALSE(desc1->CanTailCall(node));
89 }
90
91
92 TEST_F(LinkageTailCall, MoreRegisterParametersCallee) {
93 // Caller
94 LinkageLocation location_array1[] = {RegisterLocation(0)};
95 LocationSignature locations1(1, 0, location_array1);
96 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
97
98 // Callee
99 LinkageLocation location_array2[] = {RegisterLocation(0),
100 RegisterLocation(0)};
101 LocationSignature locations2(1, 1, location_array2);
102 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
103
104 CommonOperatorBuilder common(zone());
105 const Operator* op = common.Call(desc2);
106 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
107 EXPECT_TRUE(desc1->CanTailCall(node));
108 }
109
110
111 TEST_F(LinkageTailCall, MoreRegisterParametersCaller) {
112 // Caller
113 LinkageLocation location_array1[] = {RegisterLocation(0),
114 RegisterLocation(0)};
115 LocationSignature locations1(1, 1, location_array1);
116 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
117
118 // Callee
119 LinkageLocation location_array2[] = {RegisterLocation(0)};
120 LocationSignature locations2(1, 0, location_array2);
121 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
122
123 CommonOperatorBuilder common(zone());
124 const Operator* op = common.Call(desc2);
125 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
126 EXPECT_TRUE(desc1->CanTailCall(node));
127 }
128
129
130 TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCallee) {
131 // Caller
132 LinkageLocation location_array1[] = {RegisterLocation(0)};
133 LocationSignature locations1(1, 0, location_array1);
134 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
135
136 // Callee
137 LinkageLocation location_array2[] = {RegisterLocation(0), RegisterLocation(0),
138 RegisterLocation(1), StackLocation(1)};
139 LocationSignature locations2(1, 3, location_array2);
140 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
141
142 CommonOperatorBuilder common(zone());
143 const Operator* op = common.Call(desc2);
144 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
145 EXPECT_FALSE(desc1->CanTailCall(node));
146 }
147
148
149 TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCaller) {
150 // Caller
151 LinkageLocation location_array[] = {RegisterLocation(0), RegisterLocation(0),
152 RegisterLocation(1), StackLocation(1)};
153 LocationSignature locations1(1, 3, location_array);
154 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
155
156 // Callee
157 LinkageLocation location_array2[] = {RegisterLocation(0)};
158 LocationSignature locations2(1, 0, location_array2);
159 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
160
161 CommonOperatorBuilder common(zone());
162 const Operator* op = common.Call(desc2);
163 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
164 EXPECT_FALSE(desc1->CanTailCall(node));
165 }
166
167
168 TEST_F(LinkageTailCall, MatchingStackParameters) {
169 // Caller
170 LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
171 StackLocation(2), StackLocation(1)};
172 LocationSignature locations1(1, 3, location_array);
173 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
174
175 // Caller
176 LocationSignature locations2(1, 3, location_array);
177 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
178
179 CommonOperatorBuilder common(zone());
180 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
181 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
182 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
183 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
184 Node* parameters[] = {p0, p1, p2, p3};
185 const Operator* op = common.Call(desc2);
186 Node* const node =
187 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
188 EXPECT_TRUE(desc1->CanTailCall(node));
189 }
190
191
192 TEST_F(LinkageTailCall, NonMatchingStackParameters) {
193 // Caller
194 LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
195 StackLocation(2), StackLocation(1)};
196 LocationSignature locations1(1, 3, location_array);
197 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
198
199 // Caller
200 LocationSignature locations2(1, 3, location_array);
201 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
202
203 CommonOperatorBuilder common(zone());
204 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
205 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
206 Node* p2 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
207 Node* p3 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
208 Node* parameters[] = {p0, p1, p2, p3};
209 const Operator* op = common.Call(desc2);
210 Node* const node =
211 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
212 EXPECT_FALSE(desc1->CanTailCall(node));
213 }
214
215
216 TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegisters) {
217 // Caller
218 LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
219 StackLocation(2), StackLocation(1),
220 RegisterLocation(0), RegisterLocation(1)};
221 LocationSignature locations1(1, 5, location_array);
222 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
223
224 // Caller
225 LocationSignature locations2(1, 3, location_array);
226 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
227
228 CommonOperatorBuilder common(zone());
229 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
230 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
231 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
232 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
233 Node* parameters[] = {p0, p1, p2, p3};
234 const Operator* op = common.Call(desc2);
235 Node* const node =
236 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
237 EXPECT_TRUE(desc1->CanTailCall(node));
238 }
239
240
241 TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegisters) {
242 // Caller
243 LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
244 StackLocation(2), StackLocation(1),
245 RegisterLocation(0), RegisterLocation(1)};
246 LocationSignature locations1(1, 3, location_array);
247 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
248
249 // Caller
250 LocationSignature locations2(1, 5, location_array);
251 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1);
252
253 CommonOperatorBuilder common(zone());
254 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
255 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
256 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
257 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
258 Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false);
259 Node* parameters[] = {p0, p1, p2, p3, p4};
260 const Operator* op = common.Call(desc2);
261 Node* const node =
262 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
263 EXPECT_TRUE(desc1->CanTailCall(node));
264 }
265
266
267 TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegistersAndStack) {
268 // Caller
269 LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
270 StackLocation(2), StackLocation(1),
271 RegisterLocation(0), StackLocation(4)};
272 LocationSignature locations1(1, 5, location_array);
273 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
274
275 // Caller
276 LocationSignature locations2(1, 3, location_array);
277 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
278
279 CommonOperatorBuilder common(zone());
280 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
281 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
282 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
283 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
284 Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false);
285 Node* parameters[] = {p0, p1, p2, p3, p4};
286 const Operator* op = common.Call(desc2);
287 Node* const node =
288 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
289 EXPECT_FALSE(desc1->CanTailCall(node));
290 }
291
292
293 TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegistersAndStack) {
294 // Caller
295 LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3),
296 StackLocation(2), RegisterLocation(0),
297 RegisterLocation(1), StackLocation(4)};
298 LocationSignature locations1(1, 3, location_array);
299 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1);
300
301 // Caller
302 LocationSignature locations2(1, 5, location_array);
303 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2);
304
305 CommonOperatorBuilder common(zone());
306 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
307 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
308 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
309 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
310 Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false);
311 Node* parameters[] = {p0, p1, p2, p3, p4};
312 const Operator* op = common.Call(desc2);
313 Node* const node =
314 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
315 EXPECT_FALSE(desc1->CanTailCall(node));
316 }
317
318 } // namespace compiler
319 } // namespace internal
320 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/linkage.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698