From 5a686eac9e118421798d0fbf7b89018f283fec67 Mon Sep 17 00:00:00 2001 From: Mads Ager Date: Tue, 19 Jan 2021 14:25:26 +0100 Subject: [PATCH] [JVM_IR] Reduce the amount of `super` suffixes on accesibility bridges. The super suffix was used for any static field/method that needed an accessor. We should only use it when that field or method is inherited. (cherry picked from commit ef36b81c6764119941a39ee1ea0f58178f380a8c) --- .../jvm/lower/SyntheticAccessorLowering.kt | 14 ++++++++------ .../accessorForTopLevelMembers.kt | 6 ++++++ .../accessorForTopLevelMembers.txt | 16 ++++++++++++++++ .../accessorForTopLevelMembers_ir.txt | 16 ++++++++++++++++ .../codegen/BytecodeListingTestGenerated.java | 5 +++++ .../ir/IrBytecodeListingTestGenerated.java | 5 +++++ .../testData/codegen/customSimple.ir.txt | 4 ++-- .../codegen/customSimpleWithNewArray.ir.txt | 4 ++-- 8 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.kt create mode 100644 compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.txt create mode 100644 compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers_ir.txt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt index 302650761260c..0b207a63c2c72 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt @@ -531,9 +531,10 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle // Accessor for _s_uper-qualified call superQualifier != null -> "\$s" + superQualifier.owner.syntheticAccessorToSuperSuffix() - // Access to static members that need an accessor must be because they are inherited, - // hence accessed on a _s_upertype. - isStatic -> "\$s" + parentAsClass.syntheticAccessorToSuperSuffix() + // Access to protected members that need an accessor must be because they are inherited, + // hence accessed on a _s_upertype. If what is accessed is static, we can point to different + // parts of the inheritance hierarchy and need to distinguish with a suffix. + isStatic && visibility.isProtected -> "\$s" + parentAsClass.syntheticAccessorToSuperSuffix() else -> "" } @@ -556,9 +557,10 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle return "cp" } - // Static accesses that need an accessor must be due to being inherited, hence accessed on a - // _s_upertype - return "p" + if (isStatic) "\$s" + parentAsClass.syntheticAccessorToSuperSuffix() else "" + // Accesses to static protected fields that need an accessor must be due to being inherited, hence accessed on a + // _s_upertype. If the field is static, the super class the access is on can be different and therefore + // we generate a suffix to distinguish access to field with different receiver types in the super hierarchy. + return "p" + if (isStatic && visibility.isProtected) "\$s" + parentAsClass.syntheticAccessorToSuperSuffix() else "" } private val DescriptorVisibility.isPrivate diff --git a/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.kt b/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.kt new file mode 100644 index 0000000000000..b7ff5b7e84040 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.kt @@ -0,0 +1,6 @@ +private val x: String = "OK" +private fun f(y: String) = y + +class A { + fun g() = f(x) +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.txt b/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.txt new file mode 100644 index 0000000000000..4bb382d5e44c7 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.txt @@ -0,0 +1,16 @@ +@kotlin.Metadata +public final class A { + // source: 'accessorForTopLevelMembers.kt' + public method (): void + public final @org.jetbrains.annotations.NotNull method g(): java.lang.String +} + +@kotlin.Metadata +public final class AccessorForTopLevelMembersKt { + // source: 'accessorForTopLevelMembers.kt' + private final static field x: java.lang.String + static method (): void + public synthetic final static method access$f(p0: java.lang.String): java.lang.String + public synthetic final static method access$getX$p(): java.lang.String + private final static method f(p0: java.lang.String): java.lang.String +} diff --git a/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers_ir.txt b/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers_ir.txt new file mode 100644 index 0000000000000..9eb5b4f087f5c --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers_ir.txt @@ -0,0 +1,16 @@ +@kotlin.Metadata +public final class A { + // source: 'accessorForTopLevelMembers.kt' + public method (): void + public final @org.jetbrains.annotations.NotNull method g(): java.lang.String +} + +@kotlin.Metadata +public final class AccessorForTopLevelMembersKt { + // source: 'accessorForTopLevelMembers.kt' + private final static @org.jetbrains.annotations.NotNull field x: java.lang.String + static method (): void + public synthetic final static method access$f(p0: java.lang.String): java.lang.String + public synthetic final static method access$getX$p(): java.lang.String + private final static method f(p0: java.lang.String): java.lang.String +} diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 2f1784db67e6d..9d8ed928865c9 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -35,6 +35,11 @@ public void testAccessorForProtectedPropertyWithPrivateSetterInObjectLiteral() t runTest("compiler/testData/codegen/bytecodeListing/accessorForProtectedPropertyWithPrivateSetterInObjectLiteral.kt"); } + @TestMetadata("accessorForTopLevelMembers.kt") + public void testAccessorForTopLevelMembers() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.kt"); + } + public void testAllFilesPresentInBytecodeListing() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index 64dbef4225602..b5a0319f36ded 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -35,6 +35,11 @@ public void testAccessorForProtectedPropertyWithPrivateSetterInObjectLiteral() t runTest("compiler/testData/codegen/bytecodeListing/accessorForProtectedPropertyWithPrivateSetterInObjectLiteral.kt"); } + @TestMetadata("accessorForTopLevelMembers.kt") + public void testAccessorForTopLevelMembers() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/accessorForTopLevelMembers.kt"); + } + public void testAllFilesPresentInBytecodeListing() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } diff --git a/plugins/parcelize/parcelize-compiler/testData/codegen/customSimple.ir.txt b/plugins/parcelize/parcelize-compiler/testData/codegen/customSimple.ir.txt index d3efd23f1c6e1..a3c900f529f9c 100644 --- a/plugins/parcelize/parcelize-compiler/testData/codegen/customSimple.ir.txt +++ b/plugins/parcelize/parcelize-compiler/testData/codegen/customSimple.ir.txt @@ -41,7 +41,7 @@ public final class User$Creator : java/lang/Object, android/os/Parcelable$Creato ALOAD (1) LDC (parcel) INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V) - INVOKESTATIC (User, access$getCompanion$p$s2645995, ()LUser$Companion;) + INVOKESTATIC (User, access$getCompanion$p, ()LUser$Companion;) ALOAD (1) INVOKEVIRTUAL (User$Companion, create, (Landroid/os/Parcel;)LUser;) ARETURN @@ -90,7 +90,7 @@ public final class User : java/lang/Object, android/os/Parcelable { public void (java.lang.String firstName, java.lang.String lastName, int age) - public final static User$Companion access$getCompanion$p$s2645995() + public final static User$Companion access$getCompanion$p() public int describeContents() diff --git a/plugins/parcelize/parcelize-compiler/testData/codegen/customSimpleWithNewArray.ir.txt b/plugins/parcelize/parcelize-compiler/testData/codegen/customSimpleWithNewArray.ir.txt index 63803c0dca9c7..aed21ea992e88 100644 --- a/plugins/parcelize/parcelize-compiler/testData/codegen/customSimpleWithNewArray.ir.txt +++ b/plugins/parcelize/parcelize-compiler/testData/codegen/customSimpleWithNewArray.ir.txt @@ -40,7 +40,7 @@ public final class User$Creator : java/lang/Object, android/os/Parcelable$Creato public final User[] newArray(int size) { LABEL (L0) - INVOKESTATIC (User, access$getCompanion$p$s2645995, ()LUser$Companion;) + INVOKESTATIC (User, access$getCompanion$p, ()LUser$Companion;) ILOAD (1) INVOKEVIRTUAL (User$Companion, newArray, (I)[LUser;) ARETURN @@ -72,7 +72,7 @@ public final class User : java/lang/Object, android/os/Parcelable { public void (java.lang.String firstName, java.lang.String lastName, int age) - public final static User$Companion access$getCompanion$p$s2645995() + public final static User$Companion access$getCompanion$p() public int describeContents()