From 82899e624355b3fb7c48bc0359ec2ff4cd983b4b Mon Sep 17 00:00:00 2001 From: pyos Date: Mon, 3 Feb 2020 16:01:26 +0100 Subject: [PATCH] JVM_IR: reuse MethodNodes for inline functions in same module This fixes the weird cases when a class gets overwritten by an imperfect copy, reduces the number of classes in the output if an inline function contains an inline call that causes it to have regenerated anonymous objects, and makes inlining of same module functions a bit faster in general. On the other hand, this may increase memory footprint a bit because classes cannot be flushed to the output jar, as the inliner would not be able to locate classes for anonymous objects if they have already been unloaded from memory. --- .../ir/FirBlackBoxCodegenTestGenerated.java | 5 + .../kotlin/backend/jvm/JvmBackendContext.kt | 9 +- .../kotlin/backend/jvm/JvmBackendFacade.kt | 7 +- .../backend/jvm/codegen/ClassCodegen.kt | 113 +++++++------- .../backend/jvm/codegen/CoroutineCodegen.kt | 4 +- .../backend/jvm/codegen/ExpressionCodegen.kt | 2 +- .../backend/jvm/codegen/FunctionCodegen.kt | 13 +- .../backend/jvm/codegen/IrInlineCodegen.kt | 10 +- .../jvm/codegen/IrSourceCompilerForInline.kt | 95 +----------- .../tailCallOptimizations/crossinline_ir.txt | 114 +------------- .../inlineWithoutStateMachine_ir.txt | 2 +- .../innerObjectRetransformation_ir.txt | 24 +-- .../unit/override5_ir.txt | 2 +- .../codegen/box/finally/objectInFinally.kt | 14 ++ .../coroutineContextIntrinsic_ir.txt | 18 +++ .../coroutines/coroutineFields_ir.txt | 4 +- .../coroutines/oomInReturnUnit_ir.txt | 17 +++ .../coroutines/tcoContinuation_ir.txt | 139 ------------------ .../writeFlags/inline/lostInnerClass.kt | 1 - .../writeFlags/inline/lostInnerClass2.kt | 1 - .../codegen/BlackBoxCodegenTestGenerated.java | 5 + .../LightAnalysisModeTestGenerated.java | 5 + .../ir/IrBlackBoxCodegenTestGenerated.java | 5 + .../directives.txt | 1 - .../IrJsCodegenBoxTestGenerated.java | 5 + .../semantics/JsCodegenBoxTestGenerated.java | 5 + 26 files changed, 170 insertions(+), 450 deletions(-) create mode 100644 compiler/testData/codegen/box/finally/objectInFinally.kt create mode 100644 compiler/testData/codegen/bytecodeListing/coroutines/coroutineContextIntrinsic_ir.txt create mode 100644 compiler/testData/codegen/bytecodeListing/coroutines/oomInReturnUnit_ir.txt delete mode 100644 jps-plugin/testData/incremental/withJava/other/innerClassNotGeneratedWhenRebuilding/directives.txt diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 378729caafd..287c2e32528 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -10712,6 +10712,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/finally/notChainCatch.kt"); } + @TestMetadata("objectInFinally.kt") + public void testObjectInFinally() throws Exception { + runTest("compiler/testData/codegen/box/finally/objectInFinally.kt"); + } + @TestMetadata("tryFinally.kt") public void testTryFinally() throws Exception { runTest("compiler/testData/codegen/box/finally/tryFinally.kt"); diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index a1b75aba0c7..8855057d8dd 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.Mapping import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.lower.irThrow import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig +import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen import org.jetbrains.kotlin.backend.jvm.codegen.IrTypeMapper import org.jetbrains.kotlin.backend.jvm.codegen.MethodSignatureMapper import org.jetbrains.kotlin.backend.jvm.codegen.createFakeContinuation @@ -20,7 +21,6 @@ import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods import org.jetbrains.kotlin.backend.jvm.lower.CollectionStubComputer import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.MemoizedInlineClassReplacements -import org.jetbrains.kotlin.codegen.inline.NameGenerator import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor @@ -90,12 +90,7 @@ class JvmBackendContext( internal val customEnclosingFunction = mutableMapOf() - // TODO cache these at ClassCodegen level. Currently, sharing this map between classes in a module is required - // because IrSourceCompilerForInline constructs a new (Fake)ClassCodegen for every call to - // an inline function in the same module. Thus, if two inline functions happen to have the same name - // and call a third inline function that has an anonymous object, the one which is called last - // will overwrite the other's regenerated copy. (Or don't recompile the inline function for every call.) - internal val regeneratedObjectNameGenerators = mutableMapOf, NameGenerator>() + internal val classCodegens = mutableMapOf() internal val localDelegatedProperties = mutableMapOf>() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt index 6cf16ba1091..fa7b3a6e922 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt @@ -112,14 +112,15 @@ object JvmBackendFacade { if (loweredClass !is IrClass) { throw AssertionError("File-level declaration should be IrClass after JvmLower, got: " + loweredClass.render()) } - - ClassCodegen.generate(loweredClass, context) + ClassCodegen.getOrCreate(loweredClass, context).generate() } - state.afterIndependentPart() } catch (e: Throwable) { CodegenUtil.reportBackendException(e, "code generation", irFile.fileEntry.name) } } } + // TODO: split classes into groups connected by inline calls; call this after every group + // and clear `JvmBackendContext.classCodegens` + state.afterIndependentPart() } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index ab9684a6568..5043ba6c8b8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -44,15 +44,15 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.commons.Method +import org.jetbrains.org.objectweb.asm.tree.MethodNode import java.io.File -open class ClassCodegen protected constructor( +class ClassCodegen private constructor( internal val irClass: IrClass, val context: JvmBackendContext, - private val parentClassCodegen: ClassCodegen? = null, private val parentFunction: IrFunction? = null ) : InnerClassConsumer { - private val innerClasses = mutableListOf() + private val parentClassCodegen = (parentFunction?.parentAsClass ?: irClass.parent as? IrClass)?.let { getOrCreate(it, context) } private val withinInline: Boolean = parentClassCodegen?.withinInline == true || parentFunction?.isInline == true private val state get() = context.state @@ -79,10 +79,21 @@ open class ClassCodegen protected constructor( } } - val visitor: ClassBuilder = createClassBuilder() - - open fun createClassBuilder(): ClassBuilder { - return state.factory.newVisitor(classOrigin, type, irClass.fileParent.loadSourceFilesInfo()) + private val visitor = state.factory.newVisitor(classOrigin, type, irClass.fileParent.loadSourceFilesInfo()).apply { + val signature = getSignature(irClass, type, irClass.getSuperClassInfo(typeMapper), typeMapper) + // Ensure that the backend only produces class names that would be valid in the frontend for JVM. + if (context.state.classBuilderMode.generateBodies && signature.hasInvalidName()) { + throw IllegalStateException("Generating class with invalid name '${type.className}': ${irClass.dump()}") + } + defineClass( + irClass.descriptor.psiElement, + state.classFileVersion, + irClass.flags, + signature.name, + signature.javaGenericSignature, + signature.superclassName, + signature.interfaces.toTypedArray() + ) } private var sourceMapper: DefaultSourceMapper? = null @@ -103,9 +114,11 @@ open class ClassCodegen protected constructor( else -> null } + private var regeneratedObjectNameGenerators = mutableMapOf() + fun getRegeneratedObjectNameGenerator(function: IrFunction): NameGenerator { val name = if (function.name.isSpecial) "special" else function.name.asString() - return context.regeneratedObjectNameGenerators.getOrPut(irClass to name) { + return regeneratedObjectNameGenerators.getOrPut(name) { NameGenerator("${type.internalName}\$$name\$\$inlined") } } @@ -113,27 +126,13 @@ open class ClassCodegen protected constructor( private var hasAssertField = irClass.hasAssertionsDisabledField(context) private var classInitializer = irClass.functions.singleOrNull { it.name.asString() == "" } private var generatingClInit = false + private var generated = false fun generate(): ReifiedTypeParametersUsages { - if (withinInline) { - getOrCreateSourceMapper() //initialize default mapping that would be later written in class file - } - - val signature = getSignature(irClass, type, irClass.getSuperClassInfo(typeMapper), typeMapper) - // Ensure that the backend only produces class names that would be valid in the frontend for JVM. - if (context.state.classBuilderMode.generateBodies && signature.hasInvalidName()) { - throw IllegalStateException("Generating class with invalid name '${type.className}': ${irClass.dump()}") - } - - visitor.defineClass( - irClass.descriptor.psiElement, - state.classFileVersion, - irClass.flags, - signature.name, - signature.javaGenericSignature, - signature.superclassName, - signature.interfaces.toTypedArray() - ) + // TODO: reject repeated generate() calls; currently, these can happen for objects in finally + // blocks since they are `accept`ed once per each CFG edge out of the try-finally. + if (generated) return reifiedTypeParametersUsages + generated = true for (declaration in irClass.declarations) { when (declaration) { @@ -155,7 +154,7 @@ open class ClassCodegen protected constructor( // everything moved to the outer class has already been recorded in `globalSerializationBindings`. for (declaration in irClass.declarations) { if (declaration is IrClass) { - ClassCodegen(declaration, context, this).generate() + getOrCreate(declaration, context).generate() } } @@ -173,21 +172,16 @@ open class ClassCodegen protected constructor( visitor.visitSource(shortName, null) } - if (irClass.origin != JvmLoweredDeclarationOrigin.CONTINUATION_CLASS) { - done() - } - return reifiedTypeParametersUsages - } - - fun done() { generateInnerAndOuterClasses() - sourceMapper?.let { - visitor.visitSMAP(it, !context.state.languageVersionSettings.supportsFeature(LanguageFeature.CorrectSourceMappingSyntax)) + if (withinInline || sourceMapper != null) { + val smap = getOrCreateSourceMapper() + visitor.visitSMAP(smap, !context.state.languageVersionSettings.supportsFeature(LanguageFeature.CorrectSourceMappingSyntax)) } visitor.done() jvmSignatureClashDetector.reportErrors(classOrigin) + return reifiedTypeParametersUsages } fun generateAssertFieldIfNeeded(): IrExpression? { @@ -301,17 +295,21 @@ open class ClassCodegen protected constructor( } companion object { - fun generate(irClass: IrClass, context: JvmBackendContext) { - ClassCodegen(irClass, context).generate() - } + fun getOrCreate(irClass: IrClass, context: JvmBackendContext, parentFunction: IrFunction? = null): ClassCodegen = + context.classCodegens.getOrPut(irClass) { + ClassCodegen(irClass, context, parentFunction) + }.also { + assert(parentFunction == null || it.parentFunction == parentFunction) { + "inconsistent parent function for ${irClass.render()}:\n" + + "New: ${parentFunction!!.render()}\n" + + "Old: ${it.parentFunction?.render()}" + } + } private fun JvmClassSignature.hasInvalidName() = name.splitToSequence('/').any { identifier -> identifier.any { it in JvmSimpleNameBacktickChecker.INVALID_CHARS } } } - fun createLocalClassCodegen(klass: IrClass, parentFunction: IrFunction): ClassCodegen = - ClassCodegen(klass, context, this, parentFunction) - private fun generateField(field: IrField) { if (field.isFakeOverride) return @@ -345,13 +343,29 @@ open class ClassCodegen protected constructor( } } + private val generatedInlineMethods = mutableMapOf() + + fun generateMethodNode(method: IrFunction): MethodNode { + if (!method.isInline && !method.isSuspend) { + // Inline methods can be used multiple times by `IrSourceCompilerForInline`, suspend methods + // could be used twice if they capture crossinline lambdas, and everything else is only + // generated by `generateMethod` below so does not need caching. + return FunctionCodegen(method, this).generate() + } + val node = generatedInlineMethods.getOrPut(method) { FunctionCodegen(method, this).generate() } + val copy = with(node) { MethodNode(Opcodes.API_VERSION, access, name, desc, signature, exceptions.toTypedArray()) } + node.instructions.resetLabels() + node.accept(copy) + return copy + } + private fun generateMethod(method: IrFunction) { if (method.isFakeOverride) { jvmSignatureClashDetector.trackFakeOverrideMethod(method) return } - val node = FunctionCodegen(method, this).generate() + val node = generateMethodNode(method) node.preprocessSuspendMarkers( method.origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE, method.origin == JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE @@ -360,14 +374,12 @@ open class ClassCodegen protected constructor( if (method.hasContinuation() || method.isInvokeSuspendOfLambda()) { // Generate a state machine within this method. The continuation class for it should be generated // lazily so that if tail call optimization kicks in, the unused class will not be written to the output. - val continuationClassCodegen = lazy { - createLocalClassCodegen(method.continuationClass()!!, method).also { it.generate() } - } + val continuationClassCodegen = lazy { getOrCreate(method.continuationClass()!!, context, method) } node.acceptWithStateMachine(method, this, mv) { if (method.isSuspend) continuationClassCodegen.value.visitor else visitor } if (continuationClassCodegen.isInitialized() || method.alwaysNeedsContinuation()) { - continuationClassCodegen.value.done() + continuationClassCodegen.value.generate() } } else { node.accept(mv) @@ -398,10 +410,7 @@ open class ClassCodegen protected constructor( private fun generateInnerAndOuterClasses() { // JVMS7 (4.7.6): a nested class or interface member will have InnerClasses information // for each enclosing class and for each immediate member - parentClassCodegen?.innerClasses?.add(irClass) - for (innerClass in innerClasses) { - writeInnerClass(innerClass, typeMapper, context, visitor) - } + parentClassCodegen?.let { writeInnerClass(irClass, typeMapper, context, it.visitor) } for (codegen in generateSequence(this) { it.parentClassCodegen }.takeWhile { it.parentClassCodegen != null }) { writeInnerClass(codegen.irClass, typeMapper, context, visitor) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt index 3149f8f7fb3..fafbe7c0721 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt @@ -55,11 +55,11 @@ internal fun MethodNode.acceptWithStateMachine( sourceFile = classCodegen.irClass.file.name, languageVersionSettings = languageVersionSettings, shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, - containingClassInternalName = classCodegen.visitor.thisName, + containingClassInternalName = classCodegen.type.internalName, isForNamedFunction = irFunction.isSuspend, // SuspendLambda.invokeSuspend is not suspend needDispatchReceiver = irFunction.isSuspend && (irFunction.dispatchReceiverParameter != null || irFunction.origin == JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION), - internalNameForDispatchReceiver = classCodegen.visitor.thisName, + internalNameForDispatchReceiver = classCodegen.type.internalName, putContinuationParameterToLvt = false, disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let { it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 13e35722e00..2754cd8962f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -697,7 +697,7 @@ class ExpressionCodegen( override fun visitClass(declaration: IrClass, data: BlockInfo): PromisedValue { if (declaration.origin != JvmLoweredDeclarationOrigin.CONTINUATION_CLASS) { closureReifiedMarkers[declaration] = - classCodegen.createLocalClassCodegen(declaration, generateSequence(this) { it.inlinedInto }.last().irFunction).generate() + ClassCodegen.getOrCreate(declaration, context, generateSequence(this) { it.inlinedInto }.last().irFunction).generate() } return unitValue } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index e9eebce9081..72dcf3d5ab0 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper +import org.jetbrains.kotlin.codegen.inline.MethodBodyVisitor import org.jetbrains.kotlin.codegen.inline.wrapWithMaxLocalCalc import org.jetbrains.kotlin.codegen.mangleNameIfNeeded import org.jetbrains.kotlin.codegen.state.GenerationState @@ -86,17 +87,19 @@ class FunctionCodegen( } } + // `$$forInline` versions of suspend functions have the same bodies as the originals, but with different + // name/flags/annotations and with no state machine. + val notForInline = irFunction.suspendForInlineToOriginal() if (!context.state.classBuilderMode.generateBodies || flags.and(Opcodes.ACC_ABSTRACT) != 0 || irFunction.isExternal) { generateAnnotationDefaultValueIfNeeded(methodVisitor) + } else if (notForInline != null) { + classCodegen.generateMethodNode(notForInline).accept(MethodBodyVisitor(methodVisitor)) } else { - // `$$forInline` versions of suspend functions have the same bodies are the originals, but with different - // name/flags/annotations and with no state machine. - val notForInline = irFunction.suspendForInlineToOriginal() ?: irFunction - val frameMap = notForInline.createFrameMapWithReceivers() + val frameMap = irFunction.createFrameMapWithReceivers() context.state.globalInlineContext.enterDeclaration(irFunction.suspendFunctionOriginal().descriptor) try { val adapter = InstructionAdapter(methodVisitor) - ExpressionCodegen(notForInline, signature, frameMap, adapter, classCodegen, inlinedInto, smapOverride).generate() + ExpressionCodegen(irFunction, signature, frameMap, adapter, classCodegen, inlinedInto, smapOverride).generate() } finally { context.state.globalInlineContext.exitDeclaration() } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index 4db3ac82717..a9d07444b12 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -46,12 +46,10 @@ class IrInlineCodegen( IrCallGenerator { override fun generateAssertFieldIfNeeded(info: RootInliningContext) { - if (info.generateAssertField && (sourceCompiler as IrSourceCompilerForInline).isPrimaryCopy) { - codegen.classCodegen.generateAssertFieldIfNeeded()?.run { - // Generating right now, so no longer can insert the initializer into it. - // Instead, ask ExpressionCodegen to generate the code for it directly. - accept(codegen, BlockInfo()).discard() - } + if (info.generateAssertField) { + // May be inlining code into ``, in which case it's too late to modify the IR and + // `generateAssertFieldIfNeeded` will return a statement for which we need to emit bytecode. + codegen.classCodegen.generateAssertFieldIfNeeded()?.accept(codegen, BlockInfo())?.discard() } } 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 35ad2490108..76231cd9098 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,15 +6,12 @@ package org.jetbrains.kotlin.backend.jvm.codegen import com.intellij.openapi.util.TextRange -import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.codegen.BaseExpressionCodegen -import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.inline.* -import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource @@ -23,16 +20,15 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.incremental.components.LocationInfo import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.Position -import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.util.isSuspend +import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.doNotAnalyze import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR -import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.org.objectweb.asm.* @@ -105,8 +101,8 @@ class IrSourceCompilerForInline( asmMethod: Method ): SMAPAndMethodNode { assert(callableDescriptor == callee.symbol.descriptor.original) { "Expected $callableDescriptor got ${callee.descriptor.original}" } - val classCodegen = FakeClassCodegen(callee, codegen.classCodegen) - val node = FunctionCodegen(callee, classCodegen).generate() + val classCodegen = ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context) + val node = classCodegen.generateMethodNode(callee) return SMAPAndMethodNode(node, SMAP(classCodegen.getOrCreateSourceMapper().resultMappings)) } @@ -153,89 +149,4 @@ class IrSourceCompilerForInline( } private fun findElement() = (callElement.symbol.descriptor.original as? DeclarationDescriptorWithSource)?.source?.getPsi() as? KtElement - - internal val isPrimaryCopy: Boolean - get() = codegen.classCodegen !is FakeClassCodegen - - private class FakeClassCodegen(irFunction: IrFunction, codegen: ClassCodegen) : - ClassCodegen(irFunction.parent as IrClass, codegen.context) { - - override fun createClassBuilder(): ClassBuilder { - return FakeBuilder - } - - companion object { - val FakeBuilder = object : ClassBuilder { - override fun newField( - origin: JvmDeclarationOrigin, - access: Int, - name: String, - desc: String, - signature: String?, - value: Any? - ): FieldVisitor { - TODO("not implemented") - } - - override fun newMethod( - origin: JvmDeclarationOrigin, - access: Int, - name: String, - desc: String, - signature: String?, - exceptions: Array? - ): MethodVisitor { - TODO("not implemented") - } - - override fun getSerializationBindings(): JvmSerializationBindings { - return JvmSerializationBindings() - } - - override fun newAnnotation(desc: String, visible: Boolean): AnnotationVisitor { - TODO("not implemented") - } - - override fun done() { - TODO("not implemented") - } - - override fun getVisitor(): ClassVisitor { - TODO("not implemented") - } - - override fun defineClass( - origin: PsiElement?, - version: Int, - access: Int, - name: String, - signature: String?, - superName: String, - interfaces: Array - ) { - TODO("not implemented") - } - - override fun visitSource(name: String, debug: String?) { - TODO("not implemented") - } - - override fun visitOuterClass(owner: String, name: String?, desc: String?) { - TODO("not implemented") - } - - override fun visitSMAP(smap: SourceMapper, backwardsCompatibleSyntax: Boolean) { - TODO("not implemented") - } - - override fun visitInnerClass(name: String, outerName: String?, innerName: String?, access: Int) { - TODO("not implemented") - } - - override fun getThisName(): String { - TODO("not implemented") - } - } - } - } } diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt index 5e808ce07ad..f4b95e7f8cf 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt @@ -127,35 +127,6 @@ public final class CrossinlineKt$filter$$inlined$source$1 { public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata -public final class CrossinlineKt$filter$$inlined$source$2$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object - field L$4: java.lang.Object - field L$5: java.lang.Object - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: CrossinlineKt$filter$$inlined$source$2 - inner class CrossinlineKt$filter$$inlined$source$2 - inner class CrossinlineKt$filter$$inlined$source$2$1 - public method (p0: CrossinlineKt$filter$$inlined$source$2, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class CrossinlineKt$filter$$inlined$source$2 { - synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1 - synthetic final field $this$inlined: SourceCrossinline - inner class CrossinlineKt$filter$$inlined$source$2 - inner class CrossinlineKt$filter$$inlined$source$2$1 - public method (p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void - public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - @kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1$1 { @@ -183,33 +154,6 @@ public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1 { public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata -public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2 - inner class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2 - inner class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2$1 - public method (p0: CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2 { - synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1 - synthetic final field $this$inlined: Sink - inner class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2 - inner class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2$1 - public method (p0: kotlin.jvm.functions.Function1, p1: Sink): void - public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void - public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - @kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata public final class CrossinlineKt$fold$$inlined$consumeEach$1$1 { @@ -238,64 +182,8 @@ public final class CrossinlineKt$fold$$inlined$consumeEach$1 { public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata -public final class CrossinlineKt$fold$$inlined$consumeEach$2$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$2 - inner class CrossinlineKt$fold$$inlined$consumeEach$2 - inner class CrossinlineKt$fold$$inlined$consumeEach$2$1 - public method (p0: CrossinlineKt$fold$$inlined$consumeEach$2, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - @kotlin.Metadata -public final class CrossinlineKt$fold$$inlined$consumeEach$2 { - synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef - synthetic final field $operation$inlined: kotlin.jvm.functions.Function3 - inner class CrossinlineKt$fold$$inlined$consumeEach$2 - inner class CrossinlineKt$fold$$inlined$consumeEach$2$1 - public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void - public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void - public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - -@kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata -public final class CrossinlineKt$fold$$inlined$consumeEach$3$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$3 - inner class CrossinlineKt$fold$$inlined$consumeEach$3 - inner class CrossinlineKt$fold$$inlined$consumeEach$3$1 - public method (p0: CrossinlineKt$fold$$inlined$consumeEach$3, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class CrossinlineKt$fold$$inlined$consumeEach$3 { - synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef - synthetic final field $operation$inlined: kotlin.jvm.functions.Function3 - inner class CrossinlineKt$fold$$inlined$consumeEach$3 - inner class CrossinlineKt$fold$$inlined$consumeEach$3$1 - public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void - public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void - public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - -@kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata final class CrossinlineKt$fold$1 { field L$0: java.lang.Object field L$1: java.lang.Object @@ -338,8 +226,8 @@ public final class CrossinlineKt$range$$inlined$source$1 { public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata public final class CrossinlineKt$source$1$consume$1 { field L$0: java.lang.Object field L$1: java.lang.Object diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine_ir.txt index a92a4027c51..fa8ad6e391a 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine_ir.txt @@ -12,8 +12,8 @@ final class InlineWithoutStateMachineKt$box$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } -@kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata final class InlineWithoutStateMachineKt$complexSuspend$1 { field L$0: java.lang.Object field L$1: java.lang.Object diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt index 3fb78b70c43..0a55228895a 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt @@ -41,8 +41,8 @@ public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata final class flow/InnerObjectRetransformationKt$check$1 { field L$0: java.lang.Object field label: int @@ -116,28 +116,6 @@ public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1 { public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 { - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$2 - inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2 - inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 - public method (p0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$2, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2 { - synthetic final field $builderBlock$inlined: kotlin.jvm.functions.Function2 - synthetic final field $this$inlined: flow.Flow - inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2 - inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 - public method (p0: kotlin.jvm.functions.Function2, p1: flow.Flow): void - public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - @kotlin.Metadata public final class flow/InnerObjectRetransformationKt { inner class flow/InnerObjectRetransformationKt$box$1 diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt index 26c9679fd1e..bfbba0e37bc 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt @@ -22,8 +22,8 @@ final class Override5Kt$box$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } -@kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata public final class Override5Kt$inlineMe$1$generic$1 { field L$0: java.lang.Object field label: int diff --git a/compiler/testData/codegen/box/finally/objectInFinally.kt b/compiler/testData/codegen/box/finally/objectInFinally.kt new file mode 100644 index 00000000000..dfb35c05159 --- /dev/null +++ b/compiler/testData/codegen/box/finally/objectInFinally.kt @@ -0,0 +1,14 @@ +var lambda: (() -> String)? = null + +fun f() { + try { + return + } finally { + lambda = { "OK" } + } +} + +fun box(): String { + f() + return lambda?.let { it() } ?: "fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/coroutines/coroutineContextIntrinsic_ir.txt b/compiler/testData/codegen/bytecodeListing/coroutines/coroutineContextIntrinsic_ir.txt new file mode 100644 index 00000000000..c282b724656 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/coroutines/coroutineContextIntrinsic_ir.txt @@ -0,0 +1,18 @@ +@kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata +final class CoroutineContextIntrinsicKt$notTailCall$1 { + field label: int + synthetic field result: java.lang.Object + inner class CoroutineContextIntrinsicKt$notTailCall$1 + method (p0: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + +@kotlin.Metadata +public final class CoroutineContextIntrinsicKt { + inner class CoroutineContextIntrinsicKt$notTailCall$1 + public final static @org.jetbrains.annotations.Nullable method mustBeTailCall(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method notTailCall(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method retrieveCoroutineContext(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.CoroutineContext, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} diff --git a/compiler/testData/codegen/bytecodeListing/coroutines/coroutineFields_ir.txt b/compiler/testData/codegen/bytecodeListing/coroutines/coroutineFields_ir.txt index f22a5b5da76..9e174695321 100644 --- a/compiler/testData/codegen/bytecodeListing/coroutines/coroutineFields_ir.txt +++ b/compiler/testData/codegen/bytecodeListing/coroutines/coroutineFields_ir.txt @@ -1,5 +1,5 @@ -@kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata final class Controller$multipleSuspensions$1 { field L$0: java.lang.Object field label: int @@ -10,8 +10,8 @@ final class Controller$multipleSuspensions$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } -@kotlin.Metadata @kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata final class Controller$nonTailCall$1 { field L$0: java.lang.Object field label: int diff --git a/compiler/testData/codegen/bytecodeListing/coroutines/oomInReturnUnit_ir.txt b/compiler/testData/codegen/bytecodeListing/coroutines/oomInReturnUnit_ir.txt new file mode 100644 index 00000000000..a09ca837d90 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/coroutines/oomInReturnUnit_ir.txt @@ -0,0 +1,17 @@ +@kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata +final class OomInReturnUnitKt$test$1 { + field L$0: java.lang.Object + field label: int + synthetic field result: java.lang.Object + inner class OomInReturnUnitKt$test$1 + method (p0: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + +@kotlin.Metadata +public final class OomInReturnUnitKt { + inner class OomInReturnUnitKt$test$1 + public final static @org.jetbrains.annotations.Nullable method some(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method test(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object +} diff --git a/compiler/testData/codegen/bytecodeListing/coroutines/tcoContinuation_ir.txt b/compiler/testData/codegen/bytecodeListing/coroutines/tcoContinuation_ir.txt index 49d2c6720c0..93b89eab73b 100644 --- a/compiler/testData/codegen/bytecodeListing/coroutines/tcoContinuation_ir.txt +++ b/compiler/testData/codegen/bytecodeListing/coroutines/tcoContinuation_ir.txt @@ -150,57 +150,6 @@ public final class TcoContinuationKt$map$$inlined$transform$1 { public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -public final class TcoContinuationKt$map$$inlined$transform$2$1 { - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: TcoContinuationKt$map$$inlined$transform$2 - inner class TcoContinuationKt$map$$inlined$transform$2 - inner class TcoContinuationKt$map$$inlined$transform$2$1 - public method (p0: TcoContinuationKt$map$$inlined$transform$2, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata -public final class TcoContinuationKt$map$$inlined$transform$2$2$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object - field L$4: java.lang.Object - field L$5: java.lang.Object - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: TcoContinuationKt$map$$inlined$transform$2$2 - inner class TcoContinuationKt$map$$inlined$transform$2$2 - inner class TcoContinuationKt$map$$inlined$transform$2$2$1 - public method (p0: TcoContinuationKt$map$$inlined$transform$2$2, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class TcoContinuationKt$map$$inlined$transform$2$2 { - synthetic final field $this$inlined: FlowCollector - synthetic final field $transformer$inlined$1: kotlin.jvm.functions.Function2 - inner class TcoContinuationKt$map$$inlined$transform$2$2 - inner class TcoContinuationKt$map$$inlined$transform$2$2$1 - public method (p0: FlowCollector, p1: kotlin.jvm.functions.Function2): void - public @org.jetbrains.annotations.Nullable method emit$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method emit(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - -@kotlin.Metadata -public final class TcoContinuationKt$map$$inlined$transform$2 { - synthetic final field $this$inlined: Flow - synthetic final field $transformer$inlined$1: kotlin.jvm.functions.Function2 - inner class TcoContinuationKt$map$$inlined$transform$2 - inner class TcoContinuationKt$map$$inlined$transform$2$1 - public method (p0: Flow, p1: kotlin.jvm.functions.Function2): void - public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - @kotlin.Metadata public final class TcoContinuationKt$transform$$inlined$flow$1$1 { field label: int @@ -223,50 +172,6 @@ public final class TcoContinuationKt$transform$$inlined$flow$1 { public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -public final class TcoContinuationKt$transform$$inlined$flow$2$1 { - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: TcoContinuationKt$transform$$inlined$flow$2 - inner class TcoContinuationKt$transform$$inlined$flow$2 - inner class TcoContinuationKt$transform$$inlined$flow$2$1 - public method (p0: TcoContinuationKt$transform$$inlined$flow$2, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class TcoContinuationKt$transform$$inlined$flow$2 { - synthetic final field $this$inlined: Flow - synthetic final field $transformer$inlined: kotlin.jvm.functions.Function3 - inner class TcoContinuationKt$transform$$inlined$flow$2 - inner class TcoContinuationKt$transform$$inlined$flow$2$1 - public method (p0: Flow, p1: kotlin.jvm.functions.Function3): void - public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - -@kotlin.Metadata -public final class TcoContinuationKt$transform$$inlined$flow$3$1 { - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: TcoContinuationKt$transform$$inlined$flow$3 - inner class TcoContinuationKt$transform$$inlined$flow$3 - inner class TcoContinuationKt$transform$$inlined$flow$3$1 - public method (p0: TcoContinuationKt$transform$$inlined$flow$3, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class TcoContinuationKt$transform$$inlined$flow$3 { - synthetic final field $this$inlined: Flow - synthetic final field $transformer$inlined: kotlin.jvm.functions.Function3 - inner class TcoContinuationKt$transform$$inlined$flow$3 - inner class TcoContinuationKt$transform$$inlined$flow$3$1 - public method (p0: Flow, p1: kotlin.jvm.functions.Function3): void - public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - @kotlin.Metadata public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$1$1 { field label: int @@ -289,50 +194,6 @@ public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$1 { public @org.jetbrains.annotations.Nullable method emit(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.Metadata -public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$2$1 { - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: TcoContinuationKt$transform$lambda-1$$inlined$collect$2 - inner class TcoContinuationKt$transform$lambda-1$$inlined$collect$2 - inner class TcoContinuationKt$transform$lambda-1$$inlined$collect$2$1 - public method (p0: TcoContinuationKt$transform$lambda-1$$inlined$collect$2, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$2 { - synthetic final field $this$inlined: FlowCollector - synthetic final field $transformer$inlined: kotlin.jvm.functions.Function3 - inner class TcoContinuationKt$transform$lambda-1$$inlined$collect$2 - inner class TcoContinuationKt$transform$lambda-1$$inlined$collect$2$1 - public method (p0: kotlin.jvm.functions.Function3, p1: FlowCollector): void - public @org.jetbrains.annotations.Nullable method emit$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method emit(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - -@kotlin.Metadata -public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$3$1 { - field label: int - synthetic field result: java.lang.Object - synthetic final field this$0: TcoContinuationKt$transform$lambda-1$$inlined$collect$3 - inner class TcoContinuationKt$transform$lambda-1$$inlined$collect$3 - inner class TcoContinuationKt$transform$lambda-1$$inlined$collect$3$1 - public method (p0: TcoContinuationKt$transform$lambda-1$$inlined$collect$3, p1: kotlin.coroutines.Continuation): void - public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object -} - -@kotlin.Metadata -public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$3 { - synthetic final field $this$inlined: FlowCollector - synthetic final field $transformer$inlined: kotlin.jvm.functions.Function3 - inner class TcoContinuationKt$transform$lambda-1$$inlined$collect$3 - inner class TcoContinuationKt$transform$lambda-1$$inlined$collect$3$1 - public method (p0: kotlin.jvm.functions.Function3, p1: FlowCollector): void - public @org.jetbrains.annotations.Nullable method emit$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - public @org.jetbrains.annotations.Nullable method emit(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object -} - @kotlin.Metadata public final class TcoContinuationKt { inner class TcoContinuationKt$collect$2 diff --git a/compiler/testData/writeFlags/inline/lostInnerClass.kt b/compiler/testData/writeFlags/inline/lostInnerClass.kt index 46f2b639367..addf27a7ef3 100644 --- a/compiler/testData/writeFlags/inline/lostInnerClass.kt +++ b/compiler/testData/writeFlags/inline/lostInnerClass.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR class Introspector { inner class SchemaRetriever(val transaction: String) { inline fun inSchema(crossinline modifier: (String) -> Unit) = diff --git a/compiler/testData/writeFlags/inline/lostInnerClass2.kt b/compiler/testData/writeFlags/inline/lostInnerClass2.kt index 70bf06dc03d..886ad9e7fd4 100644 --- a/compiler/testData/writeFlags/inline/lostInnerClass2.kt +++ b/compiler/testData/writeFlags/inline/lostInnerClass2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR interface Introspector { class SchemaRetriever(val transaction: String) { diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 87e1b693212..493e3ed1885 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -11902,6 +11902,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/finally/notChainCatch.kt"); } + @TestMetadata("objectInFinally.kt") + public void testObjectInFinally() throws Exception { + runTest("compiler/testData/codegen/box/finally/objectInFinally.kt"); + } + @TestMetadata("tryFinally.kt") public void testTryFinally() throws Exception { runTest("compiler/testData/codegen/box/finally/tryFinally.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 7f86f85985f..c265592c642 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11902,6 +11902,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/finally/notChainCatch.kt"); } + @TestMetadata("objectInFinally.kt") + public void testObjectInFinally() throws Exception { + runTest("compiler/testData/codegen/box/finally/objectInFinally.kt"); + } + @TestMetadata("tryFinally.kt") public void testTryFinally() throws Exception { runTest("compiler/testData/codegen/box/finally/tryFinally.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 801acf6d818..a9016586d15 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -10712,6 +10712,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/finally/notChainCatch.kt"); } + @TestMetadata("objectInFinally.kt") + public void testObjectInFinally() throws Exception { + runTest("compiler/testData/codegen/box/finally/objectInFinally.kt"); + } + @TestMetadata("tryFinally.kt") public void testTryFinally() throws Exception { runTest("compiler/testData/codegen/box/finally/tryFinally.kt"); diff --git a/jps-plugin/testData/incremental/withJava/other/innerClassNotGeneratedWhenRebuilding/directives.txt b/jps-plugin/testData/incremental/withJava/other/innerClassNotGeneratedWhenRebuilding/directives.txt deleted file mode 100644 index 5099b2ad971..00000000000 --- a/jps-plugin/testData/incremental/withJava/other/innerClassNotGeneratedWhenRebuilding/directives.txt +++ /dev/null @@ -1 +0,0 @@ -// IGNORE_BACKEND: JVM_IR diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 24261f1979f..1cd9f973923 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -9207,6 +9207,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/finally/notChainCatch.kt"); } + @TestMetadata("objectInFinally.kt") + public void testObjectInFinally() throws Exception { + runTest("compiler/testData/codegen/box/finally/objectInFinally.kt"); + } + @TestMetadata("tryFinally.kt") public void testTryFinally() throws Exception { runTest("compiler/testData/codegen/box/finally/tryFinally.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 9c51b4cadc5..91b54dcfb19 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -9207,6 +9207,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/finally/notChainCatch.kt"); } + @TestMetadata("objectInFinally.kt") + public void testObjectInFinally() throws Exception { + runTest("compiler/testData/codegen/box/finally/objectInFinally.kt"); + } + @TestMetadata("tryFinally.kt") public void testTryFinally() throws Exception { runTest("compiler/testData/codegen/box/finally/tryFinally.kt");