From 353bfe901872313501b966266f451e8e313f35ee Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Mon, 20 Dec 2021 22:05:26 +0300 Subject: [PATCH] [JS IR] Cleanup pir IC code --- .../common/arguments/K2JSCompilerArguments.kt | 3 - .../jetbrains/kotlin/cli/js/K2JsIrCompiler.kt | 35 +-- .../kotlin/ir/backend/js/compiler.kt | 73 +---- .../kotlin/ir/backend/js/ic/fileUtil.kt | 125 -------- .../jetbrains/kotlin/ir/backend/js/ic/ic.kt | 242 ---------------- .../kotlin/ir/backend/js/ic/invalidation.kt | 2 +- .../kotlin/ir/backend/js/ic/CacheAccessors.kt | 23 +- .../ir/backend/js/ic/IcFileDeserializer.kt | 268 ----------------- .../ir/backend/js/ic/IcModuleDeserializer.kt | 269 ------------------ .../kotlin/ir/backend/js/ic/IcSerializer.kt | 179 ------------ .../jetbrains/kotlin/ir/backend/js/ic/data.kt | 125 -------- .../jetbrains/kotlin/ir/backend/js/klib.kt | 100 +------ .../js/lower/serialization/ir/JsIrLinker.kt | 28 -- compiler/testData/cli/js/jsExtraHelp.out | 1 - .../JsEnvironmentConfigurationDirectives.kt | 5 - .../kotlin/klib/AbstractKlibTextTestCase.kt | 4 +- .../js/test/AbstractJsKLibABITestCase.kt | 4 +- .../js/test/converters/JsIrBackendFacade.kt | 15 +- .../kotlin/js/test/ir/AbstractJsIrTest.kt | 1 - .../test/utils/JsIrIncrementalDataProvider.kt | 8 - .../jetbrains/kotlin/js/testOld/ApiTest.kt | 5 +- 21 files changed, 27 insertions(+), 1488 deletions(-) delete mode 100644 compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ic.kt delete mode 100644 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcFileDeserializer.kt delete mode 100644 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcModuleDeserializer.kt delete mode 100644 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcSerializer.kt delete mode 100644 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/data.kt diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt index d0c9867def9..d8d0ca6fe1f 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt @@ -132,9 +132,6 @@ class K2JSCompilerArguments : CommonCompilerArguments() { ) var irDceRuntimeDiagnostic: String? by NullableStringFreezableVar(null) - @Argument(value = "-Xir-dce-driven", description = "Perform a more experimental faster dead code elimination") - var irDceDriven: Boolean by FreezableVar(false) - @Argument(value = "-Xir-dce-print-reachability-info", description = "Print declarations' reachability info to stdout during performing DCE") var irDcePrintReachabilityInfo: Boolean by FreezableVar(false) diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 3f53ce1ecb0..99afaaef00a 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -40,14 +40,15 @@ import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity -import org.jetbrains.kotlin.ir.backend.js.ic.* +import org.jetbrains.kotlin.ir.backend.js.ic.actualizeCacheForModule +import org.jetbrains.kotlin.ir.backend.js.ic.buildCacheForModuleFiles +import org.jetbrains.kotlin.ir.backend.js.ic.loadModuleCaches import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformerTmp import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.SourceMapsInfo import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC -import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult import org.jetbrains.kotlin.js.config.* import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION @@ -78,13 +79,6 @@ class K2JsIrCompiler : CLICompiler() { return K2JSCompilerArguments() } - @Suppress("UNUSED_PARAMETER") - private fun usePerFileInvalidator(configuration: CompilerConfiguration): Boolean = true - - private fun IcCacheInfo.toICCacheMap(): Map { - return data.map { it.key to ICCache(PersistentCacheProvider.EMPTY, PersistentCacheConsumer.EMPTY, it.value) }.toMap() - } - override fun doExecute( arguments: K2JSCompilerArguments, configuration: CompilerConfiguration, @@ -184,10 +178,7 @@ class K2JsIrCompiler : CLICompiler() { val outputFile = File(outputFilePath) val moduleName = arguments.irModuleName ?: FileUtil.getNameWithoutExtension(outputFile) - configurationJs.put( - CommonConfigurationKeys.MODULE_NAME, - moduleName - ) + configurationJs.put(CommonConfigurationKeys.MODULE_NAME, moduleName) // TODO: in this method at least 3 different compiler configurations are used (original, env.configuration, jsConfig.configuration) // Such situation seems a bit buggy... @@ -246,10 +237,7 @@ class K2JsIrCompiler : CLICompiler() { configurationJs, libraries, friendLibraries, - AnalyzerWithCompilerReport(config.configuration), - icUseGlobalSignatures = icCaches.isNotEmpty(), - icUseStdlibCache = icCaches.isNotEmpty(), - icCache = if (icCaches.isNotEmpty()) checkCaches(libraries, icCaches, skipLib = includes).toICCacheMap() else emptyMap() + AnalyzerWithCompilerReport(config.configuration) ) val result = sourceModule.jsFrontEndResult.jsAnalysisResult if (result is JsAnalysisResult.RetryWithAdditionalRoots) { @@ -323,10 +311,7 @@ class K2JsIrCompiler : CLICompiler() { kLib, configurationJs, libraries, - friendLibraries, - icUseGlobalSignatures = icCaches.isNotEmpty(), - icUseStdlibCache = icCaches.isNotEmpty(), - icCache = if (icCaches.isNotEmpty()) checkCaches(libraries, icCaches, skipLib = includes).toICCacheMap() else emptyMap() + friendLibraries ) } else { sourceModule @@ -389,7 +374,6 @@ class K2JsIrCompiler : CLICompiler() { } try { val irFactory = when { - arguments.irDceDriven -> PersistentIrFactory() arguments.irNewIr2Js -> IrFactoryImplForJsIC(WholeWorldStageController()) else -> IrFactoryImpl } @@ -402,7 +386,6 @@ class K2JsIrCompiler : CLICompiler() { arguments.irDceRuntimeDiagnostic, messageCollector ), - dceDriven = arguments.irDceDriven, propertyLazyInitialization = arguments.irPropertyLazyInitialization, baseClassIntoMetadata = arguments.irBaseClassInMetadata, safeExternalBoolean = arguments.irSafeExternalBoolean, @@ -410,7 +393,6 @@ class K2JsIrCompiler : CLICompiler() { arguments.irSafeExternalBooleanDiagnostic, messageCollector ), - lowerPerModule = false,//icCaches.isNotEmpty(), granularity = granularity, icCompatibleIr2Js = arguments.irNewIr2Js, ) @@ -597,11 +579,6 @@ class K2JsIrCompiler : CLICompiler() { K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_NEVER to SourceMapSourceEmbedding.NEVER, K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_INLINING to SourceMapSourceEmbedding.INLINING ) - private val produceMap = mapOf( - null to ProduceKind.DEFAULT, - "js" to ProduceKind.JS, - "klib" to ProduceKind.KLIB - ) @JvmStatic fun main(args: Array) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index b14ad5a5eb0..d08048660b1 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -5,13 +5,11 @@ package org.jetbrains.kotlin.ir.backend.js -import org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity -import org.jetbrains.kotlin.ir.backend.js.ic.icCompile import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker @@ -20,8 +18,6 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode import org.jetbrains.kotlin.ir.backend.js.utils.NameTables import org.jetbrains.kotlin.ir.declarations.IrFactory import org.jetbrains.kotlin.ir.declarations.IrModuleFragment -import org.jetbrains.kotlin.ir.declarations.StageController -import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.noUnboundLeft @@ -53,13 +49,11 @@ fun compile( phaseConfig: PhaseConfig, irFactory: IrFactory, exportedDeclarations: Set = emptySet(), - dceDriven: Boolean = false, dceRuntimeDiagnostic: RuntimeDiagnostic? = null, es6mode: Boolean = false, propertyLazyInitialization: Boolean, verifySignatures: Boolean = true, baseClassIntoMetadata: Boolean = false, - lowerPerModule: Boolean = false, safeExternalBoolean: Boolean = false, safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null, filesToLower: Set? = null, @@ -67,20 +61,7 @@ fun compile( icCompatibleIr2Js: Boolean = false, ): LoweredIr { - if (lowerPerModule) { - return icCompile( - depsDescriptors, - exportedDeclarations, - dceRuntimeDiagnostic, - es6mode, - propertyLazyInitialization, - baseClassIntoMetadata, - safeExternalBoolean, - safeExternalBooleanDiagnostic, - ) - } - - val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer, _) = + val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) = loadIr(depsDescriptors, irFactory, verifySignatures, filesToLower, loadFunctionInterfacesIntoStdlib = true) return compileIr( @@ -93,12 +74,10 @@ fun compile( deserializer, phaseConfig, exportedDeclarations, - dceDriven, dceRuntimeDiagnostic, es6mode, propertyLazyInitialization, baseClassIntoMetadata, - lowerPerModule, safeExternalBoolean, safeExternalBooleanDiagnostic, granularity, @@ -116,12 +95,10 @@ fun compileIr( deserializer: JsIrLinker, phaseConfig: PhaseConfig, exportedDeclarations: Set, - dceDriven: Boolean, dceRuntimeDiagnostic: RuntimeDiagnostic?, es6mode: Boolean, propertyLazyInitialization: Boolean, baseClassIntoMetadata: Boolean, - lowerPerModule: Boolean, safeExternalBoolean: Boolean, safeExternalBooleanDiagnostic: RuntimeDiagnostic?, granularity: JsGenerationGranularity, @@ -170,55 +147,13 @@ fun compileIr( // TODO should be done incrementally generateJsTests(context, allModules.last()) - if (dceDriven) { - val controller = MutableController(context, pirLowerings) - - check(irFactory is PersistentIrFactory) - irFactory.stageController = controller - - controller.currentStage = controller.lowerings.size + 1 - - eliminateDeadDeclarations(allModules, context) - - irFactory.stageController = StageController(controller.currentStage) - } else { - // TODO is this reachable when lowerPerModule == true? - if (lowerPerModule) { - val controller = WholeWorldStageController() - check(irFactory is PersistentIrFactory) - irFactory.stageController = controller - allModules.forEach { - lowerPreservingIcData(it, context, controller) - } - irFactory.stageController = object : StageController(irFactory.stageController.currentStage) {} - } else { - (irFactory.stageController as? WholeWorldStageController)?.let { - lowerPreservingTags(allModules, context, phaseConfig, it) - } ?: jsPhases.invokeToplevel(phaseConfig, context, allModules) - } - } + (irFactory.stageController as? WholeWorldStageController)?.let { + lowerPreservingTags(allModules, context, phaseConfig, it) + } ?: jsPhases.invokeToplevel(phaseConfig, context, allModules) return LoweredIr(context, moduleFragment, allModules) } -fun lowerPreservingIcData(module: IrModuleFragment, context: JsIrBackendContext, controller: WholeWorldStageController) { - // Lower all the things - controller.currentStage = 0 - - pirLowerings.forEachIndexed { i, lowering -> - controller.currentStage = i + 1 - when (lowering) { - is DeclarationLowering -> - lowering.declarationTransformer(context).lower(module) - is BodyLowering -> - lowering.bodyLowering(context).lower(module) - is ModuleLowering -> { /*TODO what about other lowerings? */ } - } - } - - controller.currentStage = pirLowerings.size + 1 -} - fun generateJsCode( context: JsIrBackendContext, moduleFragment: IrModuleFragment, diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/fileUtil.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/fileUtil.kt index edbe482b793..7b00286fa64 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/fileUtil.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/fileUtil.kt @@ -5,123 +5,8 @@ package org.jetbrains.kotlin.ir.backend.js.ic -import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.ir.backend.js.MainModule -import org.jetbrains.kotlin.ir.backend.js.toByteArray -import org.jetbrains.kotlin.name.FqName import java.io.File import java.io.PrintWriter -import java.security.MessageDigest -import kotlin.random.Random -import kotlin.random.nextULong - -// TODO: Proper version of the compiler (should take changes to lowerings into account) -private val compilerVersion = Random.nextULong() - -private fun IcCacheInfo.toICCacheMap(): Map { - return data.map { it.key to ICCache(PersistentCacheProvider.EMPTY, PersistentCacheConsumer.EMPTY, it.value) }.toMap() -} - -// TODO more parameters for lowerings -// Returns true if caches were built. False if caches were up-to-date. -fun buildCache( - cachePath: String, - project: Project, - mainModule: MainModule.Klib, - configuration: CompilerConfiguration, - dependencies: Collection, - friendDependencies: Collection, - exportedDeclarations: Set = emptySet(), - forceClean: Boolean = false, - icCache: IcCacheInfo = IcCacheInfo.EMPTY, -): Boolean { - val dependencyHashes = dependencies.mapNotNull { - val path = File(it).canonicalPath - icCache.md5[path] - } + compilerVersion - - val md5 = File(mainModule.libPath).md5(dependencyHashes) - - if (!forceClean) { - val oldCacheInfo = CacheInfo.load(cachePath) - if (oldCacheInfo != null && md5 == oldCacheInfo.flatHash) return false - } - - val icDir = File(cachePath) - icDir.listFiles { file: File -> file.name.startsWith("ic-") }!!.forEach { it.deleteRecursively() } - File(icDir, "info").delete() - icDir.mkdirs() - - val icData = prepareSingleLibraryIcCache(project, configuration, mainModule.libPath, dependencies, friendDependencies, exportedDeclarations, icCache.toICCacheMap()) - - icData.serializedIcData.writeTo(File(cachePath)) - - CacheInfo(cachePath, mainModule.libPath, md5, 0UL).save() - - return true -} - -private fun File.md5(additional: Iterable = emptyList()): ULong { - val md5 = MessageDigest.getInstance("MD5") - - for (ul in additional) { - md5.update(ul.toLong().toByteArray()) - } - - fun File.process(prefix: String = "") { - if (isDirectory) { - this.listFiles()!!.sortedBy { it.name }.forEach { - md5.update((prefix + it.name).toByteArray()) - it.process(prefix + it.name + "/") - } - } else { - md5.update(readBytes()) - } - } - - this.process() - - val d = md5.digest() - - return ((d[0].toULong() and 0xFFUL) - or ((d[1].toULong() and 0xFFUL) shl 8) - or ((d[2].toULong() and 0xFFUL) shl 16) - or ((d[3].toULong() and 0xFFUL) shl 24) - or ((d[4].toULong() and 0xFFUL) shl 32) - or ((d[5].toULong() and 0xFFUL) shl 40) - or ((d[6].toULong() and 0xFFUL) shl 48) - or ((d[7].toULong() and 0xFFUL) shl 56) - ) -} - -fun checkCaches( - dependencies: Collection, - cachePaths: List, - skipLib: String? = null, -): IcCacheInfo { - val skipLibPath = File(skipLib).canonicalPath - val allLibs = dependencies.map { File(it).canonicalPath }.toSet() - skipLibPath - - val caches = cachePaths.map { CacheInfo.load(it) ?: error("Cannot load IC cache from ${it}") } - - val missedLibs = allLibs - caches.map { it.libPath } - if (!missedLibs.isEmpty()) { - error("Missing caches for libraries: ${missedLibs}") - } - - val result = mutableMapOf() - val md5 = mutableMapOf() - - for (c in caches) { - if (c.libPath !in allLibs) error("Missing library: ${c.libPath}") - - result[c.libPath] = File(c.path).readIcData() - md5[c.libPath] = c.flatHash - } - - return IcCacheInfo(result, md5) -} // TODO md5 hash data class CacheInfo(val path: String, val libPath: String, var flatHash: ULong, var transHash: ULong) { @@ -145,13 +30,3 @@ data class CacheInfo(val path: String, val libPath: String, var flatHash: ULong, } } } - - -class IcCacheInfo( - val data: Map, - val md5: Map, -) { - companion object { - val EMPTY = IcCacheInfo(emptyMap(), emptyMap()) - } -} \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ic.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ic.kt deleted file mode 100644 index 2233c97e234..00000000000 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ic.kt +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2010-2020 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.ir.backend.js.ic - -import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.backend.common.lower -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.ir.backend.js.* -import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests -import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace -import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment -import org.jetbrains.kotlin.ir.declarations.path -import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory -import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator -import org.jetbrains.kotlin.ir.util.KotlinLikeDumpOptions -import org.jetbrains.kotlin.ir.util.dumpKotlinLike -import org.jetbrains.kotlin.ir.util.noUnboundLeft -import org.jetbrains.kotlin.js.config.RuntimeDiagnostic -import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary -import org.jetbrains.kotlin.name.FqName -import java.io.PrintWriter - -fun prepareSingleLibraryIcCache( - project: Project, - configuration: CompilerConfiguration, - libPath: String, - dependencies: Collection, - friendDependencies: Collection = emptyList(), - exportedDeclarations: Set = emptySet(), - icCache: Map = emptyMap(), -): ICCache { - val irFactory = PersistentIrFactory() - val controller = WholeWorldStageController() - irFactory.stageController = controller - - val depsDescriptor = ModulesStructure( - project, - MainModule.Klib(libPath), - configuration, - dependencies, - friendDependencies, - true, - true, - icCache - ) - val (context, deserializer, allModules) = prepareIr( - depsDescriptor, - exportedDeclarations, - null, - false, - false, - irFactory, - ) - - val moduleFragment = allModules.last() - - moveBodilessDeclarationsToSeparatePlace(context, moduleFragment) - -// generateTests(context, moduleFragment) - - lowerPreservingIcData(moduleFragment, context, controller) - - return ICCache( - PersistentCacheProvider.EMPTY, - PersistentCacheConsumer.EMPTY, - IcSerializer( - context.irBuiltIns, - context.mapping, - irFactory, - deserializer, - moduleFragment - ).serializeDeclarations(irFactory.allDeclarations) - ) -} - -private fun KotlinResolvedLibrary.allDependencies(): List { - val visited = mutableSetOf() - - val result = mutableListOf() - - fun KotlinResolvedLibrary.dfs() { - visited += this - - resolvedDependencies.forEach { - if (it !in visited) { - it.dfs() - result += it - } - } - } - - dfs() - - return result -} - -private fun dumpIr(module: IrModuleFragment, fileName: String) { - val dumpOptions = KotlinLikeDumpOptions(printElseAsTrue = true) - - var actual = "" - - for (file in module.files) { - actual += file.path + "\n" - actual += run { - var r = "" - - file.declarations.map { it.dumpKotlinLike(dumpOptions) }.sorted().forEach { r += it } - - r - } - actual += "\n" - } - PrintWriter("/home/ab/vcs/kotlin/$fileName.txt").use { - it.print(actual) - } -} - -fun icCompile( - depsDescriptor: ModulesStructure, - exportedDeclarations: Set = emptySet(), - dceRuntimeDiagnostic: RuntimeDiagnostic? = null, - es6mode: Boolean = false, - propertyLazyInitialization: Boolean, - baseClassIntoMetadata: Boolean = false, - safeExternalBoolean: Boolean = false, - safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null, -): LoweredIr { - - val irFactory = PersistentIrFactory() - val controller = WholeWorldStageController() - irFactory.stageController = controller - - val (context, _, allModules, _, loweredIrLoaded) = prepareIr( - depsDescriptor, - exportedDeclarations, - dceRuntimeDiagnostic, - es6mode, - propertyLazyInitialization, - irFactory, - baseClassIntoMetadata, - safeExternalBoolean, - safeExternalBooleanDiagnostic - ) - - val modulesToLower = allModules.filter { it !in loweredIrLoaded } - - if (!modulesToLower.isEmpty()) { - // This won't work incrementally - modulesToLower.forEach { module -> - moveBodilessDeclarationsToSeparatePlace(context, module) - } - - generateJsTests(context, modulesToLower.last()) - - modulesToLower.forEach { - lowerPreservingIcData(it, context, controller) - } - } - -// dumpIr(allModules.first(), "simple-dump${if (useStdlibCache) "-actual" else ""}") - - return LoweredIr(context, allModules.last(), allModules) -} - -fun lowerPreservingIcData(module: IrModuleFragment, context: JsIrBackendContext, controller: WholeWorldStageController) { - // Lower all the things - controller.currentStage = 0 - - pirLowerings.forEachIndexed { i, lowering -> - controller.currentStage = i + 1 - when (lowering) { - is DeclarationLowering -> - lowering.declarationTransformer(context).lower(module) - is BodyLowering -> - lowering.bodyLowering(context).lower(module) - else -> TODO("what about other lowerings?") - } - } - - controller.currentStage = pirLowerings.size + 1 -} - -private fun prepareIr( - depsDescriptor: ModulesStructure, - exportedDeclarations: Set = emptySet(), - dceRuntimeDiagnostic: RuntimeDiagnostic? = null, - es6mode: Boolean = false, - propertyLazyInitialization: Boolean, - irFactory: PersistentIrFactory, - baseClassIntoMetadata: Boolean = false, - safeExternalBoolean: Boolean = false, - safeExternalBooleanDiagnostic: RuntimeDiagnostic? = null, -): PreparedIr { - val (moduleFragment: IrModuleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer, moduleToName, loweredIrLoaded) = - loadIr(depsDescriptor, irFactory, false) - - val moduleDescriptor = moduleFragment.descriptor - - val allModules = when (depsDescriptor.mainModule) { - is MainModule.SourceFiles -> dependencyModules + listOf(moduleFragment) - is MainModule.Klib -> dependencyModules - } - - val context = JsIrBackendContext( - moduleDescriptor, - irBuiltIns, - symbolTable, - allModules.first(), - exportedDeclarations, - depsDescriptor.compilerConfiguration, - es6mode = es6mode, - dceRuntimeDiagnostic = dceRuntimeDiagnostic, - propertyLazyInitialization = propertyLazyInitialization, - baseClassIntoMetadata = baseClassIntoMetadata, - safeExternalBoolean = safeExternalBoolean, - safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic, - mapping = deserializer.mapping, - ) - - // Load declarations referenced during `context` initialization - val irProviders = listOf(deserializer) - ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies() - - deserializer.postProcess() - symbolTable.noUnboundLeft("Unbound symbols at the end of linker") - - deserializer.loadIcIr { moveBodilessDeclarationsToSeparatePlace(context, it) } - - return PreparedIr(context, deserializer, allModules, moduleToName, loweredIrLoaded) -} - -data class PreparedIr( - val context: JsIrBackendContext, - val linker: JsIrLinker, - val allModules: List, - val moduleToName: Map, - val loweredIrLoaded: Set, -) \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/invalidation.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/invalidation.kt index 37989cc1f04..8c709229142 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/invalidation.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/invalidation.kt @@ -252,7 +252,7 @@ private fun createLinker( val moduleDescriptor = loadedModules.keys.last() val typeTranslator = TypeTranslatorImpl(symbolTable, configuration.languageVersionSettings, moduleDescriptor) val irBuiltIns = IrBuiltInsOverDescriptors(moduleDescriptor.builtIns, typeTranslator, symbolTable) - return JsIrLinker(null, logger, irBuiltIns, symbolTable, null, null) + return JsIrLinker(null, logger, irBuiltIns, symbolTable, null) } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheAccessors.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheAccessors.kt index 7bc53113848..9aac53944e4 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheAccessors.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheAccessors.kt @@ -28,7 +28,7 @@ private fun ByteArray.toHex(): String = joinToString(separator = "") { eachByte private fun createFileCacheId(fileName: String): String = md5.digest(fileName.encodeToByteArray()).toHex() -class ICCache(val dataProvider: PersistentCacheProvider, val dataConsumer: PersistentCacheConsumer, val serializedIcData: SerializedIcData) +class ICCache() class FileCache(val name: String, var ast: ByteArray?, var dts: ByteArray?, var sourceMap: ByteArray?) class ModuleCache(val name: String, val asts: Map) @@ -36,8 +36,6 @@ class ModuleCache(val name: String, val asts: Map) interface PersistentCacheProvider { fun fileFingerPrint(path: String): Hash - fun serializedParts(path: String): SerializedIcDataForFile - fun inlineGraphForFile(path: String, sigResolver: (Int) -> IdSignature): Collection> fun inlineHashes(path: String, sigResolver: (Int) -> IdSignature): Map @@ -60,10 +58,6 @@ interface PersistentCacheProvider { return 0 } - override fun serializedParts(path: String): SerializedIcDataForFile { - TODO("..") - } - override fun inlineGraphForFile(path: String, sigResolver: (Int) -> IdSignature): Collection> { return emptyList() } @@ -116,11 +110,6 @@ class PersistentCacheProviderImpl(private val cachePath: String) : PersistentCac } else 0 } - override fun serializedParts(path: String): SerializedIcDataForFile { - val fileDir = path.fileDir - return fileDir.readIcDataBinary() - } - private fun parseHashList( fileDir: File, fileName: String, @@ -209,7 +198,6 @@ interface PersistentCacheConsumer { fun commitInlineFunctions(path: String, hashes: Collection>, sigResolver: (IdSignature) -> Int) fun commitFileFingerPrint(path: String, fingerprint: Hash) fun commitInlineGraph(path: String, hashes: Collection>, sigResolver: (IdSignature) -> Int) - fun commitICCacheData(path: String, icData: SerializedIcDataForFile) fun commitBinaryAst(path: String, astData: ByteArray) fun commitBinaryDts(path: String, dstData: ByteArray) fun commitSourceMap(path: String, mapData: ByteArray) @@ -236,9 +224,6 @@ interface PersistentCacheConsumer { ) { } - override fun commitICCacheData(path: String, icData: SerializedIcDataForFile) { - } - override fun invalidateForFile(path: String) { } @@ -306,12 +291,6 @@ class PersistentCacheConsumerImpl(private val cachePath: String) : PersistentCac commitFileHashMapping(path, inlineGraphFile, hashes, sigResolver) } - override fun commitICCacheData(path: String, icData: SerializedIcDataForFile) { - val fileId = createFileCacheId(path) - val fileDir = File(File(cachePath), fileId) - icData.writeData(fileDir) - } - override fun invalidateForFile(path: String) { val fileId = createFileCacheId(path) val cacheDir = File(cachePath) diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcFileDeserializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcFileDeserializer.kt deleted file mode 100644 index 08f5ad729fc..00000000000 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcFileDeserializer.kt +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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 org.jetbrains.kotlin.ir.backend.js.ic - -import org.jetbrains.kotlin.backend.common.overrides.DefaultFakeOverrideClassFilter -import org.jetbrains.kotlin.backend.common.serialization.* -import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData -import org.jetbrains.kotlin.ir.backend.js.JsMappingState -import org.jetbrains.kotlin.ir.backend.js.JsStatementOrigins -import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl -import org.jetbrains.kotlin.ir.serialization.CarrierDeserializer -import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.library.SerializedIrFile -import org.jetbrains.kotlin.library.impl.DeclarationId -import org.jetbrains.kotlin.library.impl.DeclarationIrTableMemoryReader -import org.jetbrains.kotlin.library.impl.IrArrayMemoryReader -import org.jetbrains.kotlin.library.impl.IrLongArrayMemoryReader -import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite -import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoIrFile - -class IcFileDeserializer( - val linker: JsIrLinker, - private val file: IrFile, - originalFileReader: IrLibraryFileFromBytes, - fileProto: ProtoIrFile, - deserializeBodies: Boolean, - allowErrorNodes: Boolean, - deserializeInlineFunctions: Boolean, - val moduleDeserializer: IrModuleDeserializer, - val originalEnqueue: IdSignature.(IcFileDeserializer) -> Unit, - val icFileData: SerializedIcDataForFile, - val mappingState: JsMappingState, - val enqueue: IdSignature.(IcFileDeserializer) -> Unit, -) { - - private val deserializedSymbols = mutableMapOf() - val originalSymbolDeserializer = - IrSymbolDeserializer( - linker.symbolTable, - originalFileReader, - file.symbol, - fileProto.actualList, - { idSig -> - idSig.enqueue(this) - if (idSig.hasTopLevel) { - idSig.topLevelSignature().originalEnqueue(this) - } - }, - linker::handleExpectActualMapping, - enqueueAllDeclarations = true, - deserializedSymbols = deserializedSymbols, - deserializePublicSymbol = ::deserializePublicSymbol - ) - - private val originalDeclarationDeserializer = IrDeclarationDeserializer( - linker.builtIns, - linker.symbolTable, - linker.symbolTable.irFactory, - originalFileReader, - file, - allowErrorNodes, - deserializeInlineFunctions, - deserializeBodies, - originalSymbolDeserializer, - linker.fakeOverrideBuilder.platformSpecificClassFilter, - linker.fakeOverrideBuilder, - allowRedeclaration = true, - compatibilityMode = CompatibilityMode.CURRENT - ) - - private fun deserializePublicSymbol(idSig: IdSignature, kind: BinarySymbolData.SymbolKind): IrSymbol { - // TODO: reference lowered declarations cross-module - if (kind == BinarySymbolData.SymbolKind.FILE_SYMBOL) return file.symbol - - val actualModuleDeserializer = moduleDeserializer.findModuleDeserializerForTopLevelId(idSig) - ?: linker.handleSignatureIdNotFoundInModuleWithDependencies(idSig, moduleDeserializer) - - return actualModuleDeserializer.deserializeIrSymbol(idSig, kind) - } - - val originalFileDeserializer = - IrFileDeserializer(file, originalFileReader, fileProto, originalSymbolDeserializer, originalDeclarationDeserializer) - - private val originalSignatureQueue = ArrayDeque() // Top-level signatures to be deserialized from original KLIB - - // Returns whether this file should be queued for deserialization - fun enqueueForDeserialization(idSig: IdSignature): Boolean { - originalSignatureQueue.addLast(idSig) - return originalSignatureQueue.size == 1 - } - - fun deserializePendingSignatures() { - while (!originalSignatureQueue.isEmpty()) { - val signature = originalSignatureQueue.removeFirst() - deserializeAnyDeclaration(signature) - } - } - - // Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations. - // Thus we schedule their deserialization in deserializer's constructor. - val explicitlyExportedToCompiler: Collection = fileProto.explicitlyExportedToCompilerList.map { - val symbolData = originalSymbolDeserializer.parseSymbolData(it) - originalSymbolDeserializer.deserializeIdSignature(symbolData.signatureId) - } - - fun allOriginalDeclarationSignatures(): Collection = originalFileDeserializer.reversedSignatureIndex.keys - - // IC data processing starts here - - private val icFileReader = IrLibraryFileFromBytes(FileReaderFromSerializedIrFile(icFileData.file)) - - val symbolDeserializer = IrSymbolDeserializer( - linker.symbolTable, - icFileReader, - file.symbol, - emptyList(), - { idSig -> idSig.enqueue(this) }, - { _, s -> s }, - enqueueAllDeclarations = true, - deserializedSymbols = deserializedSymbols, - deserializePublicSymbol = ::deserializePublicSymbol - ) - - private val declarationDeserializer = IrDeclarationDeserializer( - linker.builtIns, - linker.symbolTable, - linker.symbolTable.irFactory, - icFileReader, - file, - allowErrorNodes = true, - deserializeInlineFunctions = true, - deserializeBodies = true, - symbolDeserializer, - DefaultFakeOverrideClassFilter, - linker.fakeOverrideBuilder, - skipMutableState = true, - additionalStatementOriginIndex = additionalStatementOriginIndex, - allowErrorStatementOrigins = true, - allowRedeclaration = true, - compatibilityMode = CompatibilityMode.CURRENT, - allowErrorLoopIndices = true, - ) - - private val protoFile: ProtoIrFile by lazy { - ProtoIrFile.parseFrom(icFileData.file.fileData.codedInputStream, ExtensionRegistryLite.newInstance()) - } - - private val carrierDeserializer by lazy { - CarrierDeserializer(declarationDeserializer, icFileData.carriers) - } - - val reversedSignatureIndex: Map = - protoFile.declarationIdList.associateBy { symbolDeserializer.deserializeIdSignature(it) } - - val visited = HashSet() - - val mappingsDeserializer by lazy { - mappingState.mappingsDeserializer(icFileData.mappings, { code -> - val symbolData = symbolDeserializer.parseSymbolData(code) - symbolDeserializer.deserializeIdSignature(symbolData.signatureId) - }) { - deserializeIrSymbol(it) - } - } - - private val containerSigToOrder by lazy { - mutableMapOf().also { map -> - val containerIds = IrLongArrayMemoryReader(icFileData.order.containerSignatures).array - val declarationIds = IrArrayMemoryReader(icFileData.order.declarationSignatures) - - containerIds.forEachIndexed { index, id -> - val symbolData = symbolDeserializer.parseSymbolData(id) - val containerSig = symbolDeserializer.deserializeIdSignature(symbolData.signatureId) - - map[containerSig] = declarationIds.tableItemBytes(index) - } - } - } - - fun loadClassOrder(classSignature: IdSignature): List? { - val bytes = containerSigToOrder[classSignature] ?: return null - - return IrLongArrayMemoryReader(bytes).array.map { deserializeIrSymbol(it) } - } - - fun deserializeDeclaration(idSig: IdSignature): IrDeclaration? { - cachedDeclaration(idSig)?.let { return it } - - val idSigIndex = reversedSignatureIndex[idSig] ?: return null - val declarationProto = icFileReader.declaration(idSigIndex) - return declarationDeserializer.deserializeDeclaration(declarationProto) - } - - // Return declaration iff it was already deserialized - private fun cachedDeclaration(idSig: IdSignature): IrDeclaration? { - val symbol = deserializedSymbols[idSig] // Same map is used for both symbol deserializers - - if (symbol != null && symbol.isBound) return symbol.owner as? IrDeclaration - - return null - } - - fun deserializeAnyDeclaration(idSig: IdSignature): IrDeclaration? { - cachedDeclaration(idSig)?.let { return it } - - // TODO fast path? - val maybeTopLevel = if (idSig.hasTopLevel) idSig.topLevelSignature() else idSig - - if (maybeTopLevel in originalFileDeserializer.reversedSignatureIndex.keys) { - originalFileDeserializer.deserializeFileImplicitDataIfFirstUse() - return originalFileDeserializer.deserializeDeclaration(maybeTopLevel) - } - - reversedSignatureIndex[maybeTopLevel]?.let { idSigIndex -> - val declarationProto = icFileReader.declaration(idSigIndex) - return declarationDeserializer.deserializeDeclaration(declarationProto) - } - - // TODO: error? - return null - } - - private fun deserializeIrSymbol(code: Long): IrSymbol { - return symbolDeserializer.deserializeIrSymbol(code) - } - - fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { - idSig.enqueue(this) - return symbolDeserializer.deserializeIrSymbol(idSig, symbolKind) - } - - fun injectCarriers(declaration: IrDeclaration, signature: IdSignature) { - carrierDeserializer.injectCarriers(declaration, signature) - } - - companion object { - private val additionalStatementOrigins = JsStatementOrigins::class.nestedClasses.toList() - private val additionalStatementOriginIndex = - additionalStatementOrigins.mapNotNull { it.objectInstance as? IrStatementOriginImpl }.associateBy { it.debugName } - } -} - -private class FileReaderFromSerializedIrFile(val irFile: SerializedIrFile) : IrLibraryBytesSource() { - private val declarationReader = DeclarationIrTableMemoryReader(irFile.declarations) - private val typeReader = IrArrayMemoryReader(irFile.types) - private val signatureReader = IrArrayMemoryReader(irFile.signatures) - private val stringReader = IrArrayMemoryReader(irFile.strings) - private val bodyReader = IrArrayMemoryReader(irFile.bodies) - - override fun irDeclaration(index: Int): ByteArray = declarationReader.tableItemBytes(DeclarationId(index)) - - override fun type(index: Int): ByteArray = typeReader.tableItemBytes(index) - - override fun signature(index: Int): ByteArray = signatureReader.tableItemBytes(index) - - override fun string(index: Int): ByteArray = stringReader.tableItemBytes(index) - - override fun body(index: Int): ByteArray = bodyReader.tableItemBytes(index) - - override fun debugInfo(index: Int): ByteArray? = null -} \ No newline at end of file diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcModuleDeserializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcModuleDeserializer.kt deleted file mode 100644 index 75dea07d9c6..00000000000 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcModuleDeserializer.kt +++ /dev/null @@ -1,269 +0,0 @@ -/* - * 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 org.jetbrains.kotlin.ir.backend.js.ic - -import org.jetbrains.kotlin.backend.common.serialization.* -import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.ir.backend.js.JsMapping -import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl -import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory -import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol -import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.ir.util.isEffectivelyExternal -import org.jetbrains.kotlin.library.IrLibrary -import org.jetbrains.kotlin.library.KotlinAbiVersion -import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.library.impl.IrLongArrayMemoryReader -import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite -import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoFile - -class IcModuleDeserializer( - val irFactory: PersistentIrFactory, - val mapping: JsMapping, - val linker: JsIrLinker, - val icData: SerializedIcData, - moduleDescriptor: ModuleDescriptor, - override val klib: IrLibrary, - override val strategyResolver: (String) -> DeserializationStrategy, - private val containsErrorCode: Boolean = false, -) : IrModuleDeserializer(moduleDescriptor, (klib as KotlinLibrary).versions.abiVersion ?: KotlinAbiVersion.CURRENT) { - - private val fileToDeserializerMap = mutableMapOf() - - internal val moduleReversedFileIndex = mutableMapOf() - internal val icModuleReversedFileIndex = mutableMapOf() - - override val moduleDependencies by lazy { - moduleDescriptor.allDependencyModules.filter { it != moduleDescriptor }.map { linker.resolveModuleDeserializer(it, null) } - } - - override fun fileDeserializers(): Collection { - return fileToDeserializerMap.values - } - - override fun init(delegate: IrModuleDeserializer) { - val fileCount = klib.fileCount() - - val files = ArrayList(fileCount) - - for (i in 0 until fileCount) { - val fileStream = klib.file(i).codedInputStream - val fileProto = ProtoFile.parseFrom(fileStream, ExtensionRegistryLite.newInstance()) - files.add(deserializeIrFile(fileProto, i, delegate, containsErrorCode)) - } - - moduleFragment.files.addAll(files) - - fileToDeserializerMap.values.forEach { it.symbolDeserializer.deserializeExpectActualMapping() } - } - - private fun IrSymbolDeserializer.deserializeExpectActualMapping() { - actuals.forEach { - val expectSymbol = parseSymbolData(it.expectSymbol) - val actualSymbol = parseSymbolData(it.actualSymbol) - - val expect = deserializeIdSignature(expectSymbol.signatureId) - val actual = deserializeIdSignature(actualSymbol.signatureId) - - assert(linker.expectUniqIdToActualUniqId[expect] == null) { - "Expect signature $expect is already actualized by ${linker.expectUniqIdToActualUniqId[expect]}, while we try to record $actual" - } - linker.expectUniqIdToActualUniqId[expect] = actual - // Non-null only for topLevel declarations. - findModuleDeserializerForTopLevelId(actual)?.let { md -> linker.topLevelActualUniqItToDeserializer[actual] = md } - } - } - - override fun referenceSimpleFunctionByLocalSignature(file: IrFile, idSignature: IdSignature): IrSimpleFunctionSymbol = - fileToDeserializerMap[file]?.symbolDeserializer?.referenceSimpleFunctionByLocalSignature(idSignature) - ?: error("No deserializer for file $file in module ${moduleDescriptor.name}") - - override fun referencePropertyByLocalSignature(file: IrFile, idSignature: IdSignature): IrPropertySymbol = - fileToDeserializerMap[file]?.symbolDeserializer?.referencePropertyByLocalSignature(idSignature) - ?: error("No deserializer for file $file in module ${moduleDescriptor.name}") - - // TODO: fix to topLevel checker - override fun contains(idSig: IdSignature): Boolean = idSig.topLevelSignature() in moduleReversedFileIndex || idSig in icModuleReversedFileIndex - - override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { - assert(idSig.isPubliclyVisible) - - icModuleReversedFileIndex[idSig]?.let { icDeserializer -> - return icDeserializer.deserializeIrSymbol(idSig, symbolKind) - } - - val topLevelSignature = idSig.topLevelSignature() - val icDeserializer = moduleReversedFileIndex[topLevelSignature] - ?: error("No file for $topLevelSignature (@ $idSig) in module $moduleDescriptor") - - val symbol = icDeserializer.originalFileDeserializer.symbolDeserializer.deserializeIrSymbol(idSig, symbolKind) - - if (!symbol.isBound) { - topLevelSignature.originalEnqueue(icDeserializer) - idSig.enqueue(icDeserializer) - } - - return symbol - } - - override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, linker.builtIns, emptyList()) - - private val pathToIcFileData = icData.files.associateBy { - it.file.path - } - - private fun deserializeIrFile( - fileProto: ProtoFile, - fileIndex: Int, - moduleDeserializer: IrModuleDeserializer, - allowErrorNodes: Boolean - ): IrFile { - - val fileReader = IrLibraryFileFromBytes(IrKlibBytesSource(moduleDeserializer.klib, fileIndex)) - val file = fileReader.createFile(moduleFragment, fileProto) - val fileStrategy = strategyResolver(file.fileEntry.name) - - val icFileData = pathToIcFileData[file.path] ?: error("No IC cache found for file ${file.path}") - - val icDeserializer = IcFileDeserializer( - linker, - file, - fileReader, - fileProto, - fileStrategy.needBodies, - allowErrorNodes, - fileStrategy.inlineBodies, - moduleDeserializer, - { fileDeserializer -> originalEnqueue(fileDeserializer) }, - icFileData, - mapping.state, - { fileDeserializer -> enqueue(fileDeserializer) }, - ) - - icDeserializers += icDeserializer - - icDeserializer.explicitlyExportedToCompiler.forEach { it.topLevelSignature().originalEnqueue(icDeserializer) } - - fileToDeserializerMap[file] = icDeserializer.originalFileDeserializer - - val topLevelDeclarations = icDeserializer.originalFileDeserializer.reversedSignatureIndex.keys - topLevelDeclarations.forEach { - moduleReversedFileIndex.putIfAbsent(it, icDeserializer) // TODO Why not simple put? - } - - icDeserializer.reversedSignatureIndex.keys.forEach { - if (it.isPubliclyVisible) { - if (it in icModuleReversedFileIndex) { - val existed = icModuleReversedFileIndex[it]!! - error("Duplicate signature $it in both ${existed.originalFileDeserializer.file.path} and in ${file.path}") - } - - icModuleReversedFileIndex[it] = icDeserializer - } - } - - if (fileStrategy.theWholeWorld) { - icDeserializer.allOriginalDeclarationSignatures().forEach { it.originalEnqueue(icDeserializer) } - } - if (fileStrategy.theWholeWorld || fileStrategy.explicitlyExported) { - linker.modulesWithReachableTopLevels.add(this) - } - - return file - } - - override fun addModuleReachableTopLevel(idSig: IdSignature) { - val fileLocalDeserializationState = moduleReversedFileIndex[idSig] ?: error("No file found for key $idSig") - idSig.originalEnqueue(fileLocalDeserializationState) - } - - override fun deserializeReachableDeclarations() { - while (!originalFileQueue.isEmpty()) { - originalFileQueue.removeFirst().deserializePendingSignatures() - } - } - - val originalFileQueue = ArrayDeque() - - fun IdSignature.originalEnqueue(fileDeserializer: IcFileDeserializer) { - if (fileDeserializer.enqueueForDeserialization(this)) { - linker.modulesWithReachableTopLevels.add(this@IcModuleDeserializer) - originalFileQueue.addLast(fileDeserializer) - } - } - - val fileQueue = ArrayDeque() - val signatureQueue = ArrayDeque() - - val icDeserializers = mutableListOf() - val classToDeclarationSymbols = mutableMapOf>() - - fun IdSignature.enqueue(icDeserializer: IcFileDeserializer) { - if (this !in icDeserializer.visited) { - fileQueue.addLast(icDeserializer) - signatureQueue.addLast(this) - icDeserializer.visited += this - } - } - - override fun postProcess() { - while (signatureQueue.isNotEmpty()) { - val icFileDeserializer = fileQueue.removeFirst() - val signature = signatureQueue.removeFirst() - - val declaration = - icFileDeserializer.deserializeDeclaration(signature) ?: icFileDeserializer.deserializeAnyDeclaration(signature) - - if (declaration != null) { - icFileDeserializer.injectCarriers(declaration, signature) - - icFileDeserializer.mappingsDeserializer(signature, declaration) - - // Make sure all members are loaded - if (declaration is IrClass) { - icFileDeserializer.loadClassOrder(signature)?.let { - classToDeclarationSymbols[declaration] = it - } - } - } - } - - irFactory.stageController.withStage(1000) { - - for (icDeserializer in icDeserializers) { - val fd = icDeserializer.originalFileDeserializer - val order = icDeserializer.icFileData.order - - fd.file.declarations.retainAll { it.isEffectivelyExternal() } - - IrLongArrayMemoryReader(order.topLevelSignatures).array.forEach { - val symbolData = icDeserializer.symbolDeserializer.parseSymbolData(it) - val idSig = icDeserializer.symbolDeserializer.deserializeIdSignature(symbolData.signatureId) - - // Don't create unbound symbols for top-level declarations we don't need. - if (idSig in icDeserializer.visited) { - val declaration = icDeserializer.deserializeIrSymbol(idSig, symbolData.kind).owner as IrDeclaration - fd.file.declarations += declaration - } - } - } - - for ((klass, declarations) in classToDeclarationSymbols.entries) { - irFactory.stageController.unrestrictDeclarationListsAccess { - klass.declarations.clear() - for (ds in declarations) { - klass.declarations += ds.owner as IrDeclaration - } - } - } - } - } -} \ No newline at end of file diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcSerializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcSerializer.kt deleted file mode 100644 index 8561fe13975..00000000000 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IcSerializer.kt +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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 org.jetbrains.kotlin.ir.backend.js.ic - -import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode -import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable -import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer -import org.jetbrains.kotlin.ir.IrBuiltIns -import org.jetbrains.kotlin.ir.backend.js.JsMapping -import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsGlobalDeclarationTable -import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrFileSerializer -import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrBodyBase -import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrDeclarationBase -import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory -import org.jetbrains.kotlin.ir.expressions.IrExpressionBody -import org.jetbrains.kotlin.ir.serialization.serializeCarriers -import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.ir.util.file -import org.jetbrains.kotlin.ir.util.fileOrNull -import org.jetbrains.kotlin.ir.util.isFakeOverride -import org.jetbrains.kotlin.library.impl.IrMemoryArrayWriter -import org.jetbrains.kotlin.library.impl.IrMemoryLongArrayWriter - -class IcSerializer( - irBuiltIns: IrBuiltIns, - val mappings: JsMapping, - val irFactory: PersistentIrFactory, - val linker: JsIrLinker, - val module: IrModuleFragment -) { - - private val globalDeclarationTable = JsGlobalDeclarationTable(irBuiltIns) - - fun serializeDeclarations(moduleDeclarations: Iterable): SerializedIcData { - - // TODO serialize body carriers and new bodies as well - val moduleDeserializer = linker.moduleDeserializer(module.descriptor) - - val fileToDeserializer = moduleDeserializer.fileDeserializers().associateBy { it.file } - - val filteredDeclarations = moduleDeclarations.filter { - when { - it.fileOrNull.let { it == null || fileToDeserializer[it] == null } -> false - it is IrFakeOverrideFunction -> it.isBound - it is IrFakeOverrideProperty -> it.isBound - else -> (it.parent as? IrFakeOverrideFunction)?.isBound ?: (it.parent as? IrFakeOverrideProperty)?.isBound ?: true - } - } - - val filteredBodies = irFactory.allBodies.groupBy { - (it as? PersistentIrBodyBase<*>)?.let { - if (it.hasContainer) { - it.container.fileOrNull - } else null - } - } - - val dataToSerialize = filteredDeclarations.groupBy { - // TODO don't move declarations or effects outside the original file - // TODO Or invent a different mechanism for that - - it.file - } - - val icData = mutableListOf() - - for (file in fileToDeserializer.keys) { - val fileDeclarations = dataToSerialize[file] ?: emptyList() - val bodies = filteredBodies[file] ?: emptyList() - - val fileDeserializer = fileToDeserializer[file]!! - - val symbolToSignature = fileDeserializer.symbolDeserializer.deserializedSymbols.entries.associate { (idSig, symbol) -> symbol to idSig }.toMutableMap() - - val icDeclarationTable = IcDeclarationTable(globalDeclarationTable, irFactory, 1000000, symbolToSignature) - val fileSerializer = JsIrFileSerializer( - linker.messageLogger, - icDeclarationTable, - mutableMapOf(), - skipExpects = true, - icMode = true, - allowErrorStatementOrigins = true, - compatibilityMode = CompatibilityMode.CURRENT, - normalizeAbsolutePaths = false, - sourceBaseDirs = emptyList() - ) - - icDeclarationTable.inFile(file) { - bodies.forEach { body -> - if (body is IrExpressionBody) { - fileSerializer.serializeIrExpressionBody(body.expression) - } else { - fileSerializer.serializeIrStatementBody(body) - } - } - - // Only save newly created declarations - val newDeclarations = fileDeclarations.filter { d -> - d is PersistentIrDeclarationBase<*> && (d.createdOn > 0 || /*d.isFakeOverride ||*/ (d is IrValueParameter || d is IrTypeParameter) && (d.parent as IrDeclaration).isFakeOverride) - } - - val serializedCarriers = fileSerializer.serializeCarriers(fileDeclarations, bodies) { declaration -> - icDeclarationTable.signatureByDeclaration(declaration, compatibleMode = false) - } - - val serializedMappings = mappings.state.serializeMappings(fileDeclarations) { symbol -> - fileSerializer.serializeIrSymbol(symbol) - } - - val order = storeOrder(file, fileDeclarations) { symbol -> - fileSerializer.serializeIrSymbol(symbol) - } - - val serializedIrFile = fileSerializer.serializeDeclarationsForIC(file, newDeclarations) - - icData += SerializedIcDataForFile( - serializedIrFile, - serializedCarriers, - serializedMappings, - order, - ) - } - } - - return SerializedIcData(icData) - } - - // Returns precomputed signatures for the newly created declarations. Delegates to the default table otherwise. - class IcDeclarationTable( - globalDeclarationTable: JsGlobalDeclarationTable, - val irFactory: PersistentIrFactory, - startIndex: Int, - val existingMappings: MutableMap - ) : DeclarationTable(globalDeclarationTable) { - - override val signaturer: IdSignatureSerializer = - IdSignatureSerializer(globalDeclarationTable.publicIdSignatureComputer, this, startIndex) - - override fun signatureByDeclaration(declaration: IrDeclaration, compatibleMode: Boolean): IdSignature { - return existingMappings.getOrPut(declaration.symbol) { - irFactory.declarationSignature(declaration) ?: super.signatureByDeclaration(declaration, compatibleMode) - } - } - } -} - -fun storeOrder(file: IrFile, fileDeclarations: Iterable, idSigToLong: (IrSymbol) -> Long): SerializedOrder { - val topLevelSignatures = mutableListOf() - val containerSignatures = mutableListOf() - val declarationSignatures = mutableListOf() - - fun IrDeclaration.idSigIndex(): Long = idSigToLong(symbol) - - file.declarations.forEach { d -> - topLevelSignatures += d.idSigIndex() - } - - fileDeclarations.forEach { declaration -> - if (declaration is IrClass) { - // First element is the container signature - containerSignatures += declaration.idSigIndex() - val declarationIds = declaration.declarations.map { it.idSigIndex() } - - declarationSignatures += IrMemoryLongArrayWriter(declarationIds).writeIntoMemory() - } - } - - return SerializedOrder( - IrMemoryLongArrayWriter(topLevelSignatures).writeIntoMemory(), - IrMemoryLongArrayWriter(containerSignatures).writeIntoMemory(), - IrMemoryArrayWriter(declarationSignatures).writeIntoMemory(), - ) -} \ No newline at end of file diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/data.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/data.kt deleted file mode 100644 index 904689ba336..00000000000 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/ic/data.kt +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 org.jetbrains.kotlin.ir.backend.js.ic - -import org.jetbrains.kotlin.ir.backend.js.SerializedMapping -import org.jetbrains.kotlin.ir.backend.js.SerializedMappings -import org.jetbrains.kotlin.ir.serialization.SerializedCarriers -import org.jetbrains.kotlin.library.SerializedIrFile -import org.jetbrains.kotlin.library.impl.IrArrayMemoryReader -import org.jetbrains.kotlin.library.impl.IrMemoryArrayWriter -import org.jetbrains.kotlin.library.impl.toArray -import java.io.File - -class SerializedIcData( - val files: Collection, -) - -class SerializedIcDataForFile( - val file: SerializedIrFile, - val carriers: SerializedCarriers, - val mappings: SerializedMappings, - val order: SerializedOrder, -) - -class SerializedOrder( - val topLevelSignatures: ByteArray, - val containerSignatures: ByteArray, - val declarationSignatures: ByteArray, -) - -fun newFile(fileDir: File, name: String): File { - val f = File(fileDir, name) - if (f.exists()) f.delete() - return f -} - -fun SerializedIcDataForFile.writeData(fileDir: File) { - // .file - newFile(fileDir, "file.fileData").writeBytes(file.fileData) - newFile(fileDir, "file.path").writeBytes(file.path.toByteArray(Charsets.UTF_8)) - newFile(fileDir, "file.declarations").writeBytes(file.declarations) - newFile(fileDir, "file.types").writeBytes(file.types) - newFile(fileDir, "file.signatures").writeBytes(file.signatures) - newFile(fileDir, "file.strings").writeBytes(file.strings) - newFile(fileDir, "file.bodies").writeBytes(file.bodies) - // .carriers - newFile(fileDir, "carriers.signatures").writeBytes(carriers.signatures) - newFile(fileDir, "carriers.declarationCarriers").writeBytes(carriers.declarationCarriers) - newFile(fileDir, "carriers.bodyCarriers").writeBytes(carriers.bodyCarriers) - newFile(fileDir, "carriers.removedOn").writeBytes(carriers.removedOn) - // .mappings - newFile(fileDir, "mappings.keys").writeBytes(mappings.keyBytes()) - newFile(fileDir, "mappings.values").writeBytes(mappings.valueBytes()) - // .order - newFile(fileDir, "order.topLevelSignatures").writeBytes(order.topLevelSignatures) - newFile(fileDir, "order.containerSignatures").writeBytes(order.containerSignatures) - newFile(fileDir, "order.declarationSignatures").writeBytes(order.declarationSignatures) -} - -fun SerializedIcData.writeTo(dir: File) { - if (!dir.exists()) error("Directory doesn't exist: ${dir.absolutePath}") - if (!dir.isDirectory) error("Not a directory: ${dir.absolutePath}") - - files.forEach { - val fqnPath = it.file.fqName - val fileId = it.file.path.hashCode().toString(Character.MAX_RADIX) - val irFileDirectory = "ic-$fqnPath.$fileId.file" - val fileDir = File(dir, irFileDirectory) - - // TODO: just rewrite? - if (!fileDir.exists()) { - if (!fileDir.mkdirs()) error("Failed to create output dir for file ${fileDir.absolutePath}") - } - - it.writeData(fileDir) - } -} - -private fun SerializedMappings.keyBytes() = IrMemoryArrayWriter(mappings.map { it.keys }).writeIntoMemory() -private fun SerializedMappings.valueBytes() = IrMemoryArrayWriter(mappings.map { it.values }).writeIntoMemory() - -fun File.readIcDataBinary(): SerializedIcDataForFile { - val file = SerializedIrFile( - fileData = File(this, "file.fileData").readBytes(), - fqName = name.split('.').dropLast(2).joinToString(separator = "."), - path = File(this, "file.path").readBytes().toString(Charsets.UTF_8), - types = File(this, "file.types").readBytes(), - signatures = File(this, "file.signatures").readBytes(), - strings = File(this, "file.strings").readBytes(), - bodies = File(this, "file.bodies").readBytes(), - declarations = File(this, "file.declarations").readBytes(), - debugInfo = null - ) - - val carriers = SerializedCarriers( - signatures = File(this, "carriers.signatures").readBytes(), - declarationCarriers = File(this, "carriers.declarationCarriers").readBytes(), - bodyCarriers = File(this, "carriers.bodyCarriers").readBytes(), - removedOn = File(this, "carriers.removedOn").readBytes(), - ) - - val mappingKeys = IrArrayMemoryReader(File(this, "mappings.keys").readBytes()).toArray() - val mappingValues = IrArrayMemoryReader(File(this, "mappings.values").readBytes()).toArray() - assert(mappingKeys.size == mappingValues.size) - val mappings = SerializedMappings(mappingKeys.zip(mappingValues).map { (k, v) -> SerializedMapping(k, v) }) - - val order = SerializedOrder( - topLevelSignatures = File(this, "order.topLevelSignatures").readBytes(), - containerSignatures = File(this, "order.containerSignatures").readBytes(), - declarationSignatures = File(this, "order.declarationSignatures").readBytes(), - ) - - return SerializedIcDataForFile(file, carriers, mappings, order) -} - -fun File.readIcData(): SerializedIcData { - if (!this.isDirectory) error("Directory doesn't exist: ${this.absolutePath}") - - return SerializedIcData(this.listFiles()!!.filter { it.isDirectory && it.name.startsWith("ic-") }.map { fileDir -> - fileDir.readIcDataBinary() - }) -} \ No newline at end of file diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 8fa9933f0dc..6997bdc9704 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -31,8 +31,6 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI -import org.jetbrains.kotlin.ir.backend.js.ic.ICCache -import org.jetbrains.kotlin.ir.backend.js.ic.SerializedIcData import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc @@ -71,7 +69,6 @@ import org.jetbrains.kotlin.util.DummyLogger import org.jetbrains.kotlin.util.Logger import org.jetbrains.kotlin.utils.DFS import java.io.File -import org.jetbrains.kotlin.konan.file.File as KFile val KotlinLibrary.moduleName: String get() = manifestProperties.getProperty(KLIB_PROPERTY_UNIQUE_NAME) @@ -83,11 +80,6 @@ val KotlinLibrary.isBuiltIns: Boolean .propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true) .isEmpty() -// TODO: The only place loadKlib() is used now is Wasm backend. -// Need to move it to SearchPathResolver too. -fun loadKlib(klibPath: String) = - resolveSingleFileKlib(KFile(KFile(klibPath).absolutePath)) - private val CompilerConfiguration.metadataVersion get() = get(CommonConfigurationKeys.METADATA_VERSION) as? KlibMetadataVersion ?: KlibMetadataVersion.INSTANCE @@ -255,9 +247,7 @@ data class IrModuleInfo( val allDependencies: List, val bultins: IrBuiltIns, val symbolTable: SymbolTable, - val deserializer: JsIrLinker, - val moduleFragmentToUniqueName: Map, - val loweredIrLoaded: Set = emptySet(), + val deserializer: JsIrLinker ) fun sortDependencies(mapping: Map): Collection { @@ -269,14 +259,6 @@ fun sortDependencies(mapping: Map): Collection< }.reversed() } -interface LoweringsCacheProvider { - fun cacheByPath(path: String): SerializedIcData? -} - -object EmptyLoweringsCacheProvider : LoweringsCacheProvider { - override fun cacheByPath(path: String): SerializedIcData? = null -} - fun deserializeDependencies( sortedDependencies: Collection, irLinker: JsIrLinker, @@ -296,14 +278,6 @@ fun deserializeDependencies( } } -fun Map.getUniqueNameForEachFragment(): Map { - return this.entries.mapNotNull { (moduleFragment, klib) -> - klib.manifestProperties.getProperty(KLIB_PROPERTY_JS_OUTPUT_NAME)?.let { - moduleFragment to it - } - }.toMap() -} - fun getFunctionFactoryCallback(stdlibModule: IrModuleFragment) = { packageFragmentDescriptor: PackageFragmentDescriptor -> IrFileImpl( NaiveSourceBasedFileEntryImpl("${packageFragmentDescriptor.fqName}-[K][Suspend]Functions"), @@ -345,31 +319,13 @@ fun loadIr( mainModule.files, sortDependencies(depsDescriptors.descriptors), friendModules, - depsDescriptors.loweredIcData, symbolTable, messageLogger, loadFunctionInterfacesIntoStdlib, verifySignatures, - { depsDescriptors.modulesWithCaches(it) }, - { depsDescriptors.getModuleDescriptor(it) }, - ) + ) { depsDescriptors.getModuleDescriptor(it) } } is MainModule.Klib -> { - val loweredIcData = if (!depsDescriptors.icUseGlobalSignatures && !depsDescriptors.icUseStdlibCache) emptyMap() else { - val result = mutableMapOf() - - for (lib in depsDescriptors.moduleDependencies.keys) { - val path = lib.libraryFile.absolutePath - val icData = depsDescriptors.loweringsCacheProvider.cacheByPath(path) - if (icData != null) { - val desc = depsDescriptors.getModuleDescriptor(lib) - result[desc] = icData - } - } - - result - } - val mainPath = File(mainModule.libPath).canonicalPath val mainModuleLib = allDependencies.find { it.libraryFile.canonicalPath == mainPath } ?: error("No module with ${mainModule.libPath} found") @@ -386,10 +342,7 @@ fun loadIr( symbolTable, messageLogger, loadFunctionInterfacesIntoStdlib, - loweredIcData, - { depsDescriptors.modulesWithCaches(it) }, - { depsDescriptors.getModuleDescriptor(it) }, - ) + ) { depsDescriptors.getModuleDescriptor(it) } } } } @@ -404,8 +357,6 @@ fun getIrModuleInfoForKlib( symbolTable: SymbolTable, messageLogger: IrMessageLogger, loadFunctionInterfacesIntoStdlib: Boolean, - loweredIcData: Map, - filterModulesWithCache: (Iterable) -> Set, mapping: (KotlinLibrary) -> ModuleDescriptor, ): IrModuleInfo { val mainModuleLib = sortedDependencies.last() @@ -422,7 +373,6 @@ fun getIrModuleInfoForKlib( symbolTable, null, null, - loweredIcData, friendModules, allowUnboundSymbols ) @@ -443,11 +393,7 @@ fun getIrModuleInfoForKlib( ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies() irLinker.postProcess() - return IrModuleInfo( - moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, - deserializedModuleFragmentsToLib.getUniqueNameForEachFragment(), - filterModulesWithCache(deserializedModuleFragments) - ) + return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker) } @OptIn(ObsoleteDescriptorBasedAPI::class) @@ -458,12 +404,10 @@ fun getIrModuleInfoForSourceFiles( files: List, allSortedDependencies: Collection, friendModules: Map>, - loweredIcData: Map, symbolTable: SymbolTable, messageLogger: IrMessageLogger, loadFunctionInterfacesIntoStdlib: Boolean, verifySignatures: Boolean, - filterModulesWithCache: (Iterable) -> Set, mapping: (KotlinLibrary) -> ModuleDescriptor ): IrModuleInfo { val irBuiltIns = psi2IrContext.irBuiltIns @@ -481,7 +425,6 @@ fun getIrModuleInfoForSourceFiles( symbolTable, feContext, null, - loweredIcData, friendModules, allowUnboundSymbols ) @@ -517,11 +460,7 @@ fun getIrModuleInfoForSourceFiles( irBuiltIns.knownBuiltins.forEach { it.acceptVoid(mangleChecker) } } - return IrModuleInfo( - moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker, - deserializedModuleFragmentsToLib.getUniqueNameForEachFragment(), - filterModulesWithCache(deserializedModuleFragments) - ) + return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker) } fun prepareAnalyzedSourceModule( @@ -531,13 +470,10 @@ fun prepareAnalyzedSourceModule( dependencies: List, friendDependencies: List, analyzer: AbstractAnalyzerWithCompilerReport, - icUseGlobalSignatures: Boolean = false, - icUseStdlibCache: Boolean = false, - icCache: Map = emptyMap(), errorPolicy: ErrorTolerancePolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT, ): ModulesStructure { val mainModule = MainModule.SourceFiles(files) - val sourceModule = ModulesStructure(project, mainModule, configuration, dependencies, friendDependencies, icUseGlobalSignatures, icUseStdlibCache, icCache) + val sourceModule = ModulesStructure(project, mainModule, configuration, dependencies, friendDependencies) return sourceModule.apply { runAnalysis(errorPolicy, analyzer) } @@ -626,19 +562,7 @@ class ModulesStructure( val compilerConfiguration: CompilerConfiguration, val dependencies: Collection, friendDependenciesPaths: Collection, - val icUseGlobalSignatures: Boolean, - val icUseStdlibCache: Boolean, - val icCache: Map, ) { - val loweringsCacheProvider: LoweringsCacheProvider = when { - icUseStdlibCache -> object : LoweringsCacheProvider { - override fun cacheByPath(path: String): SerializedIcData? { - return icCache[path]?.serializedIcData - } - } - icUseGlobalSignatures -> EmptyLoweringsCacheProvider - else -> EmptyLoweringsCacheProvider - } val allResolvedDependencies = jsResolveLibraries( dependencies, @@ -662,7 +586,7 @@ class ModulesStructure( }.toMap() } - val builtInsDep = allDependencies.find { it.library.isBuiltIns } + private val builtInsDep = allDependencies.find { it.library.isBuiltIns } class JsFrontEndResult(val jsAnalysisResult: AnalysisResult, val hasErrors: Boolean) { val moduleDescriptor: ModuleDescriptor @@ -719,8 +643,6 @@ class ModulesStructure( // TODO: these are roughly equivalent to KlibResolvedModuleDescriptorsFactoryImpl. Refactor me. val descriptors = mutableMapOf() - val loweredIcData = mutableMapOf() - fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl = descriptors.getOrPut(current) { val isBuiltIns = current.unresolvedDependencies.isEmpty() @@ -738,17 +660,9 @@ class ModulesStructure( val dependencies = moduleDependencies.getValue(current).map { getModuleDescriptor(it) } md.setDependencies(listOf(md) + dependencies) - loweringsCacheProvider.cacheByPath(current.libraryFile.absolutePath)?.let { icData -> - loweredIcData[md] = icData - } - md } - fun modulesWithCaches(allModules: Iterable): Set { - return allModules.filter { it.descriptor in loweredIcData }.toSet() - } - val builtInModuleDescriptor = if (builtInsDep != null) getModuleDescriptor(builtInsDep.library) diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index 668d01a6e7a..a28eae4b431 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -9,12 +9,8 @@ import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.IrBuiltIns -import org.jetbrains.kotlin.ir.backend.js.JsMapping -import org.jetbrains.kotlin.ir.backend.js.ic.IcModuleDeserializer -import org.jetbrains.kotlin.ir.backend.js.ic.SerializedIcData import org.jetbrains.kotlin.ir.builders.TranslationPluginContext import org.jetbrains.kotlin.ir.declarations.IrModuleFragment -import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.library.IrLibrary @@ -26,7 +22,6 @@ class JsIrLinker( private val currentModule: ModuleDescriptor?, messageLogger: IrMessageLogger, builtIns: IrBuiltIns, symbolTable: SymbolTable, override val translationPluginContext: TranslationPluginContext?, private val icData: ICData? = null, - private val loweredIcData: Map = emptyMap(), friendModules: Map> = emptyMap(), allowUnboundSymbols: Boolean = false ) : KotlinIrLinker( @@ -53,23 +48,9 @@ class JsIrLinker( override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategyResolver: (String) -> DeserializationStrategy): IrModuleDeserializer { require(klib != null) { "Expecting kotlin library" } - loweredIcData[moduleDescriptor]?.let { loweredIcData -> - return IcModuleDeserializer( - symbolTable.irFactory as PersistentIrFactory, - mapping, - this, - loweredIcData, - moduleDescriptor, - klib, - strategyResolver, - containsErrorCode = klib.libContainsErrorCode, - ) - } return JsModuleDeserializer(moduleDescriptor, klib, strategyResolver, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, klib.libContainsErrorCode) } - val mapping: JsMapping by lazy { JsMapping(symbolTable.irFactory) } - private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) : BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, allowErrorCode) @@ -102,15 +83,6 @@ class JsIrLinker( return deserializersForModules[moduleDescriptor.name.asString()] ?: error("Deserializer for $moduleDescriptor not found") } - fun loadIcIr(preprocess: (IrModuleFragment) -> Unit) { - deserializersForModules.values.reversed().forEach { - if (it.moduleDescriptor in loweredIcData) { - preprocess(it.moduleFragment) - } - it.postProcess() - } - } - class JsFePluginContext( override val moduleDescriptor: ModuleDescriptor, override val symbolTable: ReferenceSymbolTable, diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 37a920dabe8..4abf26ee045 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -13,7 +13,6 @@ where advanced options include: -Xir-base-class-in-metadata Write base class into metadata -Xir-build-cache Use compiler to build cache -Xir-dce Perform experimental dead code elimination - -Xir-dce-driven Perform a more experimental faster dead code elimination -Xir-dce-print-reachability-info Print declarations' reachability info to stdout during performing DCE -Xir-dce-runtime-diagnostic={log|exception} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/JsEnvironmentConfigurationDirectives.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/JsEnvironmentConfigurationDirectives.kt index d9093b60325..8367226c924 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/JsEnvironmentConfigurationDirectives.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/directives/JsEnvironmentConfigurationDirectives.kt @@ -210,11 +210,6 @@ object JsEnvironmentConfigurationDirectives : SimpleDirectivesContainer() { applicability = DirectiveApplicability.Global ) - val LOWER_PER_MODULE by directive( - description = "", - applicability = DirectiveApplicability.Global - ) - val KLIB_MAIN_MODULE by directive( description = "Specify that main module is actually a klib", applicability = DirectiveApplicability.Global diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibTextTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibTextTestCase.kt index c4836812a79..ade6ed2d066 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibTextTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibTextTestCase.kt @@ -223,7 +223,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() { val typeTranslator = TypeTranslatorImpl(symbolTable, myEnvironment.configuration.languageVersionSettings, testDescriptor) val irBuiltIns = IrBuiltInsOverDescriptors(testDescriptor.builtIns, typeTranslator, symbolTable) - val irLinker = JsIrLinker(null, IrMessageLogger.None, irBuiltIns, symbolTable, null, null) + val irLinker = JsIrLinker(null, IrMessageLogger.None, irBuiltIns, symbolTable, null) irLinker.deserializeIrModuleHeader(stdlibDescriptor, stdlib) val testModule = irLinker.deserializeIrModuleHeader(testDescriptor, klib, { DeserializationStrategy.ALL }) irLinker.init(null, emptyList()) @@ -280,7 +280,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() { val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImpl, NameProvider.DEFAULT) val context = psi2Ir.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable) val irBuiltIns = context.irBuiltIns - val irLinker = JsIrLinker(moduleDescriptor, IrMessageLogger.None, irBuiltIns, symbolTable, null, null) + val irLinker = JsIrLinker(moduleDescriptor, IrMessageLogger.None, irBuiltIns, symbolTable, null) irLinker.deserializeIrModuleHeader(stdlibDescriptor, stdlib) return psi2Ir.generateModuleFragment(context, ktFiles, listOf(irLinker), emptyList(), expectActualSymbols) to bindingContext diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/AbstractJsKLibABITestCase.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/AbstractJsKLibABITestCase.kt index d900b11c81e..cef7e20d2f0 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/AbstractJsKLibABITestCase.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/AbstractJsKLibABITestCase.kt @@ -31,15 +31,15 @@ abstract class AbstractJsKLibABITestCase : AbstractKlibABITestCase() { configuration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN) configuration.put(CommonConfigurationKeys.MODULE_NAME, MAIN_MODULE_NAME) val kLib = MainModule.Klib(mainModulePath) - val moduleStructure = ModulesStructure(project, kLib, configuration, libraries, emptyList(), false, false, emptyMap()) + val moduleStructure = ModulesStructure(project, kLib, configuration, libraries, emptyList()) val ir = compile( moduleStructure, PhaseConfig(jsPhases), IrFactoryImplForJsIC(WholeWorldStageController()), + exportedDeclarations = setOf(FqName("box")), propertyLazyInitialization = true, granularity = JsGenerationGranularity.PER_MODULE, - exportedDeclarations = setOf(FqName("box")), icCompatibleIr2Js = true ) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsIrBackendFacade.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsIrBackendFacade.kt index 7acd17f513b..8163e92e832 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsIrBackendFacade.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsIrBackendFacade.kt @@ -71,7 +71,7 @@ class JsIrBackendFacade( configuration: CompilerConfiguration, inputArtifact: BinaryArtifacts.KLib, ): BinaryArtifacts.Js? { - val (irModuleFragment, dependencyModules, _, symbolTable, deserializer, _) = moduleInfo + val (irModuleFragment, dependencyModules, _, symbolTable, deserializer) = moduleInfo val splitPerModule = JsEnvironmentConfigurationDirectives.SPLIT_PER_MODULE in module.directives val splitPerFile = JsEnvironmentConfigurationDirectives.SPLIT_PER_FILE in module.directives @@ -86,7 +86,6 @@ class JsIrBackendFacade( } val testPackage = extractTestPackage(testServices) - val lowerPerModule = JsEnvironmentConfigurationDirectives.LOWER_PER_MODULE in module.directives val skipRegularMode = JsEnvironmentConfigurationDirectives.SKIP_REGULAR_MODE in module.directives if (skipRegularMode) return null @@ -132,12 +131,10 @@ class JsIrBackendFacade( deserializer, phaseConfig, exportedDeclarations = setOf(FqName.fromSegments(listOfNotNull(testPackage, TEST_FUNCTION))), - dceDriven = false, dceRuntimeDiagnostic = null, es6mode = false, propertyLazyInitialization = JsEnvironmentConfigurationDirectives.PROPERTY_LAZY_INITIALIZATION in module.directives, baseClassIntoMetadata = false, - lowerPerModule = lowerPerModule, safeExternalBoolean = JsEnvironmentConfigurationDirectives.SAFE_EXTERNAL_BOOLEAN in module.directives, safeExternalBooleanDiagnostic = module.directives[JsEnvironmentConfigurationDirectives.SAFE_EXTERNAL_BOOLEAN_DIAGNOSTIC].singleOrNull(), granularity = granularity, @@ -221,10 +218,7 @@ class JsIrBackendFacade( symbolTable, messageLogger, loadFunctionInterfacesIntoStdlib = true, - emptyMap(), - { emptySet() }, - { if (it == mainModuleLib) moduleDescriptor else testServices.jsLibraryProvider.getDescriptorByCompiledLibrary(it) }, - ) + ) { if (it == mainModuleLib) moduleDescriptor else testServices.jsLibraryProvider.getDescriptorByCompiledLibrary(it) } } private fun loadIrFromSources( @@ -254,14 +248,11 @@ class JsIrBackendFacade( inputArtifact.allKtFiles.values.toList(), sortDependencies(JsEnvironmentConfigurator.getAllRecursiveLibrariesFor(module, testServices)), emptyMap(), - emptyMap(), symbolTable, messageLogger, loadFunctionInterfacesIntoStdlib = true, verifySignatures, - { emptySet() }, - { testServices.jsLibraryProvider.getDescriptorByCompiledLibrary(it) }, - ) + ) { testServices.jsLibraryProvider.getDescriptorByCompiledLibrary(it) } } private fun jsOutputSink(perFileOutputDir: File): CompilerOutputSink { diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/AbstractJsIrTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/AbstractJsIrTest.kt index e6407572cc2..945d0822b7a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/AbstractJsIrTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/AbstractJsIrTest.kt @@ -53,7 +53,6 @@ abstract class AbstractJsIrTest( defaultDirectives { val runIc = getBoolean("kotlin.js.ir.icMode") if (runIc) +JsEnvironmentConfigurationDirectives.RUN_IC - if (runIc || getBoolean("kotlin.js.ir.lowerPerModule")) +JsEnvironmentConfigurationDirectives.LOWER_PER_MODULE if (getBoolean("kotlin.js.ir.klibMainModule")) +JsEnvironmentConfigurationDirectives.KLIB_MAIN_MODULE if (getBoolean("kotlin.js.ir.perModule", true)) +JsEnvironmentConfigurationDirectives.PER_MODULE if (getBoolean("kotlin.js.ir.dce", true)) +JsEnvironmentConfigurationDirectives.RUN_IR_DCE diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/JsIrIncrementalDataProvider.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/JsIrIncrementalDataProvider.kt index b581b7c4dda..b43e0e1d53a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/JsIrIncrementalDataProvider.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/JsIrIncrementalDataProvider.kt @@ -37,10 +37,6 @@ class TestModuleCache(val files: MutableMap) { return 0L } - override fun serializedParts(path: String): SerializedIcDataForFile { - error("Is not supported") - } - override fun inlineGraphForFile(path: String, sigResolver: (Int) -> IdSignature): Collection> { error("Is not supported") } @@ -97,10 +93,6 @@ class TestModuleCache(val files: MutableMap) { } - override fun commitICCacheData(path: String, icData: SerializedIcDataForFile) { - - } - override fun commitBinaryAst(path: String, astData: ByteArray) { val storage = files.getOrPut(path) { FileCache(path, null, null, null) } storage.ast = astData diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/ApiTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/ApiTest.kt index 7f3d6c7f409..55e5a268953 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/ApiTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/ApiTest.kt @@ -77,10 +77,7 @@ class ApiTest : KotlinTestWithEnvironment() { MainModule.Klib(File(fullRuntimeKlib).canonicalPath), configuration, listOf(fullRuntimeKlib), - emptyList(), - false, - false, - emptyMap() + emptyList() ) return loadIr(