Commit d90d76bd authored by bgeron's avatar bgeron Committed by Commit bot

[turbofan] Improve inline-exception tests.

- Make constants more interesting.
- Add an addition to be done after the inlined call in the try-block.
- On command line, have a bit more output.
- New alternative that deopts from unoptimized code.

BUG=
R=jarin

Review-Url: https://codereview.chromium.org/2285743002
Cr-Commit-Position: refs/heads/master@{#38974}
parent 529f4c87
This diff is collapsed.
This diff is collapsed.
...@@ -11,7 +11,7 @@ import sys ...@@ -11,7 +11,7 @@ import sys
SHARD_FILENAME_TEMPLATE = "test/mjsunit/compiler/inline-exception-{shard}.js" SHARD_FILENAME_TEMPLATE = "test/mjsunit/compiler/inline-exception-{shard}.js"
# Generates 2 files. Found by trial and error. # Generates 2 files. Found by trial and error.
SHARD_SIZE = 94 SHARD_SIZE = 97
PREAMBLE = """ PREAMBLE = """
...@@ -81,6 +81,24 @@ function increaseAndThrow42() { ...@@ -81,6 +81,24 @@ function increaseAndThrow42() {
throw 42; throw 42;
} }
function increaseAndReturn15_noopt_inner() {
if (deopt) %DeoptimizeFunction(f);
counter++;
return 15;
}
%NeverOptimizeFunction(increaseAndReturn15_noopt_inner);
function increaseAndThrow42_noopt_inner() {
if (deopt) %DeoptimizeFunction(f);
counter++;
throw 42;
}
%NeverOptimizeFunction(increaseAndThrow42_noopt_inner);
// Alternative 1
function returnOrThrow(doReturn) { function returnOrThrow(doReturn) {
if (doReturn) { if (doReturn) {
return increaseAndReturn15(); return increaseAndReturn15();
...@@ -89,6 +107,17 @@ function returnOrThrow(doReturn) { ...@@ -89,6 +107,17 @@ function returnOrThrow(doReturn) {
} }
} }
// Alternative 2
function increaseAndReturn15_calls_noopt() {
return increaseAndReturn15_noopt_inner();
}
function increaseAndThrow42_calls_noopt() {
return increaseAndThrow42_noopt_inner();
}
// Alternative 3.
// When passed either {increaseAndReturn15} or {increaseAndThrow42}, it acts // When passed either {increaseAndReturn15} or {increaseAndThrow42}, it acts
// as the other one. // as the other one.
function invertFunctionCall(f) { function invertFunctionCall(f) {
...@@ -101,6 +130,7 @@ function invertFunctionCall(f) { ...@@ -101,6 +130,7 @@ function invertFunctionCall(f) {
throw result + 27; throw result + 27;
} }
// Alternative 4: constructor
function increaseAndStore15Constructor() { function increaseAndStore15Constructor() {
if (deopt) %DeoptimizeFunction(f); if (deopt) %DeoptimizeFunction(f);
++counter; ++counter;
...@@ -114,6 +144,7 @@ function increaseAndThrow42Constructor() { ...@@ -114,6 +144,7 @@ function increaseAndThrow42Constructor() {
throw this.x; throw this.x;
} }
// Alternative 5: property
var magic = {}; var magic = {};
Object.defineProperty(magic, 'prop', { Object.defineProperty(magic, 'prop', {
get: function () { get: function () {
...@@ -131,6 +162,9 @@ Object.defineProperty(magic, 'prop', { ...@@ -131,6 +162,9 @@ Object.defineProperty(magic, 'prop', {
// Generate type feedback. // Generate type feedback.
assertEquals(15, increaseAndReturn15_calls_noopt());
assertThrowsEquals(function() { return increaseAndThrow42_noopt_inner() }, 42);
assertEquals(15, (new increaseAndStore15Constructor()).x); assertEquals(15, (new increaseAndStore15Constructor()).x);
assertThrowsEquals(function() { assertThrowsEquals(function() {
return (new increaseAndThrow42Constructor()).x; return (new increaseAndThrow42Constructor()).x;
...@@ -153,8 +187,6 @@ def booltuples(n): ...@@ -153,8 +187,6 @@ def booltuples(n):
yield initial + (False,) yield initial + (False,)
yield initial + (True,) yield initial + (True,)
FLAGLETTERS="4321trflcrltfrtld"
def fnname(flags): def fnname(flags):
assert len(FLAGLETTERS) == len(flags) assert len(FLAGLETTERS) == len(flags)
...@@ -175,10 +207,17 @@ def printtest(flags): ...@@ -175,10 +207,17 @@ def printtest(flags):
# tuples, ordered lexicographically from false to true, we get first the # tuples, ordered lexicographically from false to true, we get first the
# default, then alternative 1, then 2, etc. # default, then alternative 1, then 2, etc.
( (
alternativeFn4, # use alternative #4 for returning/throwing. alternativeFn5, # use alternative #5 for returning/throwing:
alternativeFn3, # use alternative #3 for returning/throwing. # return/throw using property
alternativeFn2, # use alternative #2 for returning/throwing. alternativeFn4, # use alternative #4 for returning/throwing:
alternativeFn1, # use alternative #1 for returning/throwing. # return/throw using constructor
alternativeFn3, # use alternative #3 for returning/throwing:
# return/throw indirectly, based on function argument
alternativeFn2, # use alternative #2 for returning/throwing:
# return/throw indirectly in unoptimized code,
# no branching
alternativeFn1, # use alternative #1 for returning/throwing:
# return/throw indirectly, based on boolean arg
tryThrows, # in try block, call throwing function tryThrows, # in try block, call throwing function
tryReturns, # in try block, call returning function tryReturns, # in try block, call returning function
tryFirstReturns, # in try block, returning goes before throwing tryFirstReturns, # in try block, returning goes before throwing
...@@ -197,7 +236,8 @@ def printtest(flags): ...@@ -197,7 +236,8 @@ def printtest(flags):
# BASIC RULES # BASIC RULES
# Only one alternative can be applied at any time. # Only one alternative can be applied at any time.
if alternativeFn1 + alternativeFn2 + alternativeFn3 + alternativeFn4 > 1: if (alternativeFn1 + alternativeFn2 + alternativeFn3 + alternativeFn4
+ alternativeFn5 > 1):
return return
# In try, return or throw, or both. # In try, return or throw, or both.
...@@ -228,8 +268,9 @@ def printtest(flags): ...@@ -228,8 +268,9 @@ def printtest(flags):
# PRUNING # PRUNING
anyAlternative = any([alternativeFn1, alternativeFn2, alternativeFn3, anyAlternative = any([alternativeFn1, alternativeFn2, alternativeFn3,
alternativeFn4]) alternativeFn4, alternativeFn5])
rareAlternative = any([alternativeFn1, alternativeFn3, alternativeFn4]) specificAlternative = any([alternativeFn2, alternativeFn3])
rareAlternative = not specificAlternative
# If try returns and throws, then don't catchWithLocal, endReturnLocal, or # If try returns and throws, then don't catchWithLocal, endReturnLocal, or
# deopt, or do any alternative. # deopt, or do any alternative.
...@@ -238,13 +279,18 @@ def printtest(flags): ...@@ -238,13 +279,18 @@ def printtest(flags):
return return
# We don't do any alternative if we do a finally. # We don't do any alternative if we do a finally.
if doFinally and anyAlternative: return if doFinally and anyAlternative: return
# We only use the local variable if we do alternative #2. # We only use the local variable if we do alternative #2 or #3.
if ((tryResultToLocal or catchWithLocal or endReturnLocal) and if ((tryResultToLocal or catchWithLocal or endReturnLocal) and
not alternativeFn2): not specificAlternative):
return return
# We don't need to test deopting into a finally. # We don't need to test deopting into a finally.
if doFinally and deopt: return if doFinally and deopt: return
# We're only interested in alternative #2 if we have endReturnLocal, no
# catchReturns, and no catchThrows, and deopt.
if (alternativeFn2 and
(not endReturnLocal or catchReturns or catchThrows or not deopt)):
return
# Flag check succeeded. # Flag check succeeded.
...@@ -265,17 +311,22 @@ def printtest(flags): ...@@ -265,17 +311,22 @@ def printtest(flags):
'increaseAndThrow42': 'returnOrThrow(false)', 'increaseAndThrow42': 'returnOrThrow(false)',
} }
elif alternativeFn2: elif alternativeFn2:
fragments = {
'increaseAndReturn15': 'increaseAndReturn15_calls_noopt()',
'increaseAndThrow42': 'increaseAndThrow42_calls_noopt()',
}
elif alternativeFn3:
fragments = { fragments = {
'increaseAndReturn15': 'invertFunctionCall(increaseAndThrow42)', 'increaseAndReturn15': 'invertFunctionCall(increaseAndThrow42)',
'increaseAndThrow42': 'invertFunctionCall(increaseAndReturn15)', 'increaseAndThrow42': 'invertFunctionCall(increaseAndReturn15)',
} }
elif alternativeFn3: elif alternativeFn4:
fragments = { fragments = {
'increaseAndReturn15': '(new increaseAndStore15Constructor()).x', 'increaseAndReturn15': '(new increaseAndStore15Constructor()).x',
'increaseAndThrow42': '(new increaseAndThrow42Constructor()).x', 'increaseAndThrow42': '(new increaseAndThrow42Constructor()).x',
} }
else: else:
assert alternativeFn4 assert alternativeFn5
fragments = { fragments = {
'increaseAndReturn15': 'magic.prop /* returns 15 */', 'increaseAndReturn15': 'magic.prop /* returns 15 */',
'increaseAndThrow42': '(magic.prop = 37 /* throws 42 */)', 'increaseAndThrow42': '(magic.prop = 37 /* throws 42 */)',
...@@ -294,34 +345,34 @@ def printtest(flags): ...@@ -294,34 +345,34 @@ def printtest(flags):
counter = 0 counter = 0
write( " f = function {} () {{".format(fnname(flags))) write( " f = function {} () {{".format(fnname(flags)))
write( " var local = 3;") write( " var local = 888;")
write( " deopt = {};".format("true" if deopt else "false")) write( " deopt = {};".format("true" if deopt else "false"))
local = 3 local = 888
write( " try {") write( " try {")
write( " counter++;") write( " counter++;")
counter += 1 counter += 1
resultTo = "local +=" if tryResultToLocal else "return" resultTo = "local +=" if tryResultToLocal else "return"
if tryReturns and not (tryThrows and not tryFirstReturns): if tryReturns and not (tryThrows and not tryFirstReturns):
write( " {} {increaseAndReturn15};".format(resultTo, **fragments)) write( " {} 4 + {increaseAndReturn15};".format(resultTo, **fragments))
if result == None: if result == None:
counter += 1 counter += 1
if tryResultToLocal: if tryResultToLocal:
local += 15 local += 19
else: else:
result = ("return", 15) result = ("return", 19)
if tryThrows: if tryThrows:
write( " {} {increaseAndThrow42};".format(resultTo, **fragments)) write( " {} 4 + {increaseAndThrow42};".format(resultTo, **fragments))
if result == None: if result == None:
counter += 1 counter += 1
result = ("throw", 42) result = ("throw", 42)
if tryReturns and tryThrows and not tryFirstReturns: if tryReturns and tryThrows and not tryFirstReturns:
write( " {} {increaseAndReturn15};".format(resultTo, **fragments)) write( " {} 4 + {increaseAndReturn15};".format(resultTo, **fragments))
if result == None: if result == None:
counter += 1 counter += 1
if tryResultToLocal: if tryResultToLocal:
local += 15 local += 19
else: else:
result = ("return", 15) result = ("return", 19)
write( " counter++;") write( " counter++;")
if result == None: if result == None:
counter += 1 counter += 1
...@@ -447,8 +498,10 @@ def write_shard_footer(): ...@@ -447,8 +498,10 @@ def write_shard_footer():
write("") write("")
write("runThisShard();") write("runThisShard();")
FLAGLETTERS="54321trflcrltfrtld"
flagtuple = namedtuple('flagtuple', ( flagtuple = namedtuple('flagtuple', (
"alternativeFn5",
"alternativeFn4", "alternativeFn4",
"alternativeFn3", "alternativeFn3",
"alternativeFn2", "alternativeFn2",
...@@ -508,3 +561,6 @@ if __name__ == '__main__': ...@@ -508,3 +561,6 @@ if __name__ == '__main__':
rotateshard() rotateshard()
finishshard() finishshard()
if MODE == 'shard':
print("Total: {} tests.".format(NUM_TESTS_PRINTED))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment