JVM: don't thread callDefault through the inliner

It's only used by the old backend, and should be given to
PsiSourceCompilerForInline by PsiInlineCodegen.
This commit is contained in:
pyos
2021-05-27 15:35:47 +02:00
committed by max-kammerer
parent 6dd598c7a7
commit 8307367f90
7 changed files with 32 additions and 50 deletions
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.inline.isInlineOnly import org.jetbrains.kotlin.resolve.inline.isInlineOnly
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.model.TypeParameterMarker import org.jetbrains.kotlin.types.model.TypeParameterMarker
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
@@ -100,13 +99,17 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
fun performInline( fun performInline(
typeArguments: List<TypeParameterMarker>?, typeArguments: List<TypeParameterMarker>?,
inlineDefaultLambdas: Boolean, inlineDefaultLambdas: Boolean,
mapDefaultSignature: Boolean,
typeSystem: TypeSystemCommonBackendContext, typeSystem: TypeSystemCommonBackendContext,
registerLineNumberAfterwards: Boolean, registerLineNumberAfterwards: Boolean,
) { ) {
var nodeAndSmap: SMAPAndMethodNode? = null var nodeAndSmap: SMAPAndMethodNode? = null
try { try {
nodeAndSmap = createInlineMethodNode(mapDefaultSignature, typeArguments, typeSystem) nodeAndSmap =
generateInlineIntrinsic(state, functionDescriptor, jvmSignature.asmMethod, typeArguments, typeSystem)?.let {
SMAPAndMethodNode(it, SMAP(listOf()))
} ?: sourceCompiler.compileInlineFunction(jvmSignature).apply {
node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
}
endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards) endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards)
} catch (e: CompilationException) { } catch (e: CompilationException) {
throw e throw e
@@ -420,26 +423,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
) )
} }
private fun createInlineMethodNode(
callDefault: Boolean,
typeArguments: List<TypeParameterMarker>?,
typeSystem: TypeSystemCommonBackendContext
): SMAPAndMethodNode {
val intrinsic = generateInlineIntrinsic(state, functionDescriptor, jvmSignature.asmMethod, typeArguments, typeSystem)
if (intrinsic != null) {
return SMAPAndMethodNode(intrinsic, SMAP(listOf()))
}
sourceCompiler.inlineFunctionSignature(jvmSignature, callDefault)?.let { (containerId, asmMethod) ->
val isMangled = requiresFunctionNameManglingForReturnType(functionDescriptor)
return loadCompiledInlineFunction(containerId, asmMethod, functionDescriptor.isSuspend, isMangled, state)
}
return sourceCompiler.compileInlineFunction(jvmSignature, callDefault).apply {
node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
}
}
companion object { companion object {
internal fun loadCompiledInlineFunction( fun loadCompiledInlineFunction(
containerId: ClassId, containerId: ClassId,
asmMethod: Method, asmMethod: Method,
isSuspend: Boolean, isSuspend: Boolean,
@@ -38,7 +38,7 @@ class InlineCodegenForDefaultBody(
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) { override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
assert(!callDefault) { "inlining default stub into another default stub" } assert(!callDefault) { "inlining default stub into another default stub" }
val (node, smap) = sourceCompilerForInline.compileInlineFunction(jvmSignature, callDefault) val (node, smap) = sourceCompilerForInline.compileInlineFunction(jvmSignature)
val childSourceMapper = SourceMapCopier(sourceMapper, smap) val childSourceMapper = SourceMapCopier(sourceMapper, smap)
val argsSize = val argsSize =
@@ -64,6 +64,7 @@ class PsiInlineCodegen(
callDefault: Boolean, callDefault: Boolean,
codegen: ExpressionCodegen codegen: ExpressionCodegen
) { ) {
(sourceCompiler as PsiSourceCompilerForInline).callDefault = callDefault
assert(hiddenParameters.isEmpty()) { "putHiddenParamsIntoLocals() should be called after processHiddenParameters()" } assert(hiddenParameters.isEmpty()) { "putHiddenParamsIntoLocals() should be called after processHiddenParameters()" }
if (!state.globalInlineContext.enterIntoInlining(functionDescriptor, resolvedCall?.call?.callElement)) { if (!state.globalInlineContext.enterIntoInlining(functionDescriptor, resolvedCall?.call?.callElement)) {
generateStub(resolvedCall?.call?.callElement?.text ?: "<no source>", codegen) generateStub(resolvedCall?.call?.callElement?.text ?: "<no source>", codegen)
@@ -82,7 +83,7 @@ class PsiInlineCodegen(
} }
} }
} }
performInline(resolvedCall?.typeArguments?.keys?.toList(), callDefault, callDefault, codegen.typeSystem, registerLineNumber) performInline(resolvedCall?.typeArguments?.keys?.toList(), callDefault, codegen.typeSystem, registerLineNumber)
} finally { } finally {
state.globalInlineContext.exitFromInlining() state.globalInlineContext.exitFromInlining()
} }
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.isReleaseCoroutines import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.KotlinLookupLocation import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -25,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
import org.jetbrains.kotlin.resolve.isInlineClass import org.jetbrains.kotlin.resolve.isInlineClass
import org.jetbrains.kotlin.resolve.jvm.annotations.isCallableMemberCompiledToJvmDefault import org.jetbrains.kotlin.resolve.jvm.annotations.isCallableMemberCompiledToJvmDefault
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.expressions.LabelResolver import org.jetbrains.kotlin.types.expressions.LabelResolver
@@ -224,13 +224,9 @@ class PsiSourceCompilerForInline(
return (directMember as? ImportedFromObjectCallableDescriptor<*>)?.callableFromObject ?: directMember return (directMember as? ImportedFromObjectCallableDescriptor<*>)?.callableFromObject ?: directMember
} }
override fun inlineFunctionSignature(jvmSignature: JvmMethodSignature, callDefault: Boolean): Pair<ClassId, Method>? { internal var callDefault: Boolean = false
val directMember = getDirectMemberAndCallableFromObject() as? DescriptorWithContainerSource
?: return null private fun mapDefault(): Method {
val containerId = KotlinTypeMapper.getContainingClassesForDeserializedCallable(directMember).implClassId
if (!callDefault) {
return containerId to jvmSignature.asmMethod
}
// This is all available in the `Callable` passed to `PsiInlineCodegen.genCallInner`, but it's not forwarded through the inliner... // This is all available in the `Callable` passed to `PsiInlineCodegen.genCallInner`, but it's not forwarded through the inliner...
var result = state.typeMapper.mapDefaultMethod(functionDescriptor, contextKind) var result = state.typeMapper.mapDefaultMethod(functionDescriptor, contextKind)
if (result.name.contains("-") && if (result.name.contains("-") &&
@@ -241,10 +237,19 @@ class PsiSourceCompilerForInline(
result = state.typeMapper.mapDefaultMethod(functionDescriptor, contextKind) result = state.typeMapper.mapDefaultMethod(functionDescriptor, contextKind)
state.typeMapper.useOldManglingRulesForFunctionAcceptingInlineClass = false state.typeMapper.useOldManglingRulesForFunctionAcceptingInlineClass = false
} }
return containerId to result return result
} }
override fun compileInlineFunction(jvmSignature: JvmMethodSignature, callDefault: Boolean): SMAPAndMethodNode { override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode {
val asmMethod = if (callDefault) mapDefault() else jvmSignature.asmMethod
val directMember = getDirectMemberAndCallableFromObject()
if (directMember is DescriptorWithContainerSource) {
val containerId = KotlinTypeMapper.getContainingClassesForDeserializedCallable(directMember).implClassId
val isMangled = requiresFunctionNameManglingForReturnType(functionDescriptor)
return InlineCodegen.loadCompiledInlineFunction(containerId, asmMethod, functionDescriptor.isSuspend, isMangled, state)
}
val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)
if (!(element is KtNamedFunction || element is KtPropertyAccessor)) { if (!(element is KtNamedFunction || element is KtPropertyAccessor)) {
@@ -252,10 +257,6 @@ class PsiSourceCompilerForInline(
} }
val inliningFunction = element as KtDeclarationWithBody? val inliningFunction = element as KtDeclarationWithBody?
val asmMethod = if (callDefault)
state.typeMapper.mapDefaultMethod(functionDescriptor, contextKind)
else
jvmSignature.asmMethod
val node = MethodNode( val node = MethodNode(
Opcodes.API_VERSION, Opcodes.API_VERSION,
DescriptorAsmUtil.getMethodAsmFlags(functionDescriptor, context.contextKind, state) or DescriptorAsmUtil.getMethodAsmFlags(functionDescriptor, context.contextKind, state) or
@@ -38,9 +38,7 @@ interface SourceCompilerForInline {
fun generateLambdaBody(lambdaInfo: ExpressionLambda, reifiedTypeParameters: ReifiedTypeParametersUsages): SMAPAndMethodNode fun generateLambdaBody(lambdaInfo: ExpressionLambda, reifiedTypeParameters: ReifiedTypeParametersUsages): SMAPAndMethodNode
fun inlineFunctionSignature(jvmSignature: JvmMethodSignature, callDefault: Boolean): Pair<ClassId, Method>? fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode
fun compileInlineFunction(jvmSignature: JvmMethodSignature, callDefault: Boolean): SMAPAndMethodNode
fun hasFinallyBlocks(): Boolean fun hasFinallyBlocks(): Boolean
@@ -129,8 +129,7 @@ class IrInlineCodegen(
performInline( performInline(
expression.symbol.owner.typeParameters.map { it.symbol }, expression.symbol.owner.typeParameters.map { it.symbol },
// Always look for default lambdas to allow custom default argument handling in compiler plugins. // Always look for default lambdas to allow custom default argument handling in compiler plugins.
true, inlineDefaultLambdas = true,
false,
codegen.typeMapper.typeSystem, codegen.typeMapper.typeSystem,
registerLineNumberAfterwards = isInsideIfCondition, registerLineNumberAfterwards = isInsideIfCondition,
) )
@@ -10,6 +10,7 @@ import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledReturnType
import org.jetbrains.kotlin.codegen.BaseExpressionCodegen import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.inline.*
@@ -28,7 +29,6 @@ import org.jetbrains.kotlin.ir.expressions.IrLoop
import org.jetbrains.kotlin.ir.util.isSuspend import org.jetbrains.kotlin.ir.util.isSuspend
import org.jetbrains.kotlin.ir.util.module import org.jetbrains.kotlin.ir.util.module
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.doNotAnalyze import org.jetbrains.kotlin.psi.doNotAnalyze
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
class IrSourceCompilerForInline( class IrSourceCompilerForInline(
@@ -105,11 +104,10 @@ class IrSourceCompilerForInline(
return FunctionCodegen(lambdaInfo.function, codegen.classCodegen).generate(codegen, reifiedTypeParameters) return FunctionCodegen(lambdaInfo.function, codegen.classCodegen).generate(codegen, reifiedTypeParameters)
} }
override fun inlineFunctionSignature(jvmSignature: JvmMethodSignature, callDefault: Boolean): Pair<ClassId, Method>? = override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode =
callee.parentClassId?.let { it to jvmSignature.asmMethod } callee.parentClassId?.let { containerId ->
InlineCodegen.loadCompiledInlineFunction(containerId, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state)
override fun compileInlineFunction(jvmSignature: JvmMethodSignature, callDefault: Boolean): SMAPAndMethodNode = } ?: ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee)
ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee)
override fun hasFinallyBlocks() = data.hasFinallyBlocks() override fun hasFinallyBlocks() = data.hasFinallyBlocks()