From 46f1add2f3b7c6931a7e6f4c137f99da4a98d3c4 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 21 Sep 2015 18:22:14 +0300 Subject: [PATCH] Introduce infrastructure to separate string table from metadata on JVM Nothing especially helpful happens here, this is only a big refactoring introducing a separate string array for the string table, which is currently always empty, but will contain actual strings soon Original commit: 6a8d0fbd75715bfb7c0706961ce752ba80983db1 --- .../jps/incremental/IncrementalCacheImpl.kt | 41 ++++++++++++------- .../jps/incremental/protoDifferenceUtils.kt | 10 ++--- .../AbstractProtoComparisonTest.kt | 11 +++-- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt index 8bfa18534b3..b9f97d84ddc 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache +import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName.byInternalName import org.jetbrains.kotlin.serialization.jvm.BitEncoding @@ -167,7 +168,7 @@ public class IncrementalCacheImpl( public fun saveModuleMappingToCache(sourceFiles: Collection, file: File): ChangesInfo { val jvmClassName = JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME) - protoMap.process(jvmClassName, file.readBytes(), isPackage = false, checkChangesIsOpenPart = false) + protoMap.process(jvmClassName, file.readBytes(), emptyArray(), isPackage = false, checkChangesIsOpenPart = false) dirtyOutputClassesMap.notDirty(MODULE_MAPPING_FILE_NAME) sourceFiles.forEach { sourceToClassesMap.add(it, jvmClassName) } return ChangesInfo.NO_CHANGES @@ -249,8 +250,10 @@ public class IncrementalCacheImpl( return obsoletePackageParts } - override fun getPackagePartData(fqName: String): ByteArray? { - return protoMap[JvmClassName.byInternalName(fqName)]?.bytes + override fun getPackagePartData(fqName: String): JvmPackagePartProto? { + return protoMap[JvmClassName.byInternalName(fqName)]?.let { value -> + JvmPackagePartProto(value.bytes, value.strings) + } } override fun getModuleMappingData(): ByteArray? { @@ -275,19 +278,24 @@ public class IncrementalCacheImpl( public fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean, checkChangesIsOpenPart: Boolean = true): ChangesInfo { val header = kotlinClass.classHeader val bytes = BitEncoding.decodeBytes(header.annotationData!!) - return put(kotlinClass.className, bytes, isPackage, checkChangesIsOpenPart) + return put(kotlinClass.className, bytes, header.strings!!, isPackage, checkChangesIsOpenPart) } - public fun process(className: JvmClassName, data: ByteArray, isPackage: Boolean, checkChangesIsOpenPart: Boolean): ChangesInfo { - return put(className, data, isPackage, checkChangesIsOpenPart) + public fun process(className: JvmClassName, data: ByteArray, strings: Array, isPackage: Boolean, checkChangesIsOpenPart: Boolean): ChangesInfo { + return put(className, data, strings, isPackage, checkChangesIsOpenPart) } - private fun put(className: JvmClassName, bytes: ByteArray, isPackage: Boolean, checkChangesIsOpenPart: Boolean): ChangesInfo { + private fun put( + className: JvmClassName, bytes: ByteArray, strings: Array, isPackage: Boolean, checkChangesIsOpenPart: Boolean + ): ChangesInfo { val key = className.internalName val oldData = storage[key] - val data = ProtoMapValue(isPackage, bytes) + val data = ProtoMapValue(isPackage, bytes, strings) - if (oldData == null || !Arrays.equals(bytes, oldData.bytes) || isPackage != oldData.isPackageFacade) { + if (oldData == null || + !Arrays.equals(bytes, oldData.bytes) || + !Arrays.equals(strings, oldData.strings) || + isPackage != oldData.isPackageFacade) { storage[key] = data } @@ -757,14 +765,19 @@ private object ProtoMapValueExternalizer : DataExternalizer { out.writeBoolean(value.isPackageFacade) out.writeInt(value.bytes.size()) out.write(value.bytes) + out.writeInt(value.strings.size()) + for (string in value.strings) { + out.writeUTF(string) + } } override fun read(`in`: DataInput): ProtoMapValue { val isPackageFacade = `in`.readBoolean() - val length = `in`.readInt() - val buf = ByteArray(length) - `in`.readFully(buf) - return ProtoMapValue(isPackageFacade, buf) + val bytesLength = `in`.readInt() + val bytes = ByteArray(bytesLength) + `in`.readFully(bytes, 0, bytesLength) + val stringsLength = `in`.readInt() + val strings = Array(stringsLength) { `in`.readUTF() } + return ProtoMapValue(isPackageFacade, bytes, strings) } } - diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/protoDifferenceUtils.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/protoDifferenceUtils.kt index 7bc06f13708..4a1508b3c38 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/protoDifferenceUtils.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/protoDifferenceUtils.kt @@ -31,7 +31,7 @@ public sealed class DifferenceKind() { public class MEMBERS(val names: Collection): DifferenceKind() } -data class ProtoMapValue(val isPackageFacade: Boolean, val bytes: ByteArray) +data class ProtoMapValue(val isPackageFacade: Boolean, val bytes: ByteArray, val strings: Array) public fun difference(oldData: ProtoMapValue, newData: ProtoMapValue): DifferenceKind { if (oldData.isPackageFacade != newData.isPackageFacade) return DifferenceKind.CLASS_SIGNATURE @@ -127,8 +127,8 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot ) } - val oldClassData = JvmProtoBufUtil.readClassDataFrom(oldData.bytes) - val newClassData = JvmProtoBufUtil.readClassDataFrom(newData.bytes) + val oldClassData = JvmProtoBufUtil.readClassDataFrom(oldData.bytes, oldData.strings) + val newClassData = JvmProtoBufUtil.readClassDataFrom(newData.bytes, newData.strings) val oldProto = oldClassData.classProto val newProto = newClassData.classProto @@ -217,8 +217,8 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot } private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newData: ProtoMapValue) : DifferenceCalculator() { - val oldPackageData = JvmProtoBufUtil.readPackageDataFrom(oldData.bytes) - val newPackageData = JvmProtoBufUtil.readPackageDataFrom(newData.bytes) + val oldPackageData = JvmProtoBufUtil.readPackageDataFrom(oldData.bytes, oldData.strings) + val newPackageData = JvmProtoBufUtil.readPackageDataFrom(newData.bytes, newData.strings) val oldProto = oldPackageData.packageProto val newProto = newPackageData.packageProto diff --git a/jps/jps-plugin/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt b/jps/jps-plugin/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt index 027be2715da..ce42b21f41b 100644 --- a/jps/jps-plugin/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt +++ b/jps/jps-plugin/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.test.JetTestUtils import org.jetbrains.kotlin.test.MockLibraryUtil import org.jetbrains.kotlin.utils.Printer import java.io.File -import kotlin.test.assertEquals public abstract class AbstractProtoComparisonTest : UsefulTestCase() { @@ -85,8 +84,14 @@ public abstract class AbstractProtoComparisonTest : UsefulTestCase() { val oldProtoBytes = BitEncoding.decodeBytes(oldClassHeader.annotationData!!) val newProtoBytes = BitEncoding.decodeBytes(newClassHeader.annotationData!!) - val oldProto = ProtoMapValue(oldClassHeader.isCompatiblePackageFacadeKind() || oldClassHeader.isCompatibleFileFacadeKind(), oldProtoBytes) - val newProto = ProtoMapValue(newClassHeader.isCompatiblePackageFacadeKind() || newClassHeader.isCompatibleFileFacadeKind(), newProtoBytes) + val oldProto = ProtoMapValue( + oldClassHeader.isCompatiblePackageFacadeKind() || oldClassHeader.isCompatibleFileFacadeKind(), + oldProtoBytes, oldClassHeader.strings!! + ) + val newProto = ProtoMapValue( + newClassHeader.isCompatiblePackageFacadeKind() || newClassHeader.isCompatibleFileFacadeKind(), + newProtoBytes, newClassHeader.strings!! + ) val diff = when { newClassHeader.isCompatiblePackageFacadeKind(), newClassHeader.isCompatibleClassKind(), newClassHeader.isCompatibleFileFacadeKind() ->