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

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

Issue 2216353002: [turbofan] Also inline into try blocks. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@p5-base
Patch Set: Don't inspect control outputs if the operator is NoThrow Created 4 years, 4 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
(Empty)
1 #!/usr/bin/env python3
2
3 # Copyright 2016 the V8 project authors. All rights reserved.
Jarin 2016/08/10 12:02:52 Please replace with the short version of the copyr
bgeron 2016/08/10 14:37:27 Done.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following
12 # disclaimer in the documentation and/or other materials provided
13 # with the distribution.
14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived
16 # from this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
31 from collections import namedtuple
32 import textwrap
33
34 PREAMBLE = """
35
36 // Copyright 2016 the V8 project authors. All rights reserved.
37 // Redistribution and use in source and binary forms, with or without
38 // modification, are permitted provided that the following conditions are
39 // met:
40 //
41 // * Redistributions of source code must retain the above copyright
42 // notice, this list of conditions and the following disclaimer.
43 // * Redistributions in binary form must reproduce the above
44 // copyright notice, this list of conditions and the following
45 // disclaimer in the documentation and/or other materials provided
46 // with the distribution.
47 // * Neither the name of Google Inc. nor the names of its
48 // contributors may be used to endorse or promote products derived
49 // from this software without specific prior written permission.
50 //
51 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
52 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
53 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
54 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
55 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
56 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
57 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
61 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
63 // Flags: --allow-natives-syntax --turbo
64
65 // This test file was generated by tools/gen-inlining-tests.py .
66
67 function assertOptResultEquals(expected, f) {
68 // f();
69 // %DebugPrint(f);
70 eval("'dont optimize this function itself please, but do optimize f'");
71 %OptimizeFunctionOnNextCall(f);
72 assertEquals(expected, f());
73 }
74
75 function assertOptThrowsWith(expected, f) {
76 // f();
77 // %DebugPrint(f);
78 eval("'dont optimize this function itself please, but do optimize f'");
79 %OptimizeFunctionOnNextCall(f);
80 try {
81 var result = f();
82 fail("assertOptThrowsWith", "exception: " + expected, "result: " + result);
83 } catch (ex) {
84 assertEquals(expected, ex);
85 }
86 }
87
88 var counter = 0;
89
90 function increaseAndReturn15() {
91 counter++;
92 return 15;
93 }
94
95 function increaseAndThrow42() {
96 counter++;
97 throw 42;
98 }
99
100 function returnOrThrow(doReturn) {
101 if (doReturn) {
102 return increaseAndReturn15();
103 } else {
104 return increaseAndThrow42();
105 }
106 }
107
108 // When passed either {increaseAndReturn15} or {increaseAndThrow42}, it acts
109 // as the other one.
110 function invertFunctionCall(f) {
111 var result;
112 try {
113 result = f();
114 } catch (ex) {
115 return ex - 27;
116 }
117 throw result + 27;
118 }
119
120 """.strip()
121
122 # Assert Python 3; reboot to Python 3 if currently on Python 2
123 import sys, os
124 if sys.version_info[0] == 2:
125 sys.stderr.write("Restarting script using Python 3.\n")
126 os.execl("/usr/bin/env", "env", "python3", __file__)
Jarin 2016/08/10 12:02:52 Would it be too hard to make this work with python
bgeron 2016/08/10 14:37:27 Easier than expected! Done.
127
128 def booltuples(n):
129 """booltuples(2) yields 4 tuples: (False, False), (False, True),
130 (True, False), (True, True)."""
131
132 assert isinstance(n, int)
133 if n <= 0:
134 yield ()
135 else:
136 for initial in booltuples(n-1):
137 yield initial + (False,)
138 yield initial + (True,)
139
140 NUM_TESTS_PRINTED = 0
141
142 def printtest(flags):
143 """Print a test case. Takes a couple of boolean flags, on which the
144 printed Javascript code depends."""
145
146 assert all(isinstance(flag, bool) for flag in flags)
147
148 (
149 alternativeFn2, # use alternative #2 for returning/throwing.
150 alternativeFn1, # use alternative #1 for returning/throwing.
151 tryReturns, # in try block, call returning function
152 tryThrows, # in try block, call throwing function
153 tryFirstReturns, # in try block, returning goes before throwing
154 tryResultToLocal, # in try block, result goes to local variable
155 doCatch, # include catch block
156 catchReturns, # in catch block, return
157 catchWithLocal, # in catch block, modify or return the local variable
158 catchThrows, # in catch block, throw
159 doFinally, # include finally block
160 finallyReturns, # in finally block, return local variable
161 finallyThrows, # in finally block, throw
162 endReturnLocal, # at very end, return variable local
163 ) = flags
Jarin 2016/08/10 12:02:52 We would also like to test deoptimization. However
bgeron 2016/08/10 14:37:27 Ack. Let's look at this together when you're back.
164
165 # Some pruning
166
167 if alternativeFn1 and alternativeFn2: return
168
169 # In try, return or throw, or both.
170 if not (tryReturns or tryThrows): return
171
172 # Either doCatch or doFinally.
173 if not doCatch and not doFinally: return
174
175 # Catch flags only make sense when catching
176 if not doCatch and (catchReturns or catchWithLocal or catchThrows):
177 return
178
179 # Finally flags only make sense when finallying
180 if not doFinally and (finallyReturns or finallyThrows):
181 return
182
183 # tryFirstReturns is only relevant when both tryReturns and tryThrows are true .
184 if tryFirstReturns and not (tryReturns and tryThrows): return
185
186 # From the try and finally block, we can return or throw, but not both.
187 if catchReturns and catchThrows: return
188 if finallyReturns and finallyThrows: return
189
190 # If we use an alternative function, then we don't also need to test both
191 # tryReturns and tryThrows at the same time.
192 if (alternativeFn1 or alternativeFn2) and tryReturns and tryThrows: return
193
194 # Flag check succeeded.
195 global NUM_TESTS_PRINTED
196 NUM_TESTS_PRINTED += 1
197
198 trueFlagNames = [name for (name, value) in flags._asdict().items() if value]
199 flagsMsgLine = "// Variant flags: [{}]".format(', '.join(trueFlagNames))
200 print(textwrap.fill(flagsMsgLine, subsequent_indent='// '))
201 print()
202
203 if not alternativeFn1 and not alternativeFn2:
204 fragments = {
205 'increaseAndReturn15': 'increaseAndReturn15()',
206 'increaseAndThrow42': 'increaseAndThrow42()'
207 }
208 elif alternativeFn1:
209 fragments = {
210 'increaseAndReturn15': 'returnOrThrow(true)',
211 'increaseAndThrow42': 'returnOrThrow(false)'
212 }
213 else:
214 assert alternativeFn2
215 fragments = {
216 'increaseAndReturn15': 'invertFunctionCall(increaseAndThrow42)',
217 'increaseAndThrow42': 'invertFunctionCall(increaseAndReturn15)'
218 }
219
220 # As we print code, we also maintain what the result should be. Variable
221 # {result} can be one of three things:
222 #
223 # - None, indicating returning JS null
224 # - ("return", n) with n an integer
225 # - ("throw", n), with n an integer
226
227 result = None
228 # We also maintain what the counter should be at the end.
229 counter = 0
230
231 print( "counter = 0;")
232 print( "var f = function() {")
233 print( " var local = 3;")
234 local = 3
235 print( " try {")
236 print( " counter++;")
237 counter += 1
238 resultGoesTo = "local +=" if tryResultToLocal else "return"
239 if tryReturns and not (tryThrows and not tryFirstReturns):
240 print( " {} {increaseAndReturn15};".format(resultGoesTo, **fragments))
241 if result == None:
242 counter += 1
243 if tryResultToLocal:
244 local += 15
245 else:
246 result = ("return", 15)
247 if tryThrows:
248 print( " {} {increaseAndThrow42};".format(resultGoesTo, **fragments))
249 if result == None:
250 counter += 1
251 result = ("throw", 42)
252 if tryReturns and tryThrows and not tryFirstReturns:
253 print( " {} {increaseAndReturn15};".format(resultGoesTo, **fragments))
254 if result == None:
255 counter += 1
256 if tryResultToLocal:
257 local += 15
258 else:
259 result = ("return", 15)
260 print( " counter++;")
261 if result == None:
262 counter += 1
263
264 if doCatch:
265 print( " } catch (ex) {")
266 print( " counter++;")
267 if isinstance(result, tuple) and result[0] == 'throw':
268 counter += 1
269 if catchThrows:
270 print(" throw 2 + ex;")
271 if isinstance(result, tuple) and result[0] == "throw":
272 result = ('throw', 2 + result[1])
273 elif catchReturns and catchWithLocal:
274 print(" return 2 + local;")
275 if isinstance(result, tuple) and result[0] == "throw":
276 result = ('return', 2 + local)
277 elif catchReturns and not catchWithLocal:
278 print(" return 2 + ex;");
279 if isinstance(result, tuple) and result[0] == "throw":
280 result = ('return', 2 + result[1])
281 elif catchWithLocal:
282 print(" local += ex;");
283 if isinstance(result, tuple) and result[0] == "throw":
284 local += result[1]
285 result = None
286 counter += 1
287 else:
288 if isinstance(result, tuple) and result[0] == "throw":
289 result = None
290 counter += 1
291 print( " counter++;")
292
293 if doFinally:
294 print( " } finally {")
295 print( " counter++;")
296 counter += 1
297 if finallyThrows:
298 print(" throw 25;")
299 result = ('throw', 25)
300 elif finallyReturns:
301 print(" return 3 + local;")
302 result = ('return', 3 + local)
303 elif not finallyReturns and not finallyThrows:
304 print(" local += 2;")
305 local += 2
306 counter += 1
307 else: assert False # unreachable
308 print( " counter++;")
309
310 print( " }")
311 print( " counter++;")
312 if result == None:
313 counter += 1
314 if endReturnLocal:
315 print( " return 5 + local;")
316 if result == None:
317 result = ('return', 5 + local)
318 print( "}")
319
320 if result == None:
321 print( "assertOptResultEquals(undefined, f);")
322 else:
323 tag, value = result
324 if tag == "return":
325 print( "assertOptResultEquals({}, f);".format(value))
326 else:
327 assert tag == "throw"
328 print( "assertOptThrowsWith({}, f);".format(value))
329
330 print( "assertEquals({}, counter);".format(counter))
331 print( )
332
333
334 flagtuple = namedtuple('flagtuple', (
335 "alternativeFn2",
336 "alternativeFn1",
337 "tryReturns",
338 "tryThrows",
339 "tryFirstReturns",
340 "tryResultToLocal",
341 "doCatch",
342 "catchReturns",
343 "catchWithLocal",
344 "catchThrows",
345 "doFinally",
346 "finallyReturns",
347 "finallyThrows",
348 "endReturnLocal",
349 ))
350
351 emptyflags = flagtuple(*((False,) * len(flagtuple._fields)))
352 f1 = emptyflags._replace(tryReturns=True, doCatch=True)
353
354 # You can test function printtest with f1.
355
356 allFlagCombinations = [flagtuple(*bools) for bools in booltuples(len(flagtuple._ fields))]
357
358 if __name__ == '__main__':
359 print(PREAMBLE)
360 print()
361 for flags in allFlagCombinations:
362 printtest(flags)
363
364 print("// Total: {} tests.".format(NUM_TESTS_PRINTED))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698