From 7dbf08ae1cef81ff5caa95610403a3a16bb978e2 Mon Sep 17 00:00:00 2001 From: pyos Date: Thu, 27 May 2021 16:03:18 +0200 Subject: [PATCH] JVM: move loadCompiledInlineFunction out of InlineCodegen --- .../DelegatedPropertiesCodegenHelper.kt | 4 +- .../kotlin/codegen/inline/InlineCodegen.kt | 47 ------------------- .../inline/PsiSourceCompilerForInline.kt | 2 +- .../codegen/inline/SourceCompilerForInline.kt | 46 ++++++++++++++++++ .../jvm/codegen/IrSourceCompilerForInline.kt | 2 +- 5 files changed, 50 insertions(+), 51 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DelegatedPropertiesCodegenHelper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DelegatedPropertiesCodegenHelper.kt index 25d4be238ac..c7b89491154 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DelegatedPropertiesCodegenHelper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DelegatedPropertiesCodegenHelper.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.codegen import org.jetbrains.kotlin.codegen.binding.CodegenBinding -import org.jetbrains.kotlin.codegen.inline.InlineCodegen +import org.jetbrains.kotlin.codegen.inline.loadCompiledInlineFunction import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper @@ -74,7 +74,7 @@ class DelegatedPropertiesCodegenHelper(private val state: GenerationState) { val containerId = KotlinTypeMapper.getContainingClassesForDeserializedCallable(calleeDescriptor).implClassId val asmMethod = state.typeMapper.mapAsmMethod(calleeDescriptor) val isMangled = requiresFunctionNameManglingForReturnType(calleeDescriptor) - val methodNode = InlineCodegen.loadCompiledInlineFunction(containerId, asmMethod, calleeDescriptor.isSuspend, isMangled, state).node + val methodNode = loadCompiledInlineFunction(containerId, asmMethod, calleeDescriptor.isSuspend, isMangled, state).node return isMetadataParameterUsedInCompiledMethodBody(metadataParameterIndex, methodNode) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 8e074a24212..21a32645c16 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -9,13 +9,11 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive import org.jetbrains.kotlin.codegen.context.ClosureContext -import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.Position import org.jetbrains.kotlin.incremental.components.ScopeKind -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -27,7 +25,6 @@ import org.jetbrains.kotlin.types.model.TypeParameterMarker import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type -import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.tree.* import kotlin.math.max @@ -424,50 +421,6 @@ abstract class InlineCodegen( } companion object { - fun loadCompiledInlineFunction( - containerId: ClassId, - asmMethod: Method, - isSuspend: Boolean, - isMangled: Boolean, - state: GenerationState - ): SMAPAndMethodNode { - val containerType = AsmUtil.asmTypeByClassId(containerId) - val bytes = state.inlineCache.classBytes.getOrPut(containerId) { - findVirtualFile(state, containerId)?.contentsToByteArray() - ?: throw IllegalStateException("Couldn't find declaration file for $containerId") - } - val resultInCache = state.inlineCache.methodNodeById.getOrPut(MethodId(containerType.descriptor, asmMethod)) { - getMethodNode(containerType, bytes, asmMethod.name, asmMethod.descriptor, isSuspend, isMangled) - } - return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP) - } - - private fun getMethodNode( - owner: Type, - bytes: ByteArray, - name: String, - descriptor: String, - isSuspend: Boolean, - isMangled: Boolean - ): SMAPAndMethodNode { - getMethodNode(owner, bytes, name, descriptor, isSuspend)?.let { return it } - if (isMangled) { - // Compatibility with old inline class ABI versions. - val dashIndex = name.indexOf('-') - val nameWithoutManglingSuffix = if (dashIndex > 0) name.substring(0, dashIndex) else name - if (nameWithoutManglingSuffix != name) { - getMethodNode(owner, bytes, nameWithoutManglingSuffix, descriptor, isSuspend)?.let { return it } - } - getMethodNode(owner, bytes, "$nameWithoutManglingSuffix-impl", descriptor, isSuspend)?.let { return it } - } - throw IllegalStateException("couldn't find inline method $owner.$name$descriptor") - } - - // If an `inline suspend fun` has a state machine, it should have a `$$forInline` version without one. - private fun getMethodNode(owner: Type, bytes: ByteArray, name: String, descriptor: String, isSuspend: Boolean) = - (if (isSuspend) getMethodNode(bytes, name + FOR_INLINE_SUFFIX, descriptor, owner) else null) - ?: getMethodNode(bytes, name, descriptor, owner) - private fun StackValue.isCapturedInlineParameter(): Boolean { val field = if (this is StackValue.FieldForSharedVar) receiver else this return field is StackValue.Field && field.descriptor is ParameterDescriptor && diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt index cdb75fabdf6..ac2cde8912f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt @@ -247,7 +247,7 @@ class PsiSourceCompilerForInline( if (directMember is DescriptorWithContainerSource) { val containerId = KotlinTypeMapper.getContainingClassesForDeserializedCallable(directMember).implClassId val isMangled = requiresFunctionNameManglingForReturnType(functionDescriptor) - return InlineCodegen.loadCompiledInlineFunction(containerId, asmMethod, functionDescriptor.isSuspend, isMangled, state) + return loadCompiledInlineFunction(containerId, asmMethod, functionDescriptor.isSuspend, isMangled, state) } val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt index 28bef48f1a8..96947988555 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt @@ -6,8 +6,10 @@ package org.jetbrains.kotlin.codegen.inline import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.BaseExpressionCodegen import org.jetbrains.kotlin.codegen.OwnerKind +import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -61,3 +63,47 @@ interface SourceCompilerForInline { fun reportSuspensionPointInsideMonitor(stackTraceElement: String) } + +fun loadCompiledInlineFunction( + containerId: ClassId, + asmMethod: Method, + isSuspend: Boolean, + isMangled: Boolean, + state: GenerationState +): SMAPAndMethodNode { + val containerType = AsmUtil.asmTypeByClassId(containerId) + val bytes = state.inlineCache.classBytes.getOrPut(containerId) { + findVirtualFile(state, containerId)?.contentsToByteArray() + ?: throw IllegalStateException("Couldn't find declaration file for $containerId") + } + val resultInCache = state.inlineCache.methodNodeById.getOrPut(MethodId(containerType.descriptor, asmMethod)) { + getMethodNode(containerType, bytes, asmMethod.name, asmMethod.descriptor, isSuspend, isMangled) + } + return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP) +} + +private fun getMethodNode( + owner: Type, + bytes: ByteArray, + name: String, + descriptor: String, + isSuspend: Boolean, + isMangled: Boolean +): SMAPAndMethodNode { + getMethodNode(owner, bytes, name, descriptor, isSuspend)?.let { return it } + if (isMangled) { + // Compatibility with old inline class ABI versions. + val dashIndex = name.indexOf('-') + val nameWithoutManglingSuffix = if (dashIndex > 0) name.substring(0, dashIndex) else name + if (nameWithoutManglingSuffix != name) { + getMethodNode(owner, bytes, nameWithoutManglingSuffix, descriptor, isSuspend)?.let { return it } + } + getMethodNode(owner, bytes, "$nameWithoutManglingSuffix-impl", descriptor, isSuspend)?.let { return it } + } + throw IllegalStateException("couldn't find inline method $owner.$name$descriptor") +} + +// If an `inline suspend fun` has a state machine, it should have a `$$forInline` version without one. +private fun getMethodNode(owner: Type, bytes: ByteArray, name: String, descriptor: String, isSuspend: Boolean) = + (if (isSuspend) getMethodNode(bytes, name + FOR_INLINE_SUFFIX, descriptor, owner) else null) + ?: getMethodNode(bytes, name, descriptor, owner) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt index 3c99520b3f0..ced3015c0e4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt @@ -106,7 +106,7 @@ class IrSourceCompilerForInline( override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode = callee.parentClassId?.let { containerId -> - InlineCodegen.loadCompiledInlineFunction(containerId, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state) + loadCompiledInlineFunction(containerId, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state) } ?: ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee) override fun hasFinallyBlocks() = data.hasFinallyBlocks()