JVM: hide ExpressionCodegen in finally block generation during inlining
This commit is contained in:
@@ -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
|
||||||
|
|||||||
+3
-7
@@ -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
|
||||||
|
|
||||||
|
|||||||
+3
-11
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user