From 7a18ab90947ce3b57c213a6d45624a7b15280762 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Mon, 16 Nov 2020 19:46:04 +0100 Subject: [PATCH] IC mangling: Generate version requirements to properties as well Generate the requirements at JVM only. --- .../serialization/JvmSerializerExtension.kt | 20 +++++-- .../kotlin/codegen/state/GenerationState.kt | 5 +- .../MemoizedInlineClassReplacements.kt | 2 +- .../serialization/DescriptorSerializer.kt | 12 +---- .../serialization/SerializerExtension.kt | 2 - .../AbstractVersionRequirementTest.kt | 12 +---- .../JvmVersionRequirementTest.kt | 53 +++++++++++-------- 7 files changed, 55 insertions(+), 51 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt index 7cc905d52fa..40b90e36cdb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt @@ -61,7 +61,7 @@ class JvmSerializerExtension @JvmOverloads constructor( override val metadataVersion = state.metadataVersion private val jvmDefaultMode = state.jvmDefaultMode private val approximator = state.typeApproximator - private val useOldManglingScheme = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME) + private val useOldManglingScheme = state.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures override fun shouldUseTypeTable(): Boolean = useTypeTable override fun shouldSerializeFunction(descriptor: FunctionDescriptor): Boolean { @@ -217,6 +217,13 @@ class JvmSerializerExtension @JvmOverloads constructor( ) { versionRequirementTable?.writeFunctionNameManglingForReturnTypeRequirement(proto::addVersionRequirement) } + + if ((requiresFunctionNameManglingForReturnType(descriptor) || + requiresFunctionNameManglingForParameterTypes(descriptor)) && + !DescriptorUtils.hasJvmNameAnnotation(descriptor) && !useOldManglingScheme + ) { + versionRequirementTable?.writeNewFunctionNameManglingRequirement(proto::addVersionRequirement) + } } private fun MutableVersionRequirementTable.writeInlineParameterNullCheckRequirement(add: (Int) -> Unit) { @@ -233,6 +240,12 @@ class JvmSerializerExtension @JvmOverloads constructor( } } + private fun MutableVersionRequirementTable.writeNewFunctionNameManglingRequirement(add: (Int) -> Unit) { + if (languageVersionSettings.languageVersion.major == 1 && languageVersionSettings.languageVersion.minor >= 4) { + add(writeVersionRequirement(1, 4, 30, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, this)) + } + } + private fun FunctionDescriptor.needsInlineParameterNullCheckRequirement(): Boolean = isInline && !isSuspend && !isParamAssertionsDisabled && !DescriptorVisibilities.isPrivate(visibility) && @@ -280,6 +293,9 @@ class JvmSerializerExtension @JvmOverloads constructor( } if (!DescriptorUtils.hasJvmNameAnnotation(descriptor) && requiresFunctionNameManglingForReturnType(descriptor)) { + if (!useOldManglingScheme) { + versionRequirementTable?.writeNewFunctionNameManglingRequirement(proto::addVersionRequirement) + } versionRequirementTable?.writeFunctionNameManglingForReturnTypeRequirement(proto::addVersionRequirement) } } @@ -401,6 +417,4 @@ class JvmSerializerExtension @JvmOverloads constructor( override fun releaseCoroutines(): Boolean { return languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) } - - override fun useOldInlineClassesManglingScheme(): Boolean = useOldManglingScheme } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index 8f0ebf82c3a..0315e9373fd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -195,6 +195,9 @@ class GenerationState private constructor( val languageVersionSettings = configuration.languageVersionSettings + val useOldManglingSchemeForFunctionsWithInlineClassesInSignatures = + configuration.getBoolean(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME) + val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT val runtimeStringConcat = if (target.bytecodeVersion >= JvmTarget.JVM_9.bytecodeVersion) @@ -214,7 +217,7 @@ class GenerationState private constructor( classBuilderMode, this.moduleName, languageVersionSettings, - configuration.getBoolean(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME), + useOldManglingSchemeForFunctionsWithInlineClassesInSignatures, IncompatibleClassTrackerImpl(extraJvmDiagnosticsTrace), target, isIrBackend diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt index d9bfcb12bab..677b7260343 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt @@ -222,7 +222,7 @@ class MemoizedInlineClassReplacements( if (noFakeOverride) { isFakeOverride = false } - val useOldManglingScheme = context.state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME) + val useOldManglingScheme = context.state.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures name = mangledNameFor(function, mangleReturnTypes, useOldManglingScheme) if ( !useOldManglingScheme && diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index c81709282d6..e9bb36cf332 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -362,17 +362,7 @@ class DescriptorSerializer private constructor( } if (descriptor.hasInlineClassTypesInSignature()) { - if (extension.useOldInlineClassesManglingScheme()) { - builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses)) - } else { - builder.addVersionRequirement( - writeVersionRequirement( - 1, 4, 30, - ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, - this - ) - ) - } + builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses)) } } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt index 5c7e71d1127..7e6b76ae01b 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/SerializerExtension.kt @@ -94,6 +94,4 @@ abstract class SerializerExtension { } open fun releaseCoroutines(): Boolean = false - - open fun useOldInlineClassesManglingScheme(): Boolean = false } diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt index 6444842cf6f..32a4e306aa5 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt @@ -211,19 +211,9 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() { "test.Ctor.", "test.Foo", "test.Bar", + "test.result", "test.simpleProp" ) ) } - - fun testInlineClassesAndRelevantDeclarations1430() { - doTest( - VersionRequirement.Version(1, 4, 30), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, null, - fqNamesWithRequirements = listOf( - "test.simpleFun", - "test.aliasedFun", - "test.result", - ) - ) - } } diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt index 03102fe63f0..4ce945f71b9 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt @@ -130,7 +130,8 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() { fun testInlineClassReturnTypeMangled() { // Class members returning inline class values are mangled, - // and have "since 1.4" version requirement along with "since 1.3" version requirement for inline class in signature + // and have "since 1.4", "require 1.4.30" version requirement along with + // "since 1.3" version requirement for inline class in signature doTest( VersionRequirement.Version(1, 4, 0), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null, fqNamesWithRequirements = listOf( @@ -140,42 +141,39 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() { customLanguageVersion = LanguageVersion.KOTLIN_1_4, shouldBeSingleRequirement = false ) + doTest( + VersionRequirement.Version(1, 4, 30), DeprecationLevel.ERROR, null, COMPILER_VERSION, null, + fqNamesWithRequirements = listOf( + "test.C.propertyOfInlineClassType", + "test.C.returnsInlineClassType", + ), + shouldBeSingleRequirement = false, + customLanguageVersion = LanguageVersion.KOTLIN_1_4 + ) // Top-level functions and properties returning inline class values are NOT mangled, // and have "since 1.3" version requirement for inline class in signature only. doTest( VersionRequirement.Version(1, 3, 0), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null, fqNamesWithRequirements = listOf( - "test.propertyOfInlineClassType" + "test.propertyOfInlineClassType", + "test.returnsInlineClassType", ), - shouldBeSingleRequirement = true, + shouldBeSingleRequirement = false, customLanguageVersion = LanguageVersion.KOTLIN_1_4 ) - doTest( - VersionRequirement.Version(1, 3, 0), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null, - fqNamesWithRequirements = listOf( - "test.C.propertyOfInlineClassType" - ), - shouldBeSingleRequirement = true, - customLanguageVersion = LanguageVersion.KOTLIN_1_3 - ) // In Kotlin 1.3, all functions and properties returning inline class values are NOT mangled, // and have "since 1.3" version requirement for inline class in signature only. doTest( - VersionRequirement.Version(1, 4, 30), DeprecationLevel.ERROR, null, COMPILER_VERSION, null, + VersionRequirement.Version(1, 3, 0), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null, fqNamesWithRequirements = listOf( + "test.propertyOfInlineClassType", + "test.C.propertyOfInlineClassType", "test.C.returnsInlineClassTypeJvmName", - "test.returnsInlineClassType" - ), - shouldBeSingleRequirement = true, - customLanguageVersion = LanguageVersion.KOTLIN_1_4 - ) - doTest( - VersionRequirement.Version(1, 4, 30), DeprecationLevel.ERROR, null, COMPILER_VERSION, null, - fqNamesWithRequirements = listOf( + "test.returnsInlineClassType", "test.C.returnsInlineClassType" ), - shouldBeSingleRequirement = false, - customLanguageVersion = LanguageVersion.KOTLIN_1_4 + shouldBeSingleRequirement = true, + customLanguageVersion = LanguageVersion.KOTLIN_1_3 ) } @@ -195,4 +193,15 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() { ) ) } + + fun testInlineClassesAndRelevantDeclarations1430() { + doTest( + VersionRequirement.Version(1, 4, 30), DeprecationLevel.ERROR, null, COMPILER_VERSION, null, + fqNamesWithRequirements = listOf( + "test.simpleFun", + "test.aliasedFun", + ), + shouldBeSingleRequirement = false + ) + } }