Skip to content

Commit aff0cac

Browse files
authored
Check NodeJs and D8 versions before adding --experimental-wasm-gc (#213)
Starting from version 22, NodeJS is shipped with the V8 that no longer accepts --experimental-wasm-gc flag. The option disappeared from V8 somewhere around 12.3.68. To avoid errors when running benchmarks with recent NodeJS/D8 version, plugin now checks runtime's version and appends --experimental-wasm-gc flag only when needed. Closes #212
1 parent 4c7af65 commit aff0cac

File tree

10 files changed

+136
-7
lines changed

10 files changed

+136
-7
lines changed

integration/src/main/kotlin/kotlinx/benchmark/integration/ProjectBuilder.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ class ProjectBuilder {
44
private val configurations = mutableMapOf<String, BenchmarkConfiguration>()
55
private val targets = mutableMapOf<String, BenchmarkTarget>()
66

7+
var kotlinVersion: String = System.getProperty("kotlin_version")
8+
79
fun configuration(name: String, configuration: BenchmarkConfiguration.() -> Unit = {}) {
810
configurations[name] = BenchmarkConfiguration().apply(configuration)
911
}
@@ -25,15 +27,15 @@ benchmark {
2527
}
2628
""".trimIndent()
2729

28-
return buildScript + "\n\n" + original + "\n\n" + script
30+
return generateBuildScript(kotlinVersion) + "\n\n" + original + "\n\n" + script
2931
}
3032
}
3133

3234
private val kotlin_repo = System.getProperty("kotlin_repo_url").let {
3335
if (it.isNullOrBlank()) "" else "maven { url '$it' }"
3436
}
3537

36-
private val buildScript =
38+
private fun generateBuildScript(kotlinVersion: String) =
3739
"""
3840
buildscript {
3941
repositories {
@@ -42,7 +44,7 @@ private val buildScript =
4244
mavenCentral()
4345
}
4446
dependencies {
45-
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:${System.getProperty("kotlin_version")}'
47+
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion'
4648
classpath 'org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.5.0-SNAPSHOT'
4749
}
4850
}

integration/src/test/kotlin/kotlinx/benchmark/integration/GradleTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ abstract class GradleTest {
2121
name: String,
2222
print: Boolean = false,
2323
gradleVersion: GradleTestVersion? = null,
24+
kotlinVersion: String? = null,
2425
build: ProjectBuilder.() -> Unit = {}
2526
): Runner {
26-
val builder = ProjectBuilder().apply(build)
27+
val builder = ProjectBuilder().apply {
28+
kotlinVersion?.let { this.kotlinVersion = it }
29+
}.apply(build)
2730
templates.resolve(name).copyRecursively(rootProjectDir)
2831
file("build.gradle").modify(builder::build)
2932
val settingsFile = file("settings.gradle")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package kotlinx.benchmark.integration
2+
3+
import org.junit.Test
4+
5+
class WasmGcOptionsTest : GradleTest() {
6+
@Test
7+
fun nodeJs() {
8+
// The test uses Kotlin 1.9.24 as previous versions
9+
// would append the --experimental-wasm-gc flag causing run failures.
10+
val runner = project(
11+
"wasm-gc-non-experimental/wasm-nodejs", true, kotlinVersion = "1.9.24"
12+
)
13+
runner.run("wasmJsBenchmark")
14+
}
15+
16+
@Test
17+
fun d8() {
18+
// The test uses Kotlin 1.9.24 as previous versions
19+
// would append the --experimental-wasm-gc flag causing run failures.
20+
val runner = project(
21+
"wasm-gc-non-experimental/wasm-d8", true, kotlinVersion = "1.9.24"
22+
)
23+
runner.run( "wasmJsBenchmark")
24+
}
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import org.jetbrains.kotlin.gradle.targets.js.d8.D8RootExtension
2+
3+
kotlin {
4+
wasm('wasmJs') {
5+
d8()
6+
}
7+
8+
sourceSets {
9+
commonMain {
10+
dependencies {
11+
implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.5.0-SNAPSHOT")
12+
}
13+
}
14+
wasmJsMain {
15+
}
16+
}
17+
}
18+
19+
benchmark {
20+
targets {
21+
register("wasmJs")
22+
}
23+
}
24+
25+
rootProject.extensions.getByType(D8RootExtension).version = "12.6.99"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.gradle.jvmargs=-Xmx2g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package test
2+
3+
import kotlinx.benchmark.*
4+
import kotlin.math.*
5+
6+
@State(Scope.Benchmark)
7+
@Measurement(iterations = 3, time = 1, timeUnit = BenchmarkTimeUnit.SECONDS)
8+
@OutputTimeUnit(BenchmarkTimeUnit.MILLISECONDS)
9+
@BenchmarkMode(Mode.Throughput)
10+
open class CommonBenchmark {
11+
@Benchmark
12+
open fun mathBenchmark(): Double {
13+
return log(sqrt(3.0) * cos(3.0), 2.0)
14+
}
15+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
2+
3+
kotlin {
4+
wasm('wasmJs') {
5+
nodejs()
6+
}
7+
8+
sourceSets {
9+
commonMain {
10+
dependencies {
11+
implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.5.0-SNAPSHOT")
12+
}
13+
}
14+
wasmJsMain {
15+
}
16+
}
17+
}
18+
19+
benchmark {
20+
targets {
21+
register("wasmJs")
22+
}
23+
}
24+
25+
rootProject.extensions.getByType(NodeJsRootExtension).nodeVersion = "22.1.0"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.gradle.jvmargs=-Xmx2g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package test
2+
3+
import kotlinx.benchmark.*
4+
import kotlin.math.*
5+
6+
@State(Scope.Benchmark)
7+
@Measurement(iterations = 3, time = 1, timeUnit = BenchmarkTimeUnit.SECONDS)
8+
@OutputTimeUnit(BenchmarkTimeUnit.MILLISECONDS)
9+
@BenchmarkMode(Mode.Throughput)
10+
open class CommonBenchmark {
11+
@Benchmark
12+
open fun mathBenchmark(): Double {
13+
return log(sqrt(3.0) * cos(3.0), 2.0)
14+
}
15+
}

plugin/main/src/kotlinx/benchmark/gradle/JsEngineExecTasks.kt

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import org.gradle.api.*
66
import org.gradle.api.file.RegularFile
77
import org.gradle.api.provider.Provider
88
import org.gradle.api.tasks.TaskProvider
9+
import org.gradle.util.internal.VersionNumber
910
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
1011
import org.jetbrains.kotlin.gradle.targets.js.d8.D8Exec
12+
import org.jetbrains.kotlin.gradle.targets.js.d8.D8RootExtension
1113
import org.jetbrains.kotlin.gradle.targets.js.dsl.*
1214
import org.jetbrains.kotlin.gradle.targets.js.ir.*
1315
import org.jetbrains.kotlin.gradle.targets.js.nodejs.*
@@ -65,7 +67,7 @@ private fun Project.getExecutableFile(compilation: KotlinJsIrCompilation): Provi
6567
private val KotlinJsIrCompilation.isWasmCompilation: Boolean get() =
6668
target.platformType == KotlinPlatformType.wasm
6769

68-
private fun MutableList<String>.addWasmArguments() {
70+
private fun MutableList<String>.addWasmGcArguments() {
6971
add("--experimental-wasm-gc")
7072
}
7173

@@ -86,7 +88,15 @@ private fun Project.createNodeJsExec(
8688
inputFileProperty.set(getExecutableFile(compilation))
8789
with(nodeArgs) {
8890
if (compilation.isWasmCompilation) {
89-
addWasmArguments()
91+
val addGcArgs = rootProject.extensions.findByType(NodeJsRootExtension::class.java)?.let {
92+
val nodeVersion = VersionNumber.parse(it.nodeVersion)
93+
// Starting from version 22, NodeJS is shipped with V8 versions
94+
// that no longer accept --experimental-wasm-gc argument.
95+
nodeVersion.major < 22
96+
} ?: true
97+
if (addGcArgs) {
98+
addWasmGcArguments()
99+
}
90100
} else {
91101
addJsArguments()
92102
}
@@ -106,7 +116,14 @@ private fun Project.createD8Exec(
106116
description = "Executes benchmark for '${target.name}' with D8"
107117
inputFileProperty.set(getExecutableFile(compilation))
108118
if (compilation.isWasmCompilation) {
109-
d8Args.addWasmArguments()
119+
val addGcArgs = rootProject.extensions.findByType(D8RootExtension::class.java)?.let {
120+
val d8Version = VersionNumber.parse(it.version)
121+
// --experimental-wasm-gc flag was removed from V8 starting from ~ 12.3.68
122+
d8Version < VersionNumber(12, 3, 68, null)
123+
} ?: true
124+
if (addGcArgs) {
125+
d8Args.addWasmGcArguments()
126+
}
110127
}
111128
val reportFile = setupReporting(target, config)
112129
args(writeParameters(target.name, reportFile, traceFormat(), config))

0 commit comments

Comments
 (0)