Skip to content

[native-image] Classes with loops inside Kotlin coroutines fail to generate native code #366

@rhencke

Description

@rhencke

Consider the following Kotlin code:

import kotlin.coroutines.experimental.buildIterator

fun main(args: Array<String>) {
    val iter = buildIterator {
        for (i in 1..10) {
            yield("hello")
        }
    }
    for (i in iter) {
        println(i)
    }
}

Compile it with the Kotlin compiler (kotlin-compiler-1.2.40.zip). (Assume the zip is extracted to a directory represented by $KOTLIN_HOME)

$KOTLIN_HOME/bin/kotlinc-jvm -Xcoroutines=enable Main.kt
native-image -cp .:$KOTLIN_HOME/lib/kotlin-runtime.jar MainKt

This will fail to generate a native image, showing the following error:

Build on Server(pid: 21549, port: 26682)
   classlist:     244.44 ms
       (cap):   1,900.67 ms
       setup:   2,409.13 ms
    analysis:   3,028.97 ms
error: Non-reducible loop
Detailed message:
Error: Non-reducible loop
Call path from entry point to MainKt$main$iter$1.doResume(Object, Throwable): 
        at MainKt$main$iter$1.doResume(Main.kt)
        at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:54)
        at kotlin.coroutines.experimental.SequenceBuilderIterator.hasNext(SequenceBuilder.kt:129)
        at MainKt.main(Main.kt:9)
        at com.oracle.svm.reflect.proxies.Proxy_9_MainKt_main.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:199)
        at Lcom/oracle/svm/core/code/CEntryPointCallStubs;.com_002eoracle_002esvm_002ecore_002eJavaMainWrapper_002erun_0028int_002corg_002egraalvm_002enativeimage_002ec_002etype_002eCCharPointerPointer_0029(generated:0)
Original exception that caused the problem: org.graalvm.compiler.core.common.PermanentBailoutException: Non-reducible loop
        at org.graalvm.compiler.java.BciBlockMapping.computeBlockOrder(BciBlockMapping.java:852)
        at org.graalvm.compiler.java.BciBlockMapping.build(BciBlockMapping.java:514)
        at org.graalvm.compiler.java.BciBlockMapping.create(BciBlockMapping.java:1079)
        at org.graalvm.compiler.java.BytecodeParser.build(BytecodeParser.java:796)
        at org.graalvm.compiler.java.BytecodeParser.buildRootMethod(BytecodeParser.java:774)
        at org.graalvm.compiler.java.GraphBuilderPhase$Instance.run(GraphBuilderPhase.java:93)
        at org.graalvm.compiler.phases.Phase.run(Phase.java:47)
        at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:195)
        at org.graalvm.compiler.phases.Phase.apply(Phase.java:40)
        at org.graalvm.compiler.phases.Phase.apply(Phase.java:36)
        at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:195)
        at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:319)
        at com.oracle.graal.pointsto.flow.MethodTypeFlow.doParse(MethodTypeFlow.java:308)
        at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureParsed(MethodTypeFlow.java:298)
        at com.oracle.graal.pointsto.flow.MethodTypeFlow.addContext(MethodTypeFlow.java:105)
        at com.oracle.graal.pointsto.DefaultAnalysisPolicy$DefaultVirtualInvokeTypeFlow.onObservedUpdate(DefaultAnalysisPolicy.java:184)
        at com.oracle.graal.pointsto.flow.TypeFlow.notifyObservers(TypeFlow.java:345)
        at com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:387)
        at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:498)
        at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:172)
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Error: Processing image build request failed

If you adjust the sample, and comment out the loop within the coroutine as follows, the code successfully generates a working native image:

import kotlin.coroutines.experimental.buildIterator

fun main(args: Array<String>) {
    val iter = buildIterator {
        // for (i in 1..10) {
            yield("hello")
        // }
    }
    for (i in iter) {
        println(i)
    }
}

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions