Introduce CHECK_TAIL_CALL_OPTIMIZATION directive

This directive generates TailCallOptimizationChecker in package helpers.
The check for tail call optimization is based on coroutine stack traces
bug (feature?): when tail call optimization hits, the continuation
object is not generated. Thus, there is no debug metadata for this
suspend function. Consequently, the coroutines stack trace does not
contain stack trace element for that function.
This check is performed by TailCallOptimizationChecker.

Since this is runtime check, unlike bytecode tests, it does not require
test data adjustments on each codegen or inliner change.

Since the check is based on debug metadata, which is JVM specific, there
is not support for other backends yet.
This commit is contained in:
Ilmir Usmanov
2019-04-04 20:33:13 +03:00
parent 40441a18cc
commit 00e952ab15
49 changed files with 633 additions and 1613 deletions
@@ -4804,6 +4804,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines");
}
@TestMetadata("epam.kt")
public void testEpam_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines");
}
@TestMetadata("falseUnitCoercion.kt")
public void testFalseUnitCoercion_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/falseUnitCoercion.kt", "kotlin.coroutines");
@@ -6092,26 +6097,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true);
}
@TestMetadata("also.kt")
public void testAlso_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/also.kt", "kotlin.coroutines");
}
@TestMetadata("crossinline.kt")
public void testCrossinline_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.kt", "kotlin.coroutines");
}
@TestMetadata("epam.kt")
public void testEpam_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/epam.kt", "kotlin.coroutines");
}
@TestMetadata("inlineWithStateMachine.kt")
public void testInlineWithStateMachine_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithStateMachine.kt", "kotlin.coroutines");
}
@TestMetadata("inlineWithoutStateMachine.kt")
public void testInlineWithoutStateMachine_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine.kt", "kotlin.coroutines");
@@ -6122,25 +6112,10 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.kt", "kotlin.coroutines");
}
@TestMetadata("simple.kt")
public void testSimple_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt", "kotlin.coroutines");
}
@TestMetadata("tryCatch.kt")
public void testTryCatch_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
}
@TestMetadata("unreachable.kt")
public void testUnreachable_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unreachable.kt", "kotlin.coroutines");
}
@TestMetadata("whenUnit.kt")
public void testWhenUnit_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/whenUnit.kt", "kotlin.coroutines");
}
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
@@ -4914,6 +4914,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines");
}
@TestMetadata("epam.kt")
public void testEpam_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("epam.kt")
public void testEpam_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines");
}
@TestMetadata("falseUnitCoercion.kt")
public void testFalseUnitCoercion_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/falseUnitCoercion.kt", "kotlin.coroutines.experimental");
@@ -7087,16 +7097,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
}
@TestMetadata("also.kt")
public void testAlso_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/also.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("also.kt")
public void testAlso_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/also.kt", "kotlin.coroutines");
}
@TestMetadata("crossinline.kt")
public void testCrossinline_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.kt", "kotlin.coroutines.experimental");
@@ -7107,26 +7107,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.kt", "kotlin.coroutines");
}
@TestMetadata("epam.kt")
public void testEpam_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/epam.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("epam.kt")
public void testEpam_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/epam.kt", "kotlin.coroutines");
}
@TestMetadata("inlineWithStateMachine.kt")
public void testInlineWithStateMachine_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithStateMachine.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("inlineWithStateMachine.kt")
public void testInlineWithStateMachine_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithStateMachine.kt", "kotlin.coroutines");
}
@TestMetadata("inlineWithoutStateMachine.kt")
public void testInlineWithoutStateMachine_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine.kt", "kotlin.coroutines.experimental");
@@ -7147,16 +7127,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.kt", "kotlin.coroutines");
}
@TestMetadata("simple.kt")
public void testSimple_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("simple.kt")
public void testSimple_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt", "kotlin.coroutines");
}
@TestMetadata("tryCatch.kt")
public void testTryCatch_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines.experimental");
@@ -7166,26 +7136,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
public void testTryCatch_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
}
@TestMetadata("unreachable.kt")
public void testUnreachable_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unreachable.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("unreachable.kt")
public void testUnreachable_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unreachable.kt", "kotlin.coroutines");
}
@TestMetadata("whenUnit.kt")
public void testWhenUnit_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/whenUnit.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("whenUnit.kt")
public void testWhenUnit_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/whenUnit.kt", "kotlin.coroutines");
}
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")