JVM: hide ExpressionCodegen in finally block generation during inlining

This commit is contained in:
pyos
2021-06-15 19:03:59 +02:00
committed by max-kammerer
parent 108bd01698
commit aa47191de4
5 changed files with 25 additions and 49 deletions
@@ -68,6 +68,13 @@ open class FrameMapBase<T : Any> {
return Mark(currentSize) return Mark(currentSize)
} }
fun skipTo(target: Int): Mark {
return mark().also {
if (currentSize < target)
currentSize = target
}
}
inner class Mark(private val myIndex: Int) { inner class Mark(private val myIndex: Int) {
fun dropTo() { fun dropTo() {
@@ -113,7 +113,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
val infos = MethodInliner.processReturns(adapter, sourceCompiler.getContextLabels(), null) val infos = MethodInliner.processReturns(adapter, sourceCompiler.getContextLabels(), null)
generateAndInsertFinallyBlocks( 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) { if (!sourceCompiler.isFinallyMarkerRequired) {
removeFinallyMarkers(adapter) removeFinallyMarkers(adapter)
@@ -165,37 +165,25 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
val extension = extensionPoints[curInstr] val extension = extensionPoints[curInstr]
if (extension != null) { 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() val finallyNode = createEmptyMethodNode()
finallyNode.visitLabel(start) finallyNode.visitLabel(start)
val mark = codegen.frameMap.skipTo(nextFreeLocalIndex)
val finallyCodegen = sourceCompiler.generateFinallyBlocks(
sourceCompiler.createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode, curFinallyDepth) finallyNode, curFinallyDepth, extension.returnType, extension.finallyIntervalEnd.label, extension.jumpTarget
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
) )
mark.dropTo()
//Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
insertNodeBefore(finallyNode, intoNode, curInstr) insertNodeBefore(finallyNode, intoNode, curInstr)
val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd) val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd)
processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true) processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true)
processor.localVarsMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true) processor.localVarsMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true)
mark.dropTo()
} }
curInstr = curInstr.next curInstr = curInstr.next
@@ -295,19 +295,15 @@ class PsiSourceCompilerForInline(
override fun hasFinallyBlocks() = codegen.hasFinallyBlocks() 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 // 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( ExpressionCodegen(
finallyNode, codegen.frameMap, codegen.returnType, finallyNode, codegen.frameMap, codegen.returnType,
codegen.getContext(), codegen.state, codegen.parentCodegen codegen.getContext(), codegen.state, codegen.parentCodegen
).also { ).also {
it.addBlockStackElementsForNonLocalReturns(codegen.blockStackElements, curFinallyDepth) it.addBlockStackElementsForNonLocalReturns(codegen.blockStackElements, curFinallyDepth)
} }.generateFinallyBlocksIfNeeded(returnType, null, afterReturnLabel)
}
override val isCallInsideSameModuleAsCallee: Boolean override val isCallInsideSameModuleAsCallee: Boolean
get() = JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory) get() = JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory)
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.codegen.inline
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.codegen.AsmUtil 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.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CommonConfigurationKeys 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.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature 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.Label
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.commons.Method
@@ -48,12 +46,7 @@ interface SourceCompilerForInline {
fun hasFinallyBlocks(): Boolean fun hasFinallyBlocks(): Boolean
fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn( fun generateFinallyBlocks(finallyNode: MethodNode, curFinallyDepth: Int, returnType: Type, afterReturnLabel: Label, target: Label?)
finallyNode: MethodNode,
curFinallyDepth: Int
): BaseExpressionCodegen
fun generateFinallyBlocksIfNeeded(codegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label, target: Label?)
val isCallInsideSameModuleAsCallee: Boolean val isCallInsideSameModuleAsCallee: Boolean
@@ -6,12 +6,10 @@
package org.jetbrains.kotlin.backend.jvm.codegen package org.jetbrains.kotlin.backend.jvm.codegen
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
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.backend.jvm.lower.inlineclasses.hasMangledReturnType
import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils 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.kotlinFqName
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.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
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature 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.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
@@ -97,18 +93,14 @@ class IrSourceCompilerForInline(
override fun hasFinallyBlocks() = data.hasFinallyBlocks() override fun hasFinallyBlocks() = data.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?) {
require(codegen is ExpressionCodegen)
codegen.generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, target)
}
override fun createCodegenForExternalFinallyBlockGenerationOnNonLocalReturn(finallyNode: MethodNode, curFinallyDepth: Int) =
ExpressionCodegen( ExpressionCodegen(
codegen.irFunction, codegen.signature, codegen.frameMap, InstructionAdapter(finallyNode), codegen.classCodegen, codegen.irFunction, codegen.signature, codegen.frameMap, InstructionAdapter(finallyNode), codegen.classCodegen,
codegen.inlinedInto, codegen.smap, codegen.reifiedTypeParametersUsages codegen.inlinedInto, codegen.smap, codegen.reifiedTypeParametersUsages
).also { ).also {
it.finallyDepth = curFinallyDepth it.finallyDepth = curFinallyDepth
} }.generateFinallyBlocksIfNeeded(returnType, afterReturnLabel, data, target)
}
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
override val isCallInsideSameModuleAsCallee: Boolean override val isCallInsideSameModuleAsCallee: Boolean