Replace recursion with a loop #KT-51530 Fixed
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index def31a4..6a688a3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin +import org.jetbrains.kotlin.utils.addToStdlib.popLast import org.jetbrains.kotlin.utils.sure import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.MethodVisitor @@ -681,12 +682,22 @@ val suspensionPointEnds = suspensionPoints.associateBy { it.suspensionCallEnd } fun findSuspensionPointPredecessors(suspension: SuspensionPoint): List<SuspensionPoint> { val visited = mutableSetOf<AbstractInsnNode>() - fun dfs(current: AbstractInsnNode): List<SuspensionPoint> { - if (!visited.add(current)) return emptyList() - suspensionPointEnds[current]?.let { return listOf(it) } - return cfg.getPredecessorsIndices(current).flatMap { dfs(instructions[it]) } + val current = mutableListOf(suspension.suspensionCallBegin) + val result = mutableListOf<SuspensionPoint>() + + while (current.isNotEmpty()) { + val insn = current.popLast() + if (!visited.add(insn)) continue + + val end = suspensionPointEnds[insn] + if (end != null) { + result.add(end) + continue + } + current.addAll(cfg.getPredecessorsIndices(insn).map { instructions[it] }) } - return dfs(suspension.suspensionCallBegin) + + return result } val predSuspensionPoints = suspensionPoints.associateWith { findSuspensionPointPredecessors(it) }
diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index d24b1a3..ba0f91e 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java
@@ -10192,6 +10192,12 @@ } @Test + @TestMetadata("kt51530.kt") + public void testKt51530() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt51530.kt"); + } + + @Test @TestMetadata("kt51718.kt") public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt");
diff --git a/compiler/testData/codegen/box/coroutines/kt51530.kt b/compiler/testData/codegen/box/coroutines/kt51530.kt new file mode 100644 index 0000000..a5a108e --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/kt51530.kt
@@ -0,0 +1,215 @@ +// WITH_STDLIB +// IGNORE_BACKEND: JVM + +import kotlin.coroutines.* + +interface Flow<out T> { + suspend fun collect(collector: FlowCollector<T>) +} + +fun interface FlowCollector<in T> { + suspend fun emit(value: T) +} + +inline fun <T, R> Flow<T>.transform( + crossinline transform: suspend FlowCollector<R>.(value: T) -> Unit +): Flow<R> = object : Flow<R> { + override suspend fun collect(collector: FlowCollector<R>) { + this@transform.collect a@{ value -> + return@a collector.transform(value) + } + } +} + +public inline fun <T, R: Any> Flow<T>.mapNotNull(crossinline transform: suspend (value: T) -> R?): Flow<R> = transform { value -> + val transformed = transform(value) ?: return@transform + return@transform emit(transformed) +} + +internal fun Flow<List<Data>>.aggregate(aggregation: (List<Double>) -> Double): Flow<Data> = mapNotNull { + Data( + p1 = aggregation(it.mapNotNull { it. p1 }), + p2 = aggregation(it.mapNotNull { it. p2 }), + p3 = aggregation(it.mapNotNull { it. p3 }), + p4 = aggregation(it.mapNotNull { it. p4 }), + p5 = aggregation(it.mapNotNull { it. p5 }), + p6 = aggregation(it.mapNotNull { it. p6 }), + p7 = aggregation(it.mapNotNull { it. p7 }), + p8 = aggregation(it.mapNotNull { it. p8 }), + p9 = aggregation(it.mapNotNull { it. p9 }), + p10 = aggregation(it.mapNotNull { it. p10 }), + p11 = aggregation(it.mapNotNull { it. p11 }), + p12 = aggregation(it.mapNotNull { it. p12 }), + p13 = aggregation(it.mapNotNull { it. p13 }), + p14 = aggregation(it.mapNotNull { it. p14 }), + p15 = aggregation(it.mapNotNull { it. p15 }), + p16 = aggregation(it.mapNotNull { it. p16 }), + p17 = aggregation(it.mapNotNull { it. p17 }), + p18 = aggregation(it.mapNotNull { it. p18 }), + p19 = aggregation(it.mapNotNull { it. p19 }), + p20 = aggregation(it.mapNotNull { it. p20 }), + p21 = aggregation(it.mapNotNull { it. p21 }), + p22 = aggregation(it.mapNotNull { it. p22 }), + p23 = aggregation(it.mapNotNull { it. p23 }), + p24 = aggregation(it.mapNotNull { it. p24 }), + p25 = aggregation(it.mapNotNull { it. p25 }), + p26 = aggregation(it.mapNotNull { it. p26 }), + p27 = aggregation(it.mapNotNull { it. p27 }), + p28 = aggregation(it.mapNotNull { it. p28 }), + p29 = aggregation(it.mapNotNull { it. p29 }), + p30 = aggregation(it.mapNotNull { it. p30 }), + p31 = aggregation(it.mapNotNull { it. p31 }), + p32 = aggregation(it.mapNotNull { it. p32 }), + p33 = aggregation(it.mapNotNull { it. p33 }), + p34 = aggregation(it.mapNotNull { it. p34 }), + p35 = aggregation(it.mapNotNull { it. p35 }), + p36 = aggregation(it.mapNotNull { it. p36 }), + p37 = aggregation(it.mapNotNull { it. p37 }), + p38 = aggregation(it.mapNotNull { it. p38 }), + p39 = aggregation(it.mapNotNull { it. p39 }), + p40 = aggregation(it.mapNotNull { it. p40 }), + p41 = aggregation(it.mapNotNull { it. p41 }), + p42 = aggregation(it.mapNotNull { it. p42 }), + p43 = aggregation(it.mapNotNull { it. p43 }), + p44 = aggregation(it.mapNotNull { it. p44 }), + p45 = aggregation(it.mapNotNull { it. p45 }), + p46 = aggregation(it.mapNotNull { it. p46 }), + p47 = aggregation(it.mapNotNull { it. p47 }), + p48 = aggregation(it.mapNotNull { it. p48 }), + p49 = aggregation(it.mapNotNull { it. p49 }), + p50 = aggregation(it.mapNotNull { it. p50 }), + p51 = aggregation(it.mapNotNull { it. p51 }), + p52 = aggregation(it.mapNotNull { it. p52 }), + p53 = aggregation(it.mapNotNull { it. p53 }), + p54 = aggregation(it.mapNotNull { it. p54 }), + p55 = aggregation(it.mapNotNull { it. p55 }), + p56 = aggregation(it.mapNotNull { it. p56 }), + p57 = aggregation(it.mapNotNull { it. p57 }), + p58 = aggregation(it.mapNotNull { it. p58 }), + p59 = aggregation(it.mapNotNull { it. p59 }), + p60 = aggregation(it.mapNotNull { it. p60 }), + p61 = aggregation(it.mapNotNull { it. p61 }), + p62 = aggregation(it.mapNotNull { it. p62 }), + p63 = aggregation(it.mapNotNull { it. p63 }), + p64 = aggregation(it.mapNotNull { it. p64 }), + p65 = aggregation(it.mapNotNull { it. p65 }), + p66 = aggregation(it.mapNotNull { it. p66 }), + p67 = aggregation(it.mapNotNull { it. p67 }), + p68 = aggregation(it.mapNotNull { it. p68 }), + p69 = aggregation(it.mapNotNull { it. p69 }), + p70 = aggregation(it.mapNotNull { it. p70 }), + p71 = aggregation(it.mapNotNull { it. p71 }), + p72 = aggregation(it.mapNotNull { it. p72 }), + p73 = aggregation(it.mapNotNull { it. p73 }), + p74 = aggregation(it.mapNotNull { it. p74 }), + p75 = aggregation(it.mapNotNull { it. p75 }), + p76 = aggregation(it.mapNotNull { it. p76 }), + p77 = aggregation(it.mapNotNull { it. p77 }), + p78 = aggregation(it.mapNotNull { it. p78 }), + p79 = aggregation(it.mapNotNull { it. p79 }), + p80 = aggregation(it.mapNotNull { it. p80 }), + p81 = aggregation(it.mapNotNull { it. p81 }), + p82 = aggregation(it.mapNotNull { it. p82 }), + p83 = aggregation(it.mapNotNull { it. p83 }), + p84 = aggregation(it.mapNotNull { it. p84 }), + p85 = aggregation(it.mapNotNull { it. p85 }), + p86 = aggregation(it.mapNotNull { it. p86 }), + ) +} + +data class Data( + val p1 : Double?, + val p2 : Double?, + val p3 : Double?, + val p4 : Double?, + val p5 : Double?, + val p6 : Double?, + val p7 : Double?, + val p8 : Double?, + val p9 : Double?, + val p10 : Double?, + val p11 : Double?, + val p12 : Double?, + val p13 : Double?, + val p14 : Double?, + val p15 : Double?, + val p16 : Double?, + val p17 : Double?, + val p18 : Double?, + val p19 : Double?, + val p20 : Double?, + val p21 : Double?, + val p22 : Double?, + val p23 : Double?, + val p24 : Double?, + val p25 : Double?, + val p26 : Double?, + val p27 : Double?, + val p28 : Double?, + val p29 : Double?, + val p30 : Double?, + val p31 : Double?, + val p32 : Double?, + val p33 : Double?, + val p34 : Double?, + val p35 : Double?, + val p36 : Double?, + val p37 : Double?, + val p38 : Double?, + val p39 : Double?, + val p40 : Double?, + val p41 : Double?, + val p42 : Double?, + val p43 : Double?, + val p44 : Double?, + val p45 : Double?, + val p46 : Double?, + val p47 : Double?, + val p48 : Double?, + val p49 : Double?, + val p50 : Double?, + val p51 : Double?, + val p52 : Double?, + val p53 : Double?, + val p54 : Double?, + val p55 : Double?, + val p56 : Double?, + val p57 : Double?, + val p58 : Double?, + val p59 : Double?, + val p60 : Double?, + val p61 : Double?, + val p62 : Double?, + val p63 : Double?, + val p64 : Double?, + val p65 : Double?, + val p66 : Double?, + val p67 : Double?, + val p68 : Double?, + val p69 : Double?, + val p70 : Double?, + val p71 : Double?, + val p72 : Double?, + val p73 : Double?, + val p74 : Double?, + val p75 : Double?, + val p76 : Double?, + val p77 : Double?, + val p78 : Double?, + val p79 : Double?, + val p80 : Double?, + val p81 : Double?, + val p82 : Double?, + val p83 : Double?, + val p84 : Double?, + val p85 : Double?, + val p86 : Double?, +) + +fun box(): String { + object : Flow<List<Data>> { + override suspend fun collect(collector: FlowCollector<List<Data>>) { + } + }.aggregate { 1.0 } + return "OK" +} \ No newline at end of file
diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 7fb0fb73..2fc0616 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java
@@ -10066,6 +10066,12 @@ } @Test + @TestMetadata("kt51530.kt") + public void testKt51530() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt51530.kt"); + } + + @Test @TestMetadata("kt51718.kt") public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt");
diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index d99732b..913da75 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java
@@ -10192,6 +10192,12 @@ } @Test + @TestMetadata("kt51530.kt") + public void testKt51530() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt51530.kt"); + } + + @Test @TestMetadata("kt51718.kt") public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt");
diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index e0fa036..780905be 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
@@ -7551,6 +7551,11 @@ runTest("compiler/testData/codegen/box/coroutines/kt49168.kt"); } + @TestMetadata("kt51530.kt") + public void ignoreKt51530() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt51530.kt"); + } + @TestMetadata("suspendFunctionAsSupertype.kt") public void ignoreSuspendFunctionAsSupertype() throws Exception { runTest("compiler/testData/codegen/box/coroutines/suspendFunctionAsSupertype.kt");
diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index c7a2e09..35befa3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java
@@ -7158,6 +7158,12 @@ } @Test + @TestMetadata("kt51530.kt") + public void testKt51530() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt51530.kt"); + } + + @Test @TestMetadata("kt51718.kt") public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt");
diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index 074fadd..52efc10 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java
@@ -7200,6 +7200,12 @@ } @Test + @TestMetadata("kt51530.kt") + public void testKt51530() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt51530.kt"); + } + + @Test @TestMetadata("kt51718.kt") public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt");
diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 7376085..c5fb8d5 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
@@ -6241,6 +6241,11 @@ runTest("compiler/testData/codegen/box/coroutines/kt49168.kt"); } + @TestMetadata("kt51530.kt") + public void testKt51530() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt51530.kt"); + } + @TestMetadata("kt51718.kt") public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt");
diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index 40d8c96..ba6d7e1 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java
@@ -8042,6 +8042,12 @@ } @Test + @TestMetadata("kt51530.kt") + public void testKt51530() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt51530.kt"); + } + + @Test @TestMetadata("kt51718.kt") public void testKt51718() throws Exception { runTest("compiler/testData/codegen/box/coroutines/kt51718.kt");