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

Side by Side Diff: tools/gen-inlining-tests.py

Issue 2285743002: [turbofan] Improve inline-exception tests. (Closed)
Patch Set: Created 4 years, 3 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
OLDNEW
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 2
3 # Copyright 2016 the V8 project authors. All rights reserved. 3 # Copyright 2016 the V8 project authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 7
8 from collections import namedtuple 8 from collections import namedtuple
9 import textwrap 9 import textwrap
10 import sys 10 import sys
11 11
12 SHARD_FILENAME_TEMPLATE = "test/mjsunit/compiler/inline-exception-{shard}.js" 12 SHARD_FILENAME_TEMPLATE = "test/mjsunit/compiler/inline-exception-{shard}.js"
13 # Generates 2 files. Found by trial and error. 13 # Generates 2 files. Found by trial and error.
14 SHARD_SIZE = 94 14 SHARD_SIZE = 97
15 15
16 PREAMBLE = """ 16 PREAMBLE = """
17 17
18 // Copyright 2016 the V8 project authors. All rights reserved. 18 // Copyright 2016 the V8 project authors. All rights reserved.
19 // Use of this source code is governed by a BSD-style license that can be 19 // Use of this source code is governed by a BSD-style license that can be
20 // found in the LICENSE file. 20 // found in the LICENSE file.
21 21
22 // Flags: --allow-natives-syntax --turbo --no-always-opt 22 // Flags: --allow-natives-syntax --turbo --no-always-opt
23 23
24 // This test file was generated by tools/gen-inlining-tests.py . 24 // This test file was generated by tools/gen-inlining-tests.py .
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 counter++; 74 counter++;
75 return 15; 75 return 15;
76 } 76 }
77 77
78 function increaseAndThrow42() { 78 function increaseAndThrow42() {
79 if (deopt) %DeoptimizeFunction(f); 79 if (deopt) %DeoptimizeFunction(f);
80 counter++; 80 counter++;
81 throw 42; 81 throw 42;
82 } 82 }
83 83
84 function increaseAndReturn15_noopt_inner() {
85 if (deopt) %DeoptimizeFunction(f);
86 counter++;
87 return 15;
88 }
89
90 %NeverOptimizeFunction(increaseAndReturn15_noopt_inner);
91
92 function increaseAndThrow42_noopt_inner() {
93 if (deopt) %DeoptimizeFunction(f);
94 counter++;
95 throw 42;
96 }
97
98 %NeverOptimizeFunction(increaseAndThrow42_noopt_inner);
99
100 // Alternative 1
101
84 function returnOrThrow(doReturn) { 102 function returnOrThrow(doReturn) {
85 if (doReturn) { 103 if (doReturn) {
86 return increaseAndReturn15(); 104 return increaseAndReturn15();
87 } else { 105 } else {
88 return increaseAndThrow42(); 106 return increaseAndThrow42();
89 } 107 }
90 } 108 }
91 109
110 // Alternative 2
111
112 function increaseAndReturn15_noopt_outer() {
113 return increaseAndReturn15_noopt_inner();
114 }
115
116 function increaseAndThrow42_noopt_outer() {
117 return increaseAndThrow42_noopt_inner();
118 }
119
120 // Alternative 3.
92 // When passed either {increaseAndReturn15} or {increaseAndThrow42}, it acts 121 // When passed either {increaseAndReturn15} or {increaseAndThrow42}, it acts
93 // as the other one. 122 // as the other one.
94 function invertFunctionCall(f) { 123 function invertFunctionCall(f) {
95 var result; 124 var result;
96 try { 125 try {
97 result = f(); 126 result = f();
98 } catch (ex) { 127 } catch (ex) {
99 return ex - 27; 128 return ex - 27;
100 } 129 }
101 throw result + 27; 130 throw result + 27;
102 } 131 }
103 132
133 // Alternative 4: constructor
104 function increaseAndStore15Constructor() { 134 function increaseAndStore15Constructor() {
105 if (deopt) %DeoptimizeFunction(f); 135 if (deopt) %DeoptimizeFunction(f);
106 ++counter; 136 ++counter;
107 this.x = 15; 137 this.x = 15;
108 } 138 }
109 139
110 function increaseAndThrow42Constructor() { 140 function increaseAndThrow42Constructor() {
111 if (deopt) %DeoptimizeFunction(f); 141 if (deopt) %DeoptimizeFunction(f);
112 ++counter; 142 ++counter;
113 this.x = 42; 143 this.x = 42;
114 throw this.x; 144 throw this.x;
115 } 145 }
116 146
147 // Alternative 5: property
117 var magic = {}; 148 var magic = {};
118 Object.defineProperty(magic, 'prop', { 149 Object.defineProperty(magic, 'prop', {
119 get: function () { 150 get: function () {
120 if (deopt) %DeoptimizeFunction(f); 151 if (deopt) %DeoptimizeFunction(f);
121 return 15 + 0 * ++counter; 152 return 15 + 0 * ++counter;
122 }, 153 },
123 154
124 set: function(x) { 155 set: function(x) {
125 // argument should be 37 156 // argument should be 37
126 if (deopt) %DeoptimizeFunction(f); 157 if (deopt) %DeoptimizeFunction(f);
127 counter -= 36 - x; // increments counter 158 counter -= 36 - x; // increments counter
128 throw 42; 159 throw 42;
129 } 160 }
130 }) 161 })
131 162
132 // Generate type feedback. 163 // Generate type feedback.
133 164
165 assertEquals(15, increaseAndReturn15_noopt_outer());
134 assertEquals(15, (new increaseAndStore15Constructor()).x); 166 assertEquals(15, (new increaseAndStore15Constructor()).x);
135 assertThrowsEquals(function() { 167 assertThrowsEquals(function() {
136 return (new increaseAndThrow42Constructor()).x; 168 return (new increaseAndThrow42Constructor()).x;
137 }, 169 },
138 42); 170 42);
139 171
140 function runThisShard() { 172 function runThisShard() {
141 173
142 """.strip() 174 """.strip()
143 175
144 def booltuples(n): 176 def booltuples(n):
145 """booltuples(2) yields 4 tuples: (False, False), (False, True), 177 """booltuples(2) yields 4 tuples: (False, False), (False, True),
146 (True, False), (True, True).""" 178 (True, False), (True, True)."""
147 179
148 assert isinstance(n, int) 180 assert isinstance(n, int)
149 if n <= 0: 181 if n <= 0:
150 yield () 182 yield ()
151 else: 183 else:
152 for initial in booltuples(n-1): 184 for initial in booltuples(n-1):
153 yield initial + (False,) 185 yield initial + (False,)
154 yield initial + (True,) 186 yield initial + (True,)
155 187
156 FLAGLETTERS="4321trflcrltfrtld"
157
158 def fnname(flags): 188 def fnname(flags):
159 assert len(FLAGLETTERS) == len(flags) 189 assert len(FLAGLETTERS) == len(flags)
160 190
161 return "f_" + ''.join( 191 return "f_" + ''.join(
162 FLAGLETTERS[i] if b else '_' 192 FLAGLETTERS[i] if b else '_'
163 for (i, b) in enumerate(flags)) 193 for (i, b) in enumerate(flags))
164 194
165 NUM_TESTS_PRINTED = 0 195 NUM_TESTS_PRINTED = 0
166 NUM_TESTS_IN_SHARD = 0 196 NUM_TESTS_IN_SHARD = 0
167 197
168 def printtest(flags): 198 def printtest(flags):
169 """Print a test case. Takes a couple of boolean flags, on which the 199 """Print a test case. Takes a couple of boolean flags, on which the
170 printed Javascript code depends.""" 200 printed Javascript code depends."""
171 201
172 assert all(isinstance(flag, bool) for flag in flags) 202 assert all(isinstance(flag, bool) for flag in flags)
173 203
174 # The alternative flags are in reverse order so that if we take all possible 204 # The alternative flags are in reverse order so that if we take all possible
175 # tuples, ordered lexicographically from false to true, we get first the 205 # tuples, ordered lexicographically from false to true, we get first the
176 # default, then alternative 1, then 2, etc. 206 # default, then alternative 1, then 2, etc.
177 ( 207 (
178 alternativeFn4, # use alternative #4 for returning/throwing. 208 alternativeFn5, # use alternative #5 for returning/throwing:
179 alternativeFn3, # use alternative #3 for returning/throwing. 209 # return/throw using property
180 alternativeFn2, # use alternative #2 for returning/throwing. 210 alternativeFn4, # use alternative #4 for returning/throwing:
181 alternativeFn1, # use alternative #1 for returning/throwing. 211 # return/throw using constructor
212 alternativeFn3, # use alternative #3 for returning/throwing:
213 # return/throw indirectly, based on function argument
214 alternativeFn2, # use alternative #2 for returning/throwing:
215 # return/throw indirectly in unoptimized code,
216 # no branching
217 alternativeFn1, # use alternative #1 for returning/throwing:
218 # return/throw indirectly, based on boolean arg
182 tryThrows, # in try block, call throwing function 219 tryThrows, # in try block, call throwing function
183 tryReturns, # in try block, call returning function 220 tryReturns, # in try block, call returning function
184 tryFirstReturns, # in try block, returning goes before throwing 221 tryFirstReturns, # in try block, returning goes before throwing
185 tryResultToLocal, # in try block, result goes to local variable 222 tryResultToLocal, # in try block, result goes to local variable
186 doCatch, # include catch block 223 doCatch, # include catch block
187 catchReturns, # in catch block, return 224 catchReturns, # in catch block, return
188 catchWithLocal, # in catch block, modify or return the local variable 225 catchWithLocal, # in catch block, modify or return the local variable
189 catchThrows, # in catch block, throw 226 catchThrows, # in catch block, throw
190 doFinally, # include finally block 227 doFinally, # include finally block
191 finallyReturns, # in finally block, return local variable 228 finallyReturns, # in finally block, return local variable
192 finallyThrows, # in finally block, throw 229 finallyThrows, # in finally block, throw
193 endReturnLocal, # at very end, return variable local 230 endReturnLocal, # at very end, return variable local
194 deopt, # deopt inside inlined function 231 deopt, # deopt inside inlined function
195 ) = flags 232 ) = flags
196 233
197 # BASIC RULES 234 # BASIC RULES
198 235
199 # Only one alternative can be applied at any time. 236 # Only one alternative can be applied at any time.
200 if alternativeFn1 + alternativeFn2 + alternativeFn3 + alternativeFn4 > 1: 237 if (alternativeFn1 + alternativeFn2 + alternativeFn3 + alternativeFn4
238 + alternativeFn5 > 1):
201 return 239 return
202 240
203 # In try, return or throw, or both. 241 # In try, return or throw, or both.
204 if not (tryReturns or tryThrows): return 242 if not (tryReturns or tryThrows): return
205 243
206 # Either doCatch or doFinally. 244 # Either doCatch or doFinally.
207 if not doCatch and not doFinally: return 245 if not doCatch and not doFinally: return
208 246
209 # Catch flags only make sense when catching 247 # Catch flags only make sense when catching
210 if not doCatch and (catchReturns or catchWithLocal or catchThrows): 248 if not doCatch and (catchReturns or catchWithLocal or catchThrows):
(...skipping 10 matching lines...) Expand all
221 # From the try and finally block, we can return or throw, but not both. 259 # From the try and finally block, we can return or throw, but not both.
222 if catchReturns and catchThrows: return 260 if catchReturns and catchThrows: return
223 if finallyReturns and finallyThrows: return 261 if finallyReturns and finallyThrows: return
224 262
225 # If at the end we return the local, we need to have touched it. 263 # If at the end we return the local, we need to have touched it.
226 if endReturnLocal and not (tryResultToLocal or catchWithLocal): return 264 if endReturnLocal and not (tryResultToLocal or catchWithLocal): return
227 265
228 # PRUNING 266 # PRUNING
229 267
230 anyAlternative = any([alternativeFn1, alternativeFn2, alternativeFn3, 268 anyAlternative = any([alternativeFn1, alternativeFn2, alternativeFn3,
231 alternativeFn4]) 269 alternativeFn4, alternativeFn5])
232 rareAlternative = any([alternativeFn1, alternativeFn3, alternativeFn4]) 270 specificAlternative = any([alternativeFn2, alternativeFn3])
271 rareAlternative = not specificAlternative
233 272
234 # If try returns and throws, then don't catchWithLocal, endReturnLocal, or 273 # If try returns and throws, then don't catchWithLocal, endReturnLocal, or
235 # deopt, or do any alternative. 274 # deopt, or do any alternative.
236 if (tryReturns and tryThrows and 275 if (tryReturns and tryThrows and
237 (catchWithLocal or endReturnLocal or deopt or anyAlternative)): 276 (catchWithLocal or endReturnLocal or deopt or anyAlternative)):
238 return 277 return
239 # We don't do any alternative if we do a finally. 278 # We don't do any alternative if we do a finally.
240 if doFinally and anyAlternative: return 279 if doFinally and anyAlternative: return
241 # We only use the local variable if we do alternative #2. 280 # We only use the local variable if we do alternative #2 or #3.
242 if ((tryResultToLocal or catchWithLocal or endReturnLocal) and 281 if ((tryResultToLocal or catchWithLocal or endReturnLocal) and
243 not alternativeFn2): 282 not specificAlternative):
244 return 283 return
245 # We don't need to test deopting into a finally. 284 # We don't need to test deopting into a finally.
246 if doFinally and deopt: return 285 if doFinally and deopt: return
247 286
287 # We're only interested in alternative #2 if we have endReturnLocal, no
288 # catchReturns, and no catchThrows, and deopt.
289 if (alternativeFn2 and
290 (not endReturnLocal or catchReturns or catchThrows or not deopt)):
291 return
248 292
249 293
250 # Flag check succeeded. 294 # Flag check succeeded.
251 295
252 trueFlagNames = [name for (name, value) in flags._asdict().items() if value] 296 trueFlagNames = [name for (name, value) in flags._asdict().items() if value]
253 flagsMsgLine = " // Variant flags: [{}]".format(', '.join(trueFlagNames)) 297 flagsMsgLine = " // Variant flags: [{}]".format(', '.join(trueFlagNames))
254 write(textwrap.fill(flagsMsgLine, subsequent_indent=' // ')) 298 write(textwrap.fill(flagsMsgLine, subsequent_indent=' // '))
255 write("") 299 write("")
256 300
257 if not anyAlternative: 301 if not anyAlternative:
258 fragments = { 302 fragments = {
259 'increaseAndReturn15': 'increaseAndReturn15()', 303 'increaseAndReturn15': 'increaseAndReturn15()',
260 'increaseAndThrow42': 'increaseAndThrow42()', 304 'increaseAndThrow42': 'increaseAndThrow42()',
261 } 305 }
262 elif alternativeFn1: 306 elif alternativeFn1:
263 fragments = { 307 fragments = {
264 'increaseAndReturn15': 'returnOrThrow(true)', 308 'increaseAndReturn15': 'returnOrThrow(true)',
265 'increaseAndThrow42': 'returnOrThrow(false)', 309 'increaseAndThrow42': 'returnOrThrow(false)',
266 } 310 }
267 elif alternativeFn2: 311 elif alternativeFn2:
268 fragments = { 312 fragments = {
313 'increaseAndReturn15': 'increaseAndReturn15_noopt_outer()',
314 'increaseAndThrow42': 'increaseAndThrow42_noopt_outer()',
315 }
316 elif alternativeFn3:
317 fragments = {
269 'increaseAndReturn15': 'invertFunctionCall(increaseAndThrow42)', 318 'increaseAndReturn15': 'invertFunctionCall(increaseAndThrow42)',
270 'increaseAndThrow42': 'invertFunctionCall(increaseAndReturn15)', 319 'increaseAndThrow42': 'invertFunctionCall(increaseAndReturn15)',
271 } 320 }
272 elif alternativeFn3: 321 elif alternativeFn4:
273 fragments = { 322 fragments = {
274 'increaseAndReturn15': '(new increaseAndStore15Constructor()).x', 323 'increaseAndReturn15': '(new increaseAndStore15Constructor()).x',
275 'increaseAndThrow42': '(new increaseAndThrow42Constructor()).x', 324 'increaseAndThrow42': '(new increaseAndThrow42Constructor()).x',
276 } 325 }
277 else: 326 else:
278 assert alternativeFn4 327 assert alternativeFn5
279 fragments = { 328 fragments = {
280 'increaseAndReturn15': 'magic.prop /* returns 15 */', 329 'increaseAndReturn15': 'magic.prop /* returns 15 */',
281 'increaseAndThrow42': '(magic.prop = 37 /* throws 42 */)', 330 'increaseAndThrow42': '(magic.prop = 37 /* throws 42 */)',
282 } 331 }
283 332
284 # As we print code, we also maintain what the result should be. Variable 333 # As we print code, we also maintain what the result should be. Variable
285 # {result} can be one of three things: 334 # {result} can be one of three things:
286 # 335 #
287 # - None, indicating returning JS null 336 # - None, indicating returning JS null
288 # - ("return", n) with n an integer 337 # - ("return", n) with n an integer
289 # - ("throw", n), with n an integer 338 # - ("throw", n), with n an integer
290 339
291 result = None 340 result = None
292 # We also maintain what the counter should be at the end. 341 # We also maintain what the counter should be at the end.
293 # The counter is reset just before f is called. 342 # The counter is reset just before f is called.
294 counter = 0 343 counter = 0
295 344
296 write( " f = function {} () {{".format(fnname(flags))) 345 write( " f = function {} () {{".format(fnname(flags)))
297 write( " var local = 3;") 346 write( " var local = 888;")
298 write( " deopt = {};".format("true" if deopt else "false")) 347 write( " deopt = {};".format("true" if deopt else "false"))
299 local = 3 348 local = 888
300 write( " try {") 349 write( " try {")
301 write( " counter++;") 350 write( " counter++;")
302 counter += 1 351 counter += 1
303 resultTo = "local +=" if tryResultToLocal else "return" 352 resultTo = "local +=" if tryResultToLocal else "return"
304 if tryReturns and not (tryThrows and not tryFirstReturns): 353 if tryReturns and not (tryThrows and not tryFirstReturns):
305 write( " {} {increaseAndReturn15};".format(resultTo, **fragments)) 354 write( " {} 4 + {increaseAndReturn15};".format(resultTo, **fragments))
306 if result == None: 355 if result == None:
307 counter += 1 356 counter += 1
308 if tryResultToLocal: 357 if tryResultToLocal:
309 local += 15 358 local += 19
310 else: 359 else:
311 result = ("return", 15) 360 result = ("return", 19)
312 if tryThrows: 361 if tryThrows:
313 write( " {} {increaseAndThrow42};".format(resultTo, **fragments)) 362 write( " {} 4 + {increaseAndThrow42};".format(resultTo, **fragments))
314 if result == None: 363 if result == None:
315 counter += 1 364 counter += 1
316 result = ("throw", 42) 365 result = ("throw", 42)
317 if tryReturns and tryThrows and not tryFirstReturns: 366 if tryReturns and tryThrows and not tryFirstReturns:
318 write( " {} {increaseAndReturn15};".format(resultTo, **fragments)) 367 write( " {} 4 + {increaseAndReturn15};".format(resultTo, **fragments))
319 if result == None: 368 if result == None:
320 counter += 1 369 counter += 1
321 if tryResultToLocal: 370 if tryResultToLocal:
322 local += 15 371 local += 19
323 else: 372 else:
324 result = ("return", 15) 373 result = ("return", 19)
325 write( " counter++;") 374 write( " counter++;")
326 if result == None: 375 if result == None:
327 counter += 1 376 counter += 1
328 377
329 if doCatch: 378 if doCatch:
330 write( " } catch (ex) {") 379 write( " } catch (ex) {")
331 write( " counter++;") 380 write( " counter++;")
332 if isinstance(result, tuple) and result[0] == 'throw': 381 if isinstance(result, tuple) and result[0] == 'throw':
333 counter += 1 382 counter += 1
334 if catchThrows: 383 if catchThrows:
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 489
441 def write_shard_footer(): 490 def write_shard_footer():
442 write("}") 491 write("}")
443 write("%NeverOptimizeFunction(runThisShard);") 492 write("%NeverOptimizeFunction(runThisShard);")
444 write("") 493 write("")
445 write("// {} tests in this shard.".format(NUM_TESTS_IN_SHARD)) 494 write("// {} tests in this shard.".format(NUM_TESTS_IN_SHARD))
446 write("// {} tests up to here.".format(NUM_TESTS_PRINTED)) 495 write("// {} tests up to here.".format(NUM_TESTS_PRINTED))
447 write("") 496 write("")
448 write("runThisShard();") 497 write("runThisShard();")
449 498
499 FLAGLETTERS="54321trflcrltfrtld"
450 500
451 flagtuple = namedtuple('flagtuple', ( 501 flagtuple = namedtuple('flagtuple', (
502 "alternativeFn5",
452 "alternativeFn4", 503 "alternativeFn4",
453 "alternativeFn3", 504 "alternativeFn3",
454 "alternativeFn2", 505 "alternativeFn2",
455 "alternativeFn1", 506 "alternativeFn1",
456 "tryThrows", 507 "tryThrows",
457 "tryReturns", 508 "tryReturns",
458 "tryFirstReturns", 509 "tryFirstReturns",
459 "tryResultToLocal", 510 "tryResultToLocal",
460 "doCatch", 511 "doCatch",
461 "catchReturns", 512 "catchReturns",
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 print("") 552 print("")
502 sys.exit(1) 553 sys.exit(1)
503 554
504 rotateshard() 555 rotateshard()
505 556
506 for flags in allFlagCombinations: 557 for flags in allFlagCombinations:
507 printtest(flags) 558 printtest(flags)
508 rotateshard() 559 rotateshard()
509 560
510 finishshard() 561 finishshard()
562
563 if MODE == 'shard':
564 print("Total: {} tests.".format(NUM_TESTS_PRINTED))
OLDNEW
« test/mjsunit/compiler/inline-exception-1.js ('K') | « test/mjsunit/compiler/inline-exception-2.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698