From fde71918edf4de51961dd546dc31b985dda0f970 Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Wed, 21 Dec 2022 17:39:01 +0100 Subject: [PATCH] [JS IR IC] Write only modified JS files Optimization: the patch allows copying and overwriting only modified JS files during the compilation output writing routine. --- .../ir/backend/js/ic/JsExecutableProducer.kt | 3 +- .../ir/backend/js/ic/JsMultiModuleCache.kt | 5 ++- .../transformers/irToJs/CompilationOutputs.kt | 44 ++++++++++++++++++- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsExecutableProducer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsExecutableProducer.kt index 96423f14b8e..a8e03c35f29 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsExecutableProducer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsExecutableProducer.kt @@ -86,9 +86,8 @@ class JsExecutableProducer( ) stopwatch.startNext("Committing compiled JS code") - jsMultiModuleCache.commitCompiledJsCode(artifact, compiledModule) rebuildModules += moduleName - return compiledModule + return jsMultiModuleCache.commitCompiledJsCode(artifact, compiledModule) } val cachedMainModule = cachedProgram.last() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsMultiModuleCache.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsMultiModuleCache.kt index daa31c8d3d0..d32c2caae8d 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsMultiModuleCache.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsMultiModuleCache.kt @@ -102,13 +102,14 @@ class JsMultiModuleCache(private val moduleArtifacts: List) { jsCodeFilePath?.let { CompilationOutputsCached(it, sourceMapFilePath, tsDefinitionsFilePath) } } - fun commitCompiledJsCode(artifact: ModuleArtifact, compilationOutputs: CompilationOutputsBuilt) = + fun commitCompiledJsCode(artifact: ModuleArtifact, compilationOutputs: CompilationOutputsBuilt): CompilationOutputs = artifact.artifactsDir?.let { cacheDir -> val jsCodeFile = File(cacheDir, CACHED_MODULE_JS) val jsMapFile = File(cacheDir, CACHED_MODULE_JS_MAP) compilationOutputs.writeJsCode(jsCodeFile, jsMapFile) File(cacheDir, CACHED_MODULE_D_TS).writeIfNotNull(compilationOutputs.tsDefinitions?.raw) - } + CompilationOutputsBuiltForCache(jsCodeFile.absolutePath, jsMapFile.absolutePath, compilationOutputs) + } ?: compilationOutputs fun loadProgramHeadersFromCache(): List { return moduleArtifacts.map { artifact -> diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/CompilationOutputs.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/CompilationOutputs.kt index ea1baadebff..4855d56a1e1 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/CompilationOutputs.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/CompilationOutputs.kt @@ -74,6 +74,13 @@ class CompilationOutputsBuilt( } } +private fun File.copyModificationTimeFrom(from: File) { + val mtime = from.lastModified() + if (mtime > 0) { + setLastModified(mtime) + } +} + class CompilationOutputsCached( private val jsCodeFilePath: String, private val sourceMapFilePath: String?, @@ -86,10 +93,43 @@ class CompilationOutputsCached( get() = null override fun writeJsCode(outputJsFile: File, outputJsMapFile: File) { - File(jsCodeFilePath).copyTo(outputJsFile, true) + File(jsCodeFilePath).copyToIfModified(outputJsFile) sourceMapFilePath?.let { - File(it).copyTo(outputJsMapFile, true) + File(it).copyToIfModified(outputJsMapFile) + } + } + + private fun File.copyToIfModified(target: File) { + val thisMtime = lastModified() + val targetMtime = target.lastModified() + if (thisMtime <= 0 || targetMtime <= 0 || targetMtime > thisMtime) { + copyTo(target, true) + copyModificationTimeFrom(target) } } } + +class CompilationOutputsBuiltForCache( + private val jsCodeFilePath: String, + private val sourceMapFilePath: String, + private val outputBuilt: CompilationOutputsBuilt +) : CompilationOutputs() { + + init { + dependencies = outputBuilt.dependencies + } + + override val tsDefinitions: TypeScriptFragment? + get() = outputBuilt.tsDefinitions + + override val jsProgram: JsProgram? + get() = outputBuilt.jsProgram + + override fun writeJsCode(outputJsFile: File, outputJsMapFile: File) { + outputBuilt.writeJsCode(outputJsFile, outputJsMapFile) + + File(jsCodeFilePath).copyModificationTimeFrom(outputJsFile) + File(sourceMapFilePath).copyModificationTimeFrom(outputJsMapFile) + } +}