Skip to content

Commit c24e59a

Browse files
ilgonmicwoainikk
authored andcommitted
feat: ir ic (#604)
* Enable gzip * process source module * Support IC caches * Init IC caches * Prepare IC caches and copy it inside a request
1 parent c5c73df commit c24e59a

File tree

13 files changed

+281
-45
lines changed

13 files changed

+281
-45
lines changed

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ FROM openjdk:11.0.16-jdk as build
22

33
ENV KOTLIN_LIB=1.8.20-Beta
44
ENV KOTLIN_LIB_JS=1.8.20-Beta-js
5+
ENV KOTLIN_CACHES_JS=1.8.20-Beta-js-caches
56

67
RUN mkdir -p /kotlin-compiler-server
78
WORKDIR /kotlin-compiler-server
@@ -20,6 +21,7 @@ COPY --from=build /build/libs/META-INF /kotlin-compiler-server/META-INF
2021
COPY --from=build /build/libs/BOOT-INF/classes /kotlin-compiler-server
2122
COPY --from=build /kotlin-compiler-server/${KOTLIN_LIB} /kotlin-compiler-server/${KOTLIN_LIB}
2223
COPY --from=build /kotlin-compiler-server/${KOTLIN_LIB_JS} /kotlin-compiler-server/${KOTLIN_LIB_JS}
24+
COPY --from=build /kotlin-compiler-server/${KOTLIN_CACHES_JS} /kotlin-compiler-server/${KOTLIN_CACHES_JS}
2325
COPY --from=build /kotlin-compiler-server/executor.policy /kotlin-compiler-server/
2426
COPY --from=build /kotlin-compiler-server/indexes.json /kotlin-compiler-server/
2527

build.gradle.kts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,31 @@ val kotlinJsDependency: Configuration by configurations.creating {
2525
)
2626
attribute(
2727
KotlinJsCompilerAttribute.jsCompilerAttribute,
28-
KotlinJsCompilerAttribute.legacy
28+
KotlinJsCompilerAttribute.ir
2929
)
3030
}
3131
}
32+
33+
val kotlinJsIcCache: Configuration by configurations.creating {
34+
isTransitive = false
35+
attributes {
36+
attribute(
37+
KotlinPlatformType.attribute,
38+
KotlinPlatformType.js
39+
)
40+
attribute(
41+
KotlinJsCompilerAttribute.jsCompilerAttribute,
42+
KotlinJsCompilerAttribute.ir
43+
)
44+
attribute(
45+
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
46+
objects.named(LibraryElements::class.java, "js-ir-cache")
47+
)
48+
}
49+
}
50+
3251
val libJSFolder = "$kotlinVersion-js"
52+
val libJSCachesFolder = "$kotlinVersion-js-caches"
3353
val libJVMFolder = kotlinVersion
3454
val propertyFile = "application.properties"
3555
val jacksonVersionKotlinDependencyJar = "2.14.0" // don't forget to update version in `executor.policy` file.
@@ -43,6 +63,11 @@ val copyJSDependencies by tasks.creating(Copy::class) {
4363
into(libJSFolder)
4464
}
4565

66+
val copyJSCaches by tasks.creating(Copy::class) {
67+
from(kotlinJsIcCache)
68+
into(libJSCachesFolder)
69+
}
70+
4671
plugins {
4772
id("org.springframework.boot") version "2.7.9"
4873
id("io.spring.dependency-management") version "1.1.0"
@@ -87,6 +112,8 @@ dependencies {
87112
kotlinDependency("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4")
88113
kotlinJsDependency("org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion")
89114

115+
kotlinJsIcCache(project(":cache-preparator"))
116+
90117
annotationProcessor("org.springframework:spring-context-indexer")
91118
implementation("org.springframework.boot:spring-boot-starter-web")
92119
implementation("com.amazonaws.serverless:aws-serverless-java-container-springboot2:1.9.1")
@@ -131,7 +158,10 @@ fun generateProperties(prefix: String = "") = """
131158
indexesJs.file=${prefix + indexesJs}
132159
libraries.folder.jvm=${prefix + libJVMFolder}
133160
libraries.folder.js=${prefix + libJSFolder}
161+
caches.folder.js=${prefix + libJSCachesFolder}
134162
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
163+
server.compression.enabled=true
164+
server.compression.mime-types=application/json
135165
""".trimIndent()
136166

137167
tasks.withType<KotlinCompile> {
@@ -141,6 +171,7 @@ tasks.withType<KotlinCompile> {
141171
}
142172
dependsOn(copyDependencies)
143173
dependsOn(copyJSDependencies)
174+
dependsOn(copyJSCaches)
144175
dependsOn(":executors:jar")
145176
dependsOn(":indexation:run")
146177
buildPropertyFile()

cache-preparator/build.gradle.kts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
2+
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
3+
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
4+
import org.jetbrains.kotlin.gradle.targets.js.ir.JsIrBinary
5+
6+
plugins {
7+
kotlin("multiplatform")
8+
}
9+
10+
val kotlinJsDependency by rootProject.configurations
11+
12+
kotlin {
13+
js(IR) {
14+
nodejs()
15+
val executables = binaries.executable()
16+
val main by compilations.getting
17+
main.configurations.apiConfiguration.extendsFrom(kotlinJsDependency)
18+
19+
val jsCaches by configurations.creating {
20+
isVisible = false
21+
isCanBeResolved = false
22+
isCanBeConsumed = true
23+
24+
attributes {
25+
attribute(
26+
KotlinPlatformType.attribute,
27+
KotlinPlatformType.js
28+
)
29+
attribute(
30+
KotlinJsCompilerAttribute.jsCompilerAttribute,
31+
KotlinJsCompilerAttribute.ir
32+
)
33+
attribute(
34+
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
35+
objects.named(LibraryElements::class.java, "js-ir-cache")
36+
)
37+
}
38+
}
39+
40+
val linkTask = executables
41+
.filterIsInstance<JsIrBinary>()
42+
.single { it.mode == KotlinJsBinaryMode.DEVELOPMENT }
43+
.linkTask
44+
45+
val rootCacheDir = linkTask
46+
.map { it.rootCacheDirectory }
47+
48+
artifacts.add(jsCaches.name, rootCacheDir) {
49+
builtBy(linkTask)
50+
}
51+
}
52+
}
53+
54+
// just to calm down root project's allprojects block
55+
configurations.register("implementation")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fun main() {
2+
println("Hello, world")
3+
}

common/src/main/kotlin/component/KotlinEnvironment.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import java.io.File
2828

2929
class KotlinEnvironment(
3030
val classpath: List<File>,
31-
additionalJsClasspath: List<File>
31+
additionalJsClasspath: List<File>,
32+
val cachesJsDir: File
3233
) {
3334
companion object {
3435
/**

indexation/src/main/kotlin/KotlinEnvironmentConfiguration.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class KotlinEnvironmentConfiguration(fileName: String) {
77
val kotlinEnvironment = run {
88
val jvmFile = File(fileName)
99
val jsFile = File("$fileName-js")
10+
val cachesJsDir = File("$fileName-js-caches")
1011
val classPath =
1112
listOfNotNull(jvmFile)
1213
.flatMap {
@@ -15,6 +16,6 @@ class KotlinEnvironmentConfiguration(fileName: String) {
1516
}
1617

1718
val additionalJsClasspath = listOfNotNull(jsFile)
18-
KotlinEnvironment(classPath, additionalJsClasspath)
19+
KotlinEnvironment(classPath, additionalJsClasspath, cachesJsDir)
1920
}
2021
}

settings.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
rootProject.name = "kotlin-compiler-server"
22
include(":executors")
33
include(":indexation")
4-
include(":common")
4+
include(":common")
5+
include(":cache-preparator")
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.compiler.server.compiler.components
2+
3+
import com.intellij.openapi.project.Project
4+
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
5+
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
6+
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
7+
import org.jetbrains.kotlin.cli.js.klib.generateIrForKlibSerialization
8+
import org.jetbrains.kotlin.config.CompilerConfiguration
9+
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
10+
import org.jetbrains.kotlin.ir.backend.js.*
11+
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
12+
import org.jetbrains.kotlin.ir.backend.js.ic.CacheUpdater
13+
import org.jetbrains.kotlin.ir.backend.js.ic.DirtyFileState
14+
import org.jetbrains.kotlin.ir.backend.js.ic.ModuleArtifact
15+
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
16+
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC
17+
import org.jetbrains.kotlin.ir.symbols.IrSymbol
18+
import org.jetbrains.kotlin.psi.KtFile
19+
import java.io.File
20+
21+
// copy from compiler private funs
22+
23+
fun processSourceModule(
24+
project: Project,
25+
files: List<KtFile>,
26+
libraries: List<String>,
27+
friendLibraries: List<String>,
28+
configuration: CompilerConfiguration,
29+
outputKlibPath: String
30+
): ModulesStructure {
31+
val sourceModule: ModulesStructure = prepareAnalyzedSourceModule(
32+
project,
33+
files,
34+
configuration,
35+
libraries,
36+
friendLibraries,
37+
AnalyzerWithCompilerReport(configuration)
38+
)
39+
40+
val moduleSourceFiles = (sourceModule.mainModule as MainModule.SourceFiles).files
41+
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
42+
43+
val (moduleFragment, _) = generateIrForKlibSerialization(
44+
project,
45+
moduleSourceFiles,
46+
configuration,
47+
sourceModule.jsFrontEndResult.jsAnalysisResult,
48+
sourceModule.allDependencies.map { it.library },
49+
emptyList(),
50+
expectDescriptorToSymbol,
51+
IrFactoryImpl,
52+
verifySignatures = true
53+
) {
54+
sourceModule.getModuleDescriptor(it)
55+
}
56+
57+
val metadataSerializer =
58+
KlibMetadataIncrementalSerializer(
59+
configuration,
60+
sourceModule.project,
61+
sourceModule.jsFrontEndResult.hasErrors
62+
)
63+
64+
generateKLib(
65+
sourceModule,
66+
outputKlibPath,
67+
nopack = true,
68+
jsOutputName = null,
69+
icData = emptyList(),
70+
expectDescriptorToSymbol = expectDescriptorToSymbol,
71+
moduleFragment = moduleFragment
72+
) { file ->
73+
metadataSerializer.serializeScope(file, sourceModule.jsFrontEndResult.bindingContext, moduleFragment.descriptor)
74+
}
75+
return sourceModule
76+
}
77+
78+
fun prepareIcCaches(
79+
includes: String,
80+
cacheDirectory: String,
81+
libraries: List<String>,
82+
friendLibraries: List<String>,
83+
configurationJs: CompilerConfiguration,
84+
): List<ModuleArtifact> {
85+
val cacheUpdater = CacheUpdater(
86+
mainModule = includes,
87+
allModules = libraries,
88+
mainModuleFriends = friendLibraries,
89+
cacheDir = cacheDirectory,
90+
compilerConfiguration = configurationJs,
91+
irFactory = { IrFactoryImplForJsIC(WholeWorldStageController()) },
92+
mainArguments = emptyList(),
93+
compilerInterfaceFactory = { mainModule, cfg ->
94+
JsIrCompilerWithIC(
95+
mainModule,
96+
cfg,
97+
JsGenerationGranularity.WHOLE_PROGRAM,
98+
es6mode = false
99+
)
100+
}
101+
)
102+
103+
return cacheUpdater.actualizeCaches()
104+
}

src/main/kotlin/com/compiler/server/compiler/components/KotlinEnvironment.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.compiler.server.compiler.components
22

3+
import com.compiler.server.model.bean.CachesFile
34
import com.compiler.server.model.bean.LibrariesFile
45
import component.KotlinEnvironment
56
import org.springframework.context.annotation.Bean
67
import org.springframework.context.annotation.Configuration
78

89
@Configuration
9-
class KotlinEnvironmentConfiguration(val librariesFile: LibrariesFile) {
10+
class KotlinEnvironmentConfiguration(
11+
val librariesFile: LibrariesFile,
12+
val cachesFiles: CachesFile
13+
) {
1014
@Bean
1115
fun kotlinEnvironment(): KotlinEnvironment {
1216
val classPath =
@@ -17,6 +21,6 @@ class KotlinEnvironmentConfiguration(val librariesFile: LibrariesFile) {
1721
}
1822

1923
val additionalJsClasspath = listOfNotNull(librariesFile.js)
20-
return KotlinEnvironment(classPath, additionalJsClasspath)
24+
return KotlinEnvironment(classPath, additionalJsClasspath, cachesFiles.js)
2125
}
2226
}

0 commit comments

Comments
 (0)