Generate suspend markers for inline and crossinline parameters

if they are not inlined, but directly called.
Previously, all inline and crossinline lambda calls were treated by
codegen as if they are always going to be inlined. However, this is not
always the case.

Note, that we cannot generate these markers during codegen, since we
can inline code with no suspension points, but the whole inlined code
will become one giant suspension point. This, of course, breaks
tail-call optimization and, hence, slows down cold streams.

Because of that, we generate these markers, when we are sure, that they
are not going to be inlined. The only place, in which we know that, is
the inliner. During inlining of the inline function, we check, whether
the parameter is inline or crossinline and whether it is not an inline
lambda. If these checks pass, we generate the markers. Noinline
parameters are already covered by the codegen.
 #KT-30706 Fixed
 #KT-26925 Fixed
 #KT-26418 Fixed
This commit is contained in:
Ilmir Usmanov
2019-04-02 21:17:34 +03:00
parent eb1bfac83f
commit 2dee506022
12 changed files with 368 additions and 55 deletions
@@ -3936,6 +3936,16 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines");
}
@TestMetadata("passLambda.kt")
public void testPassLambda_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("passLambda.kt")
public void testPassLambda_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passLambda.kt", "kotlin.coroutines");
}
@TestMetadata("passParameterLambda.kt")
public void testPassParameterLambda_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/passParameterLambda.kt", "kotlin.coroutines.experimental");