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)
}
fun skipTo(target: Int): Mark {
return mark().also {
if (currentSize < target)
currentSize = target
}
}
inner class Mark(private val myIndex: Int) {
fun dropTo() {
@@ -113,7 +113,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
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<out T : BaseExpressionCodegen>(
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
@@ -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)
@@ -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
@@ -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