From aa47191de4de79725ba03717e52b0df2b3433b80 Mon Sep 17 00:00:00 2001 From: pyos Date: Tue, 15 Jun 2021 19:03:59 +0200 Subject: [PATCH] JVM: hide ExpressionCodegen in finally block generation during inlining --- .../org/jetbrains/kotlin/codegen/FrameMap.kt | 7 ++++ .../kotlin/codegen/inline/InlineCodegen.kt | 34 ++++++------------- .../inline/PsiSourceCompilerForInline.kt | 10 ++---- .../codegen/inline/SourceCompilerForInline.kt | 9 +---- .../jvm/codegen/IrSourceCompilerForInline.kt | 14 ++------ 5 files changed, 25 insertions(+), 49 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FrameMap.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/FrameMap.kt index c87f73d25a1..2839e21c7dd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FrameMap.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FrameMap.kt @@ -68,6 +68,13 @@ open class FrameMapBase { return Mark(currentSize) } + fun skipTo(target: Int): Mark { + return mark().also { + if (currentSize < target) + currentSize = target + } + } + inner class Mark(private val myIndex: Int) { fun dropTo() { 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 23672b8e9f7..dafed48c474 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -113,7 +113,7 @@ abstract class InlineCodegen( val infos = MethodInliner.processReturns(adapter, sourceCompiler.getContextLabels(), null) generateAndInsertFinallyBlocks( - adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index + adapter, infos, (remapper.remap(parameters.argsSizeOnStack).value as StackValue.Local).index ) if (!sourceCompiler.isFinallyMarkerRequired) { removeFinallyMarkers(adapter) @@ -165,37 +165,25 @@ abstract class InlineCodegen( val extension = extensionPoints[curInstr] if (extension != null) { - val start = Label() + var nextFreeLocalIndex = processor.nextFreeLocalIndex + for (local in processor.localVarsMetaInfo.currentIntervals) { + val size = Type.getType(local.node.desc).size + nextFreeLocalIndex = max(offsetForFinallyLocalVar + local.node.index + size, nextFreeLocalIndex) + } + val start = Label() val finallyNode = createEmptyMethodNode() finallyNode.visitLabel(start) - - val finallyCodegen = - sourceCompiler.createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode, curFinallyDepth) - - val frameMap = finallyCodegen.frameMap - val mark = frameMap.mark() - var marker = -1 - val intervals = processor.localVarsMetaInfo.currentIntervals - for (interval in intervals) { - marker = max(interval.node.index + 1, marker) - } - while (frameMap.currentSize < max(processor.nextFreeLocalIndex, offsetForFinallyLocalVar + marker)) { - frameMap.enterTemp(Type.INT_TYPE) - } - - sourceCompiler.generateFinallyBlocksIfNeeded( - finallyCodegen, extension.returnType, extension.finallyIntervalEnd.label, extension.jumpTarget + val mark = codegen.frameMap.skipTo(nextFreeLocalIndex) + sourceCompiler.generateFinallyBlocks( + finallyNode, curFinallyDepth, extension.returnType, extension.finallyIntervalEnd.label, extension.jumpTarget ) - - //Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method + mark.dropTo() insertNodeBefore(finallyNode, intoNode, curInstr) val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd) processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true) processor.localVarsMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true) - - mark.dropTo() } curInstr = curInstr.next 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 d8b0ae84d70..874bad76bc0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt @@ -295,19 +295,15 @@ class PsiSourceCompilerForInline( override fun hasFinallyBlocks() = codegen.hasFinallyBlocks() - override fun generateFinallyBlocksIfNeeded(codegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label, target: Label?) { + override fun generateFinallyBlocks(finallyNode: MethodNode, curFinallyDepth: Int, returnType: Type, afterReturnLabel: Label, target: Label?) { // TODO use the target label for non-local break/continue - require(codegen is ExpressionCodegen) - codegen.generateFinallyBlocksIfNeeded(returnType, null, afterReturnLabel) - } - - override fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode: MethodNode, curFinallyDepth: Int) = ExpressionCodegen( finallyNode, codegen.frameMap, codegen.returnType, codegen.getContext(), codegen.state, codegen.parentCodegen ).also { it.addBlockStackElementsForNonLocalReturns(codegen.blockStackElements, curFinallyDepth) - } + }.generateFinallyBlocksIfNeeded(returnType, null, afterReturnLabel) + } override val isCallInsideSameModuleAsCallee: Boolean get() = JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory) 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 af09f4878eb..a6b714e324b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt @@ -7,7 +7,6 @@ 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.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.CommonConfigurationKeys @@ -17,7 +16,6 @@ import org.jetbrains.kotlin.incremental.components.ScopeKind import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature -import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.Method @@ -48,12 +46,7 @@ interface SourceCompilerForInline { fun hasFinallyBlocks(): Boolean - fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn( - finallyNode: MethodNode, - curFinallyDepth: Int - ): BaseExpressionCodegen - - fun generateFinallyBlocksIfNeeded(codegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label, target: Label?) + fun generateFinallyBlocks(finallyNode: MethodNode, curFinallyDepth: Int, returnType: Type, afterReturnLabel: Label, target: Label?) val isCallInsideSameModuleAsCallee: Boolean 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 f9002226898..38079cd5224 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 @@ -6,12 +6,10 @@ package org.jetbrains.kotlin.backend.jvm.codegen import com.intellij.openapi.util.TextRange -import com.intellij.psi.PsiFile import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.ir.ir2string 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.inline.* import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.diagnostics.DiagnosticUtils @@ -26,11 +24,9 @@ import org.jetbrains.kotlin.ir.util.isSuspend import org.jetbrains.kotlin.ir.util.kotlinFqName import org.jetbrains.kotlin.ir.util.module import org.jetbrains.kotlin.ir.util.parentAsClass -import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.doNotAnalyze import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature -import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter @@ -97,18 +93,14 @@ class IrSourceCompilerForInline( override fun hasFinallyBlocks() = data.hasFinallyBlocks() - override fun generateFinallyBlocksIfNeeded(codegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label, target: Label?) { - require(codegen is ExpressionCodegen) - codegen.generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, target) - } - - override fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode: MethodNode, curFinallyDepth: Int) = + override fun generateFinallyBlocks(finallyNode: MethodNode, curFinallyDepth: Int, returnType: Type, afterReturnLabel: Label, target: Label?) { ExpressionCodegen( codegen.irFunction, codegen.signature, codegen.frameMap, InstructionAdapter(finallyNode), codegen.classCodegen, codegen.inlinedInto, codegen.smap, codegen.reifiedTypeParametersUsages ).also { it.finallyDepth = curFinallyDepth - } + }.generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, target) + } @OptIn(ObsoleteDescriptorBasedAPI::class) override val isCallInsideSameModuleAsCallee: Boolean