From 06d3e1d8bd3a1336ed14225e121047819034b2ae Mon Sep 17 00:00:00 2001 From: Pavel Mikhailovskii Date: Wed, 21 Dec 2022 15:06:07 +0000 Subject: [PATCH] KT-55005 Do not generate CHECKCAST before AASTORE --- .../optimization/OptimizationMethodVisitor.kt | 1 + ...heckcastsBeforeAastoreMethodTransformer.kt | 30 +++++++++++++++++++ .../FirBlackBoxCodegenTestGenerated.java | 6 ++++ .../testData/codegen/box/casts/kt55005.kt | 27 +++++++++++++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++ .../testData/codegen/Basic.asm.ir.txt | 4 --- .../testData/codegen/Basic.asm.txt | 3 -- .../testData/codegen/Sealed.asm.ir.txt | 5 ---- .../testData/codegen/Sealed.asm.txt | 7 ----- 9 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/RedundantCheckcastsBeforeAastoreMethodTransformer.kt create mode 100644 compiler/testData/codegen/box/casts/kt55005.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt index 23c4e371912..7567da7040d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt @@ -61,6 +61,7 @@ class OptimizationMethodVisitor( RedundantGotoMethodTransformer(), RedundantNopsCleanupMethodTransformer(), NegatedJumpsMethodTransformer(), + RedundantCheckcastsBeforeAastoreMethodTransformer, MethodVerifier("AFTER optimizations", generationState) ) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/RedundantCheckcastsBeforeAastoreMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/RedundantCheckcastsBeforeAastoreMethodTransformer.kt new file mode 100644 index 00000000000..bcdc8a284eb --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/RedundantCheckcastsBeforeAastoreMethodTransformer.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.codegen.optimization + +import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.isOperationReifiedMarker +import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer +import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.tree.MethodNode + +object RedundantCheckcastsBeforeAastoreMethodTransformer : MethodTransformer() { + override fun transform(internalClassName: String, methodNode: MethodNode) { + val iter = methodNode.instructions.iterator() + while (iter.hasNext()) { + val insn = iter.next() + if (insn.opcode == Opcodes.CHECKCAST && insn.next?.opcode == Opcodes.AASTORE) { + val isReified = isOperationReifiedMarker(insn.previous) + iter.remove() + if (isReified) { + for (i in 1..3) { + iter.previous() + iter.remove() + } + } + } + } + } +} \ No newline at end of file diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 63c9f9c36ce..deace6babc8 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -4853,6 +4853,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt55005.kt") + public void testKt55005() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt55005.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/compiler/testData/codegen/box/casts/kt55005.kt b/compiler/testData/codegen/box/casts/kt55005.kt new file mode 100644 index 00000000000..0d95eb8563d --- /dev/null +++ b/compiler/testData/codegen/box/casts/kt55005.kt @@ -0,0 +1,27 @@ +// TARGET_BACKEND: JVM_IR +// CHECK_BYTECODE_TEXT +// WITH_STDLIB + +import kotlin.test.* + +inline fun foo(x: Any) = arrayOf(x as T) + +fun box(): String { + val a: Array = arrayOf("") + + assertFailsWith { + (a as Array)[0] = Any() + } + assertFailsWith { + (a as Array)[0] = 1 + } + assertFailsWith { + (a as Array)[0] = StringBuilder() + } + assertFailsWith { + foo(Any()) + } + return "OK" +} + +// 0 CHECKCAST \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 46c3da02d47..0289dffb49d 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -4853,6 +4853,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/casts/kt54802.kt"); } + @Test + @TestMetadata("kt55005.kt") + public void testKt55005() throws Exception { + runTest("compiler/testData/codegen/box/casts/kt55005.kt"); + } + @Test @TestMetadata("lambdaToUnitCast.kt") public void testLambdaToUnitCast() throws Exception { diff --git a/plugins/kotlinx-serialization/testData/codegen/Basic.asm.ir.txt b/plugins/kotlinx-serialization/testData/codegen/Basic.asm.ir.txt index 1eb96801729..8e34eb406ce 100644 --- a/plugins/kotlinx-serialization/testData/codegen/Basic.asm.ir.txt +++ b/plugins/kotlinx-serialization/testData/codegen/Basic.asm.ir.txt @@ -258,7 +258,6 @@ public final class ListOfUsers : java/lang/Object { GETSTATIC (User$$serializer, INSTANCE, LUser$$serializer;) CHECKCAST (kotlinx/serialization/KSerializer) INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, , (Lkotlinx/serialization/KSerializer;)V) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (0) PUTSTATIC (ListOfUsers, $childSerializers, [Lkotlinx/serialization/KSerializer;) @@ -381,7 +380,6 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ ALOAD (1) ICONST_0 GETSTATIC (User$$serializer, INSTANCE, LUser$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (1) ARETURN @@ -760,12 +758,10 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in ALOAD (1) ICONST_0 GETSTATIC (kotlinx/serialization/internal/StringSerializer, INSTANCE, Lkotlinx/serialization/internal/StringSerializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (1) ICONST_1 GETSTATIC (kotlinx/serialization/internal/StringSerializer, INSTANCE, Lkotlinx/serialization/internal/StringSerializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (1) ARETURN diff --git a/plugins/kotlinx-serialization/testData/codegen/Basic.asm.txt b/plugins/kotlinx-serialization/testData/codegen/Basic.asm.txt index 477e52d2007..13bcce71737 100644 --- a/plugins/kotlinx-serialization/testData/codegen/Basic.asm.txt +++ b/plugins/kotlinx-serialization/testData/codegen/Basic.asm.txt @@ -342,7 +342,6 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ DUP ICONST_0 GETSTATIC (User$$serializer, INSTANCE, LUser$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ARETURN LABEL (L1) @@ -696,12 +695,10 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in DUP ICONST_0 GETSTATIC (kotlinx/serialization/internal/StringSerializer, INSTANCE, Lkotlinx/serialization/internal/StringSerializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE DUP ICONST_1 GETSTATIC (kotlinx/serialization/internal/StringSerializer, INSTANCE, Lkotlinx/serialization/internal/StringSerializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ARETURN LABEL (L1) diff --git a/plugins/kotlinx-serialization/testData/codegen/Sealed.asm.ir.txt b/plugins/kotlinx-serialization/testData/codegen/Sealed.asm.ir.txt index 7403f0a9bb5..a59f9ea6e47 100644 --- a/plugins/kotlinx-serialization/testData/codegen/Sealed.asm.ir.txt +++ b/plugins/kotlinx-serialization/testData/codegen/Sealed.asm.ir.txt @@ -346,12 +346,10 @@ final class Result$Companion$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/function ICONST_0 ANEWARRAY (java/lang/annotation/Annotation) INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, , (Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/annotation/Annotation;)V) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (1) ICONST_1 GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (1) ICONST_0 @@ -536,7 +534,6 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati ALOAD (1) ICONST_0 GETSTATIC (kotlinx/serialization/internal/StringSerializer, INSTANCE, Lkotlinx/serialization/internal/StringSerializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (1) ARETURN @@ -863,12 +860,10 @@ public final class X$Companion : java/lang/Object { ICONST_0 ANEWARRAY (java/lang/annotation/Annotation) INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, , (Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/annotation/Annotation;)V) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (1) ICONST_1 GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ALOAD (1) ICONST_0 diff --git a/plugins/kotlinx-serialization/testData/codegen/Sealed.asm.txt b/plugins/kotlinx-serialization/testData/codegen/Sealed.asm.txt index feabd89814c..92e9507a0c3 100644 --- a/plugins/kotlinx-serialization/testData/codegen/Sealed.asm.txt +++ b/plugins/kotlinx-serialization/testData/codegen/Sealed.asm.txt @@ -74,7 +74,6 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati DUP ICONST_1 GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, , (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V) AASTORE @@ -133,7 +132,6 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati DUP ICONST_1 GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, , (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V) ALOAD (5) @@ -187,7 +185,6 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati DUP ICONST_1 GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, , (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V) ALOAD (5) @@ -365,7 +362,6 @@ public final class Container : java/lang/Object { DUP ICONST_1 GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, , (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V) ALOAD (0) @@ -428,7 +424,6 @@ final class Result$Companion$serializer$1 : kotlin/jvm/internal/Lambda, kotlin/j DUP ICONST_1 GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, , (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V) ARETURN @@ -615,7 +610,6 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati DUP ICONST_0 GETSTATIC (kotlinx/serialization/internal/StringSerializer, INSTANCE, Lkotlinx/serialization/internal/StringSerializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE ARETURN LABEL (L1) @@ -931,7 +925,6 @@ public final class X$Companion : java/lang/Object { DUP ICONST_1 GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;) - CHECKCAST (kotlinx/serialization/KSerializer) AASTORE INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, , (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V) ARETURN