Skip to content

Commit 20fb95f

Browse files
committed
Wasm implementation
1 parent 855667b commit 20fb95f

36 files changed

+738
-174
lines changed

examples/kotlin-multiplatform/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ kotlin {
1616
jvm()
1717
js('jsIr', IR) { nodejs() }
1818
js { nodejs() }
19+
wasm { d8() }
1920
if (HostManager.host == KonanTarget.MACOS_X64.INSTANCE) macosX64('native')
2021
if (HostManager.host == KonanTarget.MACOS_ARM64.INSTANCE) macosArm64('native')
2122
if (HostManager.hostIsLinux) linuxX64('native')
@@ -36,6 +37,8 @@ kotlin {
3637

3738
jvmMain {}
3839

40+
wasmMain {}
41+
3942
jsMain {
4043
jsIrMain.dependsOn(it)
4144
}
@@ -101,6 +104,7 @@ benchmark {
101104
}
102105
register("jsIr")
103106
register("js")
107+
register("wasm")
104108
register("native")
105109
}
106110
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package test
2+
3+
import kotlinx.benchmark.*
4+
import kotlin.math.*
5+
6+
@State(Scope.Benchmark)
7+
class WasmTestBenchmark {
8+
private var data = 0.0
9+
10+
@Setup
11+
fun setUp() {
12+
data = 3.0
13+
}
14+
15+
@Benchmark
16+
fun sqrtBenchmark(): Double {
17+
return sqrt(data)
18+
}
19+
20+
@Benchmark
21+
fun cosBenchmark(): Double {
22+
return cos(data)
23+
}
24+
}
25+
26+

integration/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ val createClasspathManifest by tasks.registering {
5454
dependsOn(artifactsTask("jvm"))
5555
dependsOn(artifactsTask("jsIr"))
5656
dependsOn(artifactsTask("jsLegacy"))
57+
dependsOn(artifactsTask("wasm"))
5758
dependsOn(artifactsTask("metadata"))
5859
dependsOn(artifactsTaskNativeKlibs())
5960

@@ -67,6 +68,7 @@ val createClasspathManifest by tasks.registering {
6768
resolve("runtime-jvm.txt").writeText(artifactsTask("jvm").archiveFilePath)
6869
resolve("runtime-jsIr.txt").writeText(artifactsTask("jsIr").archiveFilePath)
6970
resolve("runtime-js.txt").writeText(artifactsTask("jsLegacy").archiveFilePath)
71+
resolve("runtime-wasm.txt").writeText(artifactsTask("wasm").archiveFilePath)
7072
resolve("runtime-native.txt").writeText(artifactsTaskNativeKlibs().klibs())
7173
}
7274
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ private val buildScript = run {
3737
3838
repositories {
3939
mavenCentral()
40+
maven { url 'https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap' }
4041
}
4142
4243
def benchmarkRuntimeMetadata = files(${readFileList("runtime-metadata.txt")})
4344
def benchmarkRuntimeJvm = files(${readFileList("runtime-jvm.txt")})
4445
def benchmarkRuntimeJsIr = files(${readFileList("runtime-jsIr.txt")})
4546
def benchmarkRuntimeJs = files(${readFileList("runtime-js.txt")})
47+
def benchmarkRuntimeWasm = files(${readFileList("runtime-wasm.txt")})
4648
def benchmarkRuntimeNative = files(${readFileList("runtime-native.txt")})
4749
""".trimIndent()
4850
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class ReportFormatTest : GradleTest() {
88
@Test
99
fun testReportFormatFileNames() {
1010
val formats = listOf(null, "json", "csv", "scsv", "text")
11-
val targets = listOf("jsIr", "js", "jvm", "native")
11+
val targets = listOf("jsIr", "js", "wasm", "jvm", "native")
1212

1313
val runner = project("kotlin-multiplatform", true) {
1414
formats.forEach { format ->

integration/src/test/resources/templates/kotlin-multiplatform/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ kotlin {
55
jvm()
66
js('jsIr', IR) { nodejs() }
77
js { nodejs() }
8+
wasm { d8() }
89

910
if (HostManager.hostIsLinux) linuxX64('native')
1011
if (HostManager.hostIsMingw) mingwX64('native')
@@ -32,6 +33,11 @@ kotlin {
3233
implementation(benchmarkRuntimeJs)
3334
}
3435
}
36+
wasmMain {
37+
dependencies {
38+
implementation(benchmarkRuntimeWasm)
39+
}
40+
}
3541
nativeMain {
3642
dependsOn(commonMain)
3743
dependencies {
@@ -46,6 +52,7 @@ benchmark {
4652
register("jvm")
4753
register("jsIr")
4854
register("js")
55+
register("wasm")
4956
register("native")
5057
}
5158
}

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package kotlinx.benchmark.gradle
22

33
import org.gradle.api.tasks.*
44
import org.jetbrains.kotlin.gradle.plugin.mpp.*
5+
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
56

67
open class BenchmarkConfiguration(val extension: BenchmarksExtension, val name: String) {
78
var iterations: Int? = null
@@ -50,7 +51,7 @@ abstract class JvmBenchmarkTarget(
5051
extension: BenchmarksExtension,
5152
name: String
5253
) : BenchmarkTarget(extension, name) {
53-
var jmhVersion = (extension.project.findProperty("benchmarks_jmh_version") as? String) ?: "1.21"
54+
var jmhVersion: String = (extension.project.findProperty("benchmarks_jmh_version") as? String) ?: "1.21"
5455
}
5556

5657
class JavaBenchmarkTarget(
@@ -65,18 +66,27 @@ open class KotlinJvmBenchmarkTarget(
6566
val compilation: KotlinJvmCompilation
6667
) : JvmBenchmarkTarget(extension, name)
6768

69+
enum class JsBenchmarksExecutor {
70+
BenchmarkJs,
71+
BuiltIn
72+
}
73+
6874
class JsBenchmarkTarget(
6975
extension: BenchmarksExtension,
7076
name: String,
7177
val compilation: KotlinJsCompilation
7278
) : BenchmarkTarget(extension, name) {
73-
79+
var jsBenchmarksExecutor: JsBenchmarksExecutor = JsBenchmarksExecutor.BenchmarkJs
7480
}
7581

82+
class WasmBenchmarkTarget(
83+
extension: BenchmarksExtension,
84+
name: String,
85+
val compilation: KotlinJsIrCompilation
86+
) : BenchmarkTarget(extension, name)
87+
7688
class NativeBenchmarkTarget(
7789
extension: BenchmarksExtension,
7890
name: String,
7991
val compilation: KotlinNativeCompilation
80-
) : BenchmarkTarget(extension, name) {
81-
82-
}
92+
) : BenchmarkTarget(extension, name)

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import groovy.lang.*
44
import org.gradle.api.*
55
import org.gradle.api.plugins.*
66
import org.jetbrains.kotlin.gradle.dsl.*
7+
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
78
import org.jetbrains.kotlin.gradle.plugin.mpp.*
9+
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
810

911
fun Project.benchmark(configure: Action<BenchmarksExtension>) {
1012
configure.execute(extensions.getByType(BenchmarksExtension::class.java))
@@ -58,7 +60,12 @@ open class BenchmarksExtension(val project: Project) {
5860
KotlinJvmBenchmarkTarget(this, name, compilation)
5961
}
6062
is KotlinJsCompilation -> {
61-
JsBenchmarkTarget(this, name, compilation)
63+
if (compilation.target.platformType != KotlinPlatformType.wasm) {
64+
JsBenchmarkTarget(this, name, compilation)
65+
} else {
66+
check(compilation is KotlinJsIrCompilation)
67+
WasmBenchmarkTarget(this, name, compilation)
68+
}
6269
}
6370
is KotlinNativeCompilation -> {
6471
NativeBenchmarkTarget(this, name, compilation)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class BenchmarksPlugin : Plugin<Project> {
7979
is JavaBenchmarkTarget -> processJavaSourceSet(config)
8080
is KotlinJvmBenchmarkTarget -> processJvmCompilation(config)
8181
is JsBenchmarkTarget -> processJsCompilation(config)
82+
is WasmBenchmarkTarget -> processWasmCompilation(config)
8283
is NativeBenchmarkTarget -> processNativeCompilation(config)
8384
}
8485
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package kotlinx.benchmark.gradle
2+
3+
import java.io.ByteArrayOutputStream
4+
import java.io.FileOutputStream
5+
import java.io.OutputStream
6+
7+
internal class ConsoleAndFilesOutputStream : OutputStream() {
8+
private val buffer = ByteArrayOutputStream()
9+
private var currentStream: OutputStream = System.out
10+
private val fileTag = "<FILE:"
11+
private val endFileTag = "<ENDFILE>"
12+
private val openTag = '<'.toInt()
13+
private val closeTag = '>'.toInt()
14+
private var tagOpened = false
15+
16+
private fun processTag(tag: String) {
17+
if (tag.startsWith(fileTag)) {
18+
check(currentStream !is FileOutputStream) { "$endFileTag not found" }
19+
val fileName = tag.substring(fileTag.length, tag.lastIndex)
20+
currentStream = FileOutputStream(fileName)
21+
} else if (tag == endFileTag) {
22+
val currentFile = currentStream as? FileOutputStream
23+
check(currentFile != null) { "$fileTag not found" }
24+
currentFile.flush()
25+
currentFile.close()
26+
currentStream = System.out
27+
} else {
28+
buffer.writeTo(currentStream)
29+
}
30+
buffer.reset()
31+
}
32+
33+
override fun write(b: Int) {
34+
when (b) {
35+
openTag -> {
36+
buffer.writeTo(currentStream)
37+
buffer.reset()
38+
buffer.write(b)
39+
tagOpened = true
40+
}
41+
closeTag -> {
42+
if (tagOpened) {
43+
buffer.write(b)
44+
processTag(buffer.toString())
45+
tagOpened = false
46+
} else {
47+
buffer.write(b)
48+
}
49+
}
50+
else -> {
51+
buffer.write(b)
52+
}
53+
}
54+
}
55+
56+
override fun flush() {
57+
buffer.flush()
58+
buffer.writeTo(currentStream)
59+
buffer.reset()
60+
currentStream.flush()
61+
}
62+
63+
override fun close() {
64+
flush()
65+
buffer.close()
66+
currentStream.close()
67+
}
68+
}

0 commit comments

Comments
 (0)