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 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_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 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) 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?` // 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. // the result is called 'view', just to be consistent with old backend.
internal fun IrFunction.getOrCreateSuspendFunctionViewIfNeeded(context: JvmBackendContext): IrFunction { 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 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 { private fun IrFunction.suspendFunctionView(context: JvmBackendContext): IrFunction {
require(this.isSuspend && this is IrSimpleFunction) require(this.isSuspend && this is IrSimpleFunction)
val originalDescriptor = this.descriptor val originalDescriptor = this.descriptor
@@ -146,7 +144,7 @@ private fun IrFunction.suspendFunctionView(context: JvmBackendContext): IrFuncti
else else
WrappedSimpleFunctionDescriptor(sourceElement = originalDescriptor.source) WrappedSimpleFunctionDescriptor(sourceElement = originalDescriptor.source)
return IrFunctionImpl( return IrFunctionImpl(
startOffset, endOffset, SUSPEND_FUNCTION_VIEW, IrSimpleFunctionSymbolImpl(descriptor), startOffset, endOffset, JvmLoweredDeclarationOrigin.SUSPEND_FUNCTION_VIEW, IrSimpleFunctionSymbolImpl(descriptor),
name, visibility, modality, context.irBuiltIns.anyNType, name, visibility, modality, context.irBuiltIns.anyNType,
isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect
).also { ).also {
@@ -220,10 +220,19 @@ class ExpressionCodegen(
irFunction.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE || irFunction.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
irFunction.origin == JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER || irFunction.origin == JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER ||
irFunction.origin == JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE irFunction.origin == JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE
if (!notCallableFromJava) {
irFunction.extensionReceiverParameter?.let { generateNonNullAssertion(it) } if (notCallableFromJava)
irFunction.valueParameters.forEach(::generateNonNullAssertion) 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) { private fun generateNonNullAssertion(param: IrValueParameter) {
@@ -1,7 +1,6 @@
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
import helpers.* import helpers.*
import kotlin.coroutines.* import kotlin.coroutines.*