From 41e38d5a1aab36923b408716e0c3473fd92a924c Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Tue, 21 Sep 2021 17:27:23 +0300 Subject: [PATCH] JVM_IR: move serialized IR to a separate annotation --- .../backend/jvm/codegen/ClassCodegen.kt | 23 +++---- .../kotlin/load/java/JvmAnnotationNames.java | 5 +- ...eadKotlinClassHeaderAnnotationVisitor.java | 62 +++++++++++++++---- .../kotlin/jvm/internal/SerializedIr.kt | 17 +++++ .../kotlin-stdlib-runtime-merged.txt | 4 ++ 5 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 libraries/stdlib/jvm/runtime/kotlin/jvm/internal/SerializedIr.kt 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 77abd551a56..e44212cf8f4 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 @@ -300,9 +300,8 @@ class ClassCodegen private constructor( assert(isFileClass) { "JvmPackageName is not supported for classes: ${irClass.render()}" } av.visit(JvmAnnotationNames.METADATA_PACKAGE_NAME_FIELD_NAME, irClass.fqNameWhenAvailable!!.parent().asString()) } - - serializedIr?.let { storeSerializedIr(av, it) } } + serializedIr?.let { storeSerializedIr(it) } } private fun IrFile.loadSourceFilesInfo(): List { @@ -499,6 +498,17 @@ class ClassCodegen private constructor( OtherOrigin(psiElement, toIrBasedDescriptor()) } + private fun storeSerializedIr(serializedIr: ByteArray) { + val av = visitor.newAnnotation(JvmAnnotationNames.SERIALIZED_IR_DESC, true) + val partsVisitor = av.visitArray(JvmAnnotationNames.SERIALIZED_IR_BYTES_FIELD_NAME) + val serializedIrParts = BitEncoding.encodeBytes(serializedIr) + for (part in serializedIrParts) { + partsVisitor.visit(null, part) + } + partsVisitor.visitEnd() + av.visitEnd() + } + companion object { fun getOrCreate( irClass: IrClass, @@ -584,15 +594,6 @@ private val Modality.flags: Int private val DescriptorVisibility.flags: Int get() = DescriptorAsmUtil.getVisibilityAccessFlag(this) ?: throw AssertionError("Unsupported visibility $this") -private fun storeSerializedIr(av: AnnotationVisitor, serializedIr: ByteArray) { - val serializedIrParts = BitEncoding.encodeBytes(serializedIr) - val partsVisitor = av.visitArray(JvmAnnotationNames.METADATA_SERIALIZED_IR_FIELD_NAME) - for (part in serializedIrParts) { - partsVisitor.visit(null, part) - } - partsVisitor.visitEnd() -} - // From `isAnonymousClass` in inlineCodegenUtils.kt private val Type.isAnonymousClass: Boolean get() = internalName.substringAfterLast("$", "").toIntOrNull() != null diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java index 3f3e759d250..c9d636fb7a8 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java @@ -35,7 +35,6 @@ public final class JvmAnnotationNames { public static final String METADATA_PACKAGE_NAME_FIELD_NAME = "pn"; public static final String METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME = METADATA_EXTRA_STRING_FIELD_NAME; public static final String METADATA_EXTRA_INT_FIELD_NAME = "xi"; - public static final String METADATA_SERIALIZED_IR_FIELD_NAME = "si"; public static final int METADATA_MULTIFILE_PARTS_INHERIT_FLAG = 1 << 0; public static final int METADATA_PRE_RELEASE_FLAG = 1 << 1; @@ -68,6 +67,10 @@ public final class JvmAnnotationNames { public static final FqName KOTLIN_JVM_INTERNAL = new FqName("kotlin.jvm.internal"); + public static final FqName SERIALIZED_IR_FQ_NAME = new FqName("kotlin.jvm.internal.SerializedIr"); + public static final String SERIALIZED_IR_DESC = "L" + JvmClassName.byFqNameWithoutInnerClasses(SERIALIZED_IR_FQ_NAME).getInternalName() + ";"; + public static final String SERIALIZED_IR_BYTES_FIELD_NAME = "b"; + // Just for internal use: there is no such real classes in bytecode public static final FqName ENHANCED_NULLABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedNullability"); public static final FqName ENHANCED_MUTABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedMutability"); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java index 6d93e07c128..f79ea59f7a6 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java @@ -110,6 +110,9 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor if (fqName.equals(METADATA_FQ_NAME)) { return new KotlinMetadataArgumentVisitor(); } + if (fqName.equals(SERIALIZED_IR_FQ_NAME)) { + return new KotlinSerializedIrArgumentVisitor(); + } if (IGNORE_OLD_METADATA) return null; @@ -178,9 +181,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor else if (METADATA_STRINGS_FIELD_NAME.equals(string)) { return stringsArrayVisitor(); } - else if (METADATA_SERIALIZED_IR_FIELD_NAME.equals(string)) { - return serializedIrArrayVisitor(); - } else { return null; } @@ -206,16 +206,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor }; } - @NotNull - private AnnotationArrayArgumentVisitor serializedIrArrayVisitor() { - return new CollectStringArrayAnnotationVisitor() { - @Override - protected void visitEnd(@NotNull String[] result) { - serializedIrFields = result; - } - }; - } - @Override public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) { } @@ -301,6 +291,52 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor } } + private class KotlinSerializedIrArgumentVisitor implements AnnotationArgumentVisitor { + @Override + public void visit(@Nullable Name name, @Nullable Object value) { + } + + @Override + public void visitClassLiteral(@NotNull Name name, @NotNull ClassLiteralValue classLiteralValue) { + } + + @Override + @Nullable + public AnnotationArrayArgumentVisitor visitArray(@NotNull Name name) { + String string = name.asString(); + if (SERIALIZED_IR_BYTES_FIELD_NAME.equals(string)) { + return serializedIrArrayVisitor(); + } + else { + return null; + } + } + + @NotNull + private AnnotationArrayArgumentVisitor serializedIrArrayVisitor() { + return new CollectStringArrayAnnotationVisitor() { + @Override + protected void visitEnd(@NotNull String[] result) { + serializedIrFields = result; + } + }; + } + + @Override + public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) { + } + + @Nullable + @Override + public AnnotationArgumentVisitor visitAnnotation(@NotNull Name name, @NotNull ClassId classId) { + return null; + } + + @Override + public void visitEnd() { + } + } + private abstract static class CollectStringArrayAnnotationVisitor implements AnnotationArrayArgumentVisitor { private final List strings; diff --git a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/SerializedIr.kt b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/SerializedIr.kt new file mode 100644 index 00000000000..d2424887887 --- /dev/null +++ b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/SerializedIr.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2021 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 kotlin.jvm.internal + +/** + * This annotation is used to store serialized IR data inside classfiles. + */ +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.CLASS) +@SinceKotlin("1.6") +annotation class SerializedIr( + @get:JvmName("b") + val bytes: Array = [] +) diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt index fb13f3700eb..c2d2e773ea5 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt @@ -4038,6 +4038,10 @@ public class kotlin/jvm/internal/ReflectionFactory { public abstract interface annotation class kotlin/jvm/internal/RepeatableContainer : java/lang/annotation/Annotation { } +public abstract interface annotation class kotlin/jvm/internal/SerializedIr : java/lang/annotation/Annotation { + public abstract fun b ()[Ljava/lang/String; +} + public final class kotlin/jvm/internal/ShortCompanionObject { public static final field INSTANCE Lkotlin/jvm/internal/ShortCompanionObject; public static final field MAX_VALUE S