JVM_IR: Do not generate null checks for suspend function views.

The arguments are null whenever the suspend function is resumed
and takes its state from the continuation parameter.
This commit is contained in:
Mads Ager
2019-10-25 12:19:32 +02:00
committed by Ilmir Usmanov
parent 03c7f4bf00
commit 88dd8f663c
4 changed files with 16 additions and 9 deletions
@@ -44,5 +44,6 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object INLINE_CLASS_GENERATED_IMPL_METHOD : IrDeclarationOriginImpl("INLINE_CLASS_GENERATED_IMPL_METHOD")
object GENERATED_ASSERTION_ENABLED_FIELD : IrDeclarationOriginImpl("GENERATED_ASSERTION_ENABLED_FIELD", isSynthetic = true)
object GENERATED_MAIN_FOR_PARAMETERLESS_MAIN_METHOD : IrDeclarationOriginImpl("GENERATED_MAIN_FOR_PARAMETERLESS_MAIN_METHOD", isSynthetic = true)
object SUSPEND_FUNCTION_VIEW : IrDeclarationOriginImpl("SUSPEND_FUNCTION_VIEW")
object SUSPEND_IMPL_STATIC_FUNCTION : IrDeclarationOriginImpl("SUSPEND_IMPL_STATIC_FUNCTION", isSynthetic = true)
}
@@ -125,12 +125,10 @@ internal fun IrFunction.shouldNotContainSuspendMarkers(context: JvmBackendContex
// Transform `suspend fun foo(params): RetType` into `fun foo(params, $completion: Continuation<RetType>): Any?`
// the result is called 'view', just to be consistent with old backend.
internal fun IrFunction.getOrCreateSuspendFunctionViewIfNeeded(context: JvmBackendContext): IrFunction {
if (!isSuspend || origin == SUSPEND_FUNCTION_VIEW) return this
if (!isSuspend || origin == JvmLoweredDeclarationOrigin.SUSPEND_FUNCTION_VIEW) return this
return if (isSuspend) context.suspendFunctionViews.getOrElse(this) { suspendFunctionView(context) } else this
}
private object SUSPEND_FUNCTION_VIEW : IrDeclarationOriginImpl("SUSPEND_FUNCTION_VIEW")
private fun IrFunction.suspendFunctionView(context: JvmBackendContext): IrFunction {
require(this.isSuspend && this is IrSimpleFunction)
val originalDescriptor = this.descriptor
@@ -146,7 +144,7 @@ private fun IrFunction.suspendFunctionView(context: JvmBackendContext): IrFuncti
else
WrappedSimpleFunctionDescriptor(sourceElement = originalDescriptor.source)
return IrFunctionImpl(
startOffset, endOffset, SUSPEND_FUNCTION_VIEW, IrSimpleFunctionSymbolImpl(descriptor),
startOffset, endOffset, JvmLoweredDeclarationOrigin.SUSPEND_FUNCTION_VIEW, IrSimpleFunctionSymbolImpl(descriptor),
name, visibility, modality, context.irBuiltIns.anyNType,
isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect
).also {
@@ -220,10 +220,19 @@ class ExpressionCodegen(
irFunction.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
irFunction.origin == JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER ||
irFunction.origin == JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE
if (!notCallableFromJava) {
irFunction.extensionReceiverParameter?.let { generateNonNullAssertion(it) }
irFunction.valueParameters.forEach(::generateNonNullAssertion)
}
if (notCallableFromJava)
return
// Do not generate non-null checks for suspend function views. When resumed the arguments
// will be null and the actual values are taken from the continuation.
val isSuspendFunctionView = irFunction.origin == JvmLoweredDeclarationOrigin.SUSPEND_FUNCTION_VIEW
if (isSuspendFunctionView)
return
irFunction.extensionReceiverParameter?.let { generateNonNullAssertion(it) }
irFunction.valueParameters.forEach(::generateNonNullAssertion)
}
private fun generateNonNullAssertion(param: IrValueParameter) {
@@ -1,7 +1,6 @@
// WITH_RUNTIME
// WITH_COROUTINES
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
import helpers.*
import kotlin.coroutines.*