[JS IR IC] Do not read non modified JS into memory
Optimizaion: instead of reading all non modified JS files from the cache into the memory at once, the patch allows copying non-modified JS files from disk one by one during the compilation output writing routine.
This commit is contained in:
committed by
Space Team
parent
dd268d67ff
commit
75931fb9c8
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.SourceMapsInfo
|
||||
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CompilationOutputs
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.safeModuleName
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC
|
||||
@@ -225,16 +226,6 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
||||
writeText(ClassicJsBackendFacade.wrapWithModuleEmulationMarkers(jsCode, JS_MODULE_KIND, moduleName))
|
||||
}
|
||||
|
||||
private fun writeJsFile(name: String, text: String): String {
|
||||
val moduleFileName = "./$name.js"
|
||||
val file = File(jsDir, moduleFileName)
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
}
|
||||
file.writeAsJsModule(text, moduleFileName)
|
||||
return file.canonicalPath
|
||||
}
|
||||
|
||||
private fun prepareExternalJsFiles(): MutableList<String> {
|
||||
jsDir.invalidateDir()
|
||||
return testDir.filesInDir.mapNotNullTo(mutableListOf(MODULE_EMULATION_FILE)) { file ->
|
||||
@@ -249,12 +240,15 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
||||
|
||||
private fun verifyJsCode(stepId: Int, mainModuleName: String, jsOutput: CompilationOutputs) {
|
||||
val files = prepareExternalJsFiles()
|
||||
jsOutput.dependencies.mapTo(files) { writeJsFile(it.first, it.second.jsCode) }
|
||||
files += writeJsFile(mainModuleName, jsOutput.jsCode)
|
||||
val compiledJsFiles = jsOutput.writeAll(jsDir, mainModuleName, true, mainModuleName, JS_MODULE_KIND)
|
||||
for (jsCodeFile in compiledJsFiles) {
|
||||
val jsFile = File(jsCodeFile)
|
||||
jsFile.writeAsJsModule(jsFile.readText(), "./${jsFile.name}")
|
||||
}
|
||||
|
||||
try {
|
||||
V8IrJsTestChecker.checkWithTestFunctionArgs(
|
||||
files = files,
|
||||
files = files + compiledJsFiles,
|
||||
testModuleName = "./$mainModuleName.js",
|
||||
testPackageName = null,
|
||||
testFunctionName = BOX_FUNCTION_NAME,
|
||||
@@ -269,11 +263,16 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun verifyDTS(stepId: Int, testInfo: List<TestStepInfo>, jsOutput: CompilationOutputs) {
|
||||
private fun verifyDTS(stepId: Int, testInfo: List<TestStepInfo>) {
|
||||
for (info in testInfo) {
|
||||
val expectedDTS = info.expectedDTS ?: continue
|
||||
val output = jsOutput.dependencies.find { it.first == info.moduleName }?.second ?: jsOutput
|
||||
val gotDTS = output.getFullTsDefinition(info.moduleName, JS_MODULE_KIND)
|
||||
|
||||
val dtsFile = jsDir.resolve("${File(info.modulePath).nameWithoutExtension}.d.ts")
|
||||
JUnit4Assertions.assertTrue(dtsFile.exists()) {
|
||||
"Cannot find d.ts (${dtsFile.absolutePath}) file for module ${info.moduleName} at step $stepId"
|
||||
}
|
||||
|
||||
val gotDTS = dtsFile.readText()
|
||||
JUnit4Assertions.assertEquals(expectedDTS, gotDTS) {
|
||||
"Mismatched d.ts for module ${info.moduleName} at step $stepId"
|
||||
}
|
||||
@@ -320,7 +319,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
||||
val (jsOutput, rebuiltModules) = jsExecutableProducer.buildExecutable(multiModule = true, outJsProgram = true)
|
||||
verifyJsExecutableProducerBuildModules(projStep.id, rebuiltModules, projStep.dirtyJS)
|
||||
verifyJsCode(projStep.id, mainModuleName, jsOutput)
|
||||
verifyDTS(projStep.id, testInfo, jsOutput)
|
||||
verifyDTS(projStep.id, testInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.backend.js.ic.JsExecutableProducer
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||
import org.jetbrains.kotlin.ir.backend.js.SourceMapsInfo
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CompilationOutputs
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC
|
||||
@@ -36,6 +37,7 @@ import org.jetbrains.kotlin.test.frontend.classic.moduleDescriptorProvider
|
||||
import org.jetbrains.kotlin.test.model.*
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
|
||||
import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
|
||||
import java.io.File
|
||||
|
||||
@@ -256,17 +258,28 @@ class JsIrBackendFacade(
|
||||
return this
|
||||
}
|
||||
|
||||
fun File.fixJsFile(newJsTarget: File, moduleId: String, moduleKind: ModuleKind) {
|
||||
val newJsCode = ClassicJsBackendFacade.wrapWithModuleEmulationMarkers(readText(), moduleKind, moduleId)
|
||||
|
||||
val oldJsMap = File("$absolutePath.map")
|
||||
val jsCodeMap = (moduleKind == ModuleKind.PLAIN && oldJsMap.exists()).ifTrue { oldJsMap.readText() }
|
||||
|
||||
this.delete()
|
||||
oldJsMap.delete()
|
||||
|
||||
newJsTarget.write(newJsCode)
|
||||
jsCodeMap?.let { File("${newJsTarget.absolutePath}.map").write(it) }
|
||||
}
|
||||
|
||||
private fun CompilationOutputs.writeTo(outputFile: File, moduleId: String, moduleKind: ModuleKind) {
|
||||
val wrappedCode = ClassicJsBackendFacade.wrapWithModuleEmulationMarkers(jsCode, moduleId = moduleId, moduleKind = moduleKind)
|
||||
outputFile.write(wrappedCode)
|
||||
val allJsFiles = writeAll(outputFile.parentFile, outputFile.nameWithoutExtension, false, moduleId, moduleKind)
|
||||
|
||||
if (moduleKind == ModuleKind.PLAIN) {
|
||||
writeSourceMapIfPresent(outputFile)
|
||||
}
|
||||
val mainModuleFile = File(allJsFiles.last())
|
||||
mainModuleFile.fixJsFile(outputFile, moduleId, moduleKind)
|
||||
|
||||
dependencies.forEach { (moduleId, outputs) ->
|
||||
val moduleWrappedCode = ClassicJsBackendFacade.wrapWithModuleEmulationMarkers(outputs.jsCode, moduleKind, moduleId)
|
||||
outputFile.augmentWithModuleName(moduleId).write(moduleWrappedCode)
|
||||
dependencies.map { it.first }.zip(allJsFiles.dropLast(1)).forEach { (depModuleId, builtJsFilePath) ->
|
||||
val newFile = outputFile.augmentWithModuleName(depModuleId)
|
||||
File(builtJsFilePath).fixJsFile(newFile, depModuleId, moduleKind)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.test.handlers
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.CompilationOutputs
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CompilationOutputs
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.safeModuleName
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsProgram
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.CacheUpdater
|
||||
import org.jetbrains.kotlin.ir.backend.js.ic.JsExecutableProducer
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CompilationOutputs
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
@@ -168,19 +169,10 @@ abstract class AbstractJsKLibABITestCase : KtUsefulTestCase() {
|
||||
buildBinaryNoIC(configuration, mainModuleKlibFile, allDependencies)
|
||||
|
||||
val binariesDir = File(buildDir, BIN_DIR_NAME).also { it.mkdirs() }
|
||||
val binaries = ArrayList<File>(allDependencies.regularDependencies.size)
|
||||
|
||||
for ((name, code) in compilationOutputs.dependencies) {
|
||||
val depBinary = binariesDir.binJsFile(name)
|
||||
depBinary.parentFile?.let { if (!it.exists()) it.mkdirs() }
|
||||
depBinary.writeText(code.jsCode)
|
||||
binaries.add(depBinary)
|
||||
val binaries = compilationOutputs.writeAll(binariesDir, MAIN_MODULE_NAME, false, MAIN_MODULE_NAME, ModuleKind.PLAIN).map {
|
||||
File(it)
|
||||
}
|
||||
|
||||
val mainBinary = binariesDir.binJsFile(MAIN_MODULE_NAME)
|
||||
mainBinary.writeText(compilationOutputs.jsCode)
|
||||
binaries.add(mainBinary)
|
||||
|
||||
executeAndCheckBinaries(MAIN_MODULE_NAME, binaries)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user