Skip to content

Commit c10718d

Browse files
alex28shSpace Team
authored andcommitted
[Wasm] separate array for stringLiteral arguments (start+length) (KT-79357)
1 parent 2a55ade commit c10718d

File tree

15 files changed

+73
-34
lines changed

15 files changed

+73
-34
lines changed

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmBackendContext.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class WasmBackendContext(
8080

8181
var objectInstanceFieldInitializer: IrSimpleFunction? = null
8282
var stringPoolFieldInitializer: IrSimpleFunction? = null
83+
var stringAddressesAndLengthsInitializer: IrSimpleFunction? = null
8384
var nonConstantFieldInitializer: IrSimpleFunction? = null
8485
}
8586

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ class WasmSymbols(
212212
val refCastNull = getInternalFunction("wasm_ref_cast_null")
213213
val wasmArrayCopy = getInternalFunction("wasm_array_copy")
214214
val wasmArrayNewData0 = getInternalFunction("array_new_data0")
215+
val wasmArrayNewData1 = getInternalFunction("array_new_data1")
215216
val wasmArrayNewData0CharArray = maybeGetFunction("array_new_data0_char_array", wasmInternalFqName)
216217

217218
val intToLong = getInternalFunction("wasm_i64_extend_i32_s")

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/dce/Dce.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ private fun buildRoots(modules: List<IrModuleFragment>, context: WasmBackendCont
9696

9797
context.fileContexts.values.forEach { crossFileContext ->
9898
crossFileContext.stringPoolFieldInitializer?.let { add(it) }
99+
crossFileContext.stringAddressesAndLengthsInitializer?.let { add(it) }
99100
crossFileContext.nonConstantFieldInitializer?.let { add(it) }
100101
}
101102

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,13 @@ class BodyGenerator(
11481148
body.buildInstr(WasmOp.ARRAY_NEW_DATA, location, arrayGcType, WasmImmediate.DataIdx(0))
11491149
}
11501150

1151+
wasmSymbols.wasmArrayNewData1 -> {
1152+
val arrayGcType = WasmImmediate.GcType(
1153+
wasmFileCodegenContext.referenceGcType(call.typeArguments[0]!!.getRuntimeClass(irBuiltIns).symbol)
1154+
)
1155+
body.buildInstr(WasmOp.ARRAY_NEW_DATA, location, arrayGcType, WasmImmediate.DataIdx(1))
1156+
}
1157+
11511158
wasmSymbols.wasmArrayNewData0CharArray -> {
11521159
val arrayGcType = WasmImmediate.GcType(
11531160
wasmFileCodegenContext.referenceGcType(

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/DeclarationGenerator.kt

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,8 @@ class DeclarationGenerator(
375375
""
376376
}
377377
val simpleName = klass.name.asString()
378-
val (packageNameAddress, packageNamePoolId) = wasmFileCodegenContext.referenceStringLiteralAddressAndId(qualifier)
379-
val (simpleNameAddress, simpleNamePoolId) = wasmFileCodegenContext.referenceStringLiteralAddressAndId(simpleName)
378+
val (_, packageNamePoolId) = wasmFileCodegenContext.referenceStringLiteralAddressAndId(qualifier)
379+
val (_, simpleNamePoolId) = wasmFileCodegenContext.referenceStringLiteralAddressAndId(simpleName)
380380

381381
val location = SourceLocation.NoLocation("Create instance of rtti struct")
382382
val initRttiGlobal = buildWasmExpression {
@@ -387,12 +387,7 @@ class DeclarationGenerator(
387387
buildRefNull(WasmHeapType.Simple.None, location)
388388
}
389389

390-
buildConstI32Symbol(packageNameAddress, location)
391-
buildConstI32(qualifier.length, location)
392390
buildConstI32Symbol(packageNamePoolId, location)
393-
394-
buildConstI32Symbol(simpleNameAddress, location)
395-
buildConstI32(simpleName.length, location)
396391
buildConstI32Symbol(simpleNamePoolId, location)
397392

398393
buildConstI64(wasmFileCodegenContext.referenceTypeId(symbol), location)
@@ -626,12 +621,10 @@ fun generateConstExpression(
626621
is IrConstKind.Double -> body.buildConstF64(expression.value as Double, location)
627622
is IrConstKind.String -> {
628623
val stringValue = expression.value as String
629-
val (literalAddress, literalPoolId) = context.referenceStringLiteralAddressAndId(stringValue)
624+
val (_, literalPoolId) = context.referenceStringLiteralAddressAndId(stringValue)
630625
val isLatin = stringValue.all { it.code in 0..255 }
631626
body.commentGroupStart { "const string: \"$stringValue\"" }
632627
body.buildConstI32Symbol(literalPoolId, location)
633-
body.buildConstI32Symbol(literalAddress, location)
634-
body.buildConstI32(stringValue.length, location)
635628
if (isLatin) {
636629
body.buildCall(context.referenceFunction(backendContext.wasmSymbols.stringGetLiteralLatin), location)
637630
} else {

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class WasmCompiledFileFragment(
7373

7474
val objectInstanceFieldInitializers: MutableList<IdSignature> = mutableListOf(),
7575
var stringPoolFieldInitializer: IdSignature? = null,
76+
var stringAddressesAndLengthsInitializer: IdSignature? = null,
7677
val nonConstantFieldInitializers: MutableList<IdSignature> = mutableListOf(),
7778
) : IrICProgramFragment()
7879

@@ -232,11 +233,11 @@ class WasmCompiledModuleFragment(
232233
fields = listOf(
233234
WasmStructFieldDeclaration("implementedIFaceIds", WasmRefNullType(WasmHeapType.Type(WasmSymbol(wasmLongArray))), false),
234235
WasmStructFieldDeclaration("superClassRtti", WasmRefNullType(WasmHeapType.Type(rttiTypeDeclarationSymbol)), false),
235-
WasmStructFieldDeclaration("packageNameAddress", WasmI32, false),
236-
WasmStructFieldDeclaration("packageNameLength", WasmI32, false),
236+
// WasmStructFieldDeclaration("packageNameAddress", WasmI32, false),
237+
// WasmStructFieldDeclaration("packageNameLength", WasmI32, false),
237238
WasmStructFieldDeclaration("packageNamePoolId", WasmI32, false),
238-
WasmStructFieldDeclaration("simpleNameAddress", WasmI32, false),
239-
WasmStructFieldDeclaration("simpleNameLength", WasmI32, false),
239+
// WasmStructFieldDeclaration("simpleNameAddress", WasmI32, false),
240+
// WasmStructFieldDeclaration("simpleNameLength", WasmI32, false),
240241
WasmStructFieldDeclaration("simpleNamePoolId", WasmI32, false),
241242
WasmStructFieldDeclaration("klassId", WasmI64, false),
242243
WasmStructFieldDeclaration("typeInfoFlag", WasmI32, false),
@@ -463,9 +464,12 @@ class WasmCompiledModuleFragment(
463464
val fieldInitializerFunction = WasmFunction.Defined("_fieldInitialize", WasmSymbol(parameterlessNoReturnFunctionType))
464465
with(WasmExpressionBuilder(fieldInitializerFunction.instructions)) {
465466
var stringPoolInitializer: WasmSymbol<WasmFunction>? = null
467+
var stringAddressesAndLengthsInitializer: WasmSymbol<WasmFunction>? = null
466468
wasmCompiledFileFragments.forEach { fragment ->
467469
stringPoolInitializer = stringPoolInitializer
468470
?: fragment.stringPoolFieldInitializer?.let { WasmSymbol(fragment.functions.defined[it]) }
471+
stringAddressesAndLengthsInitializer = stringAddressesAndLengthsInitializer
472+
?: fragment.stringAddressesAndLengthsInitializer?.let { WasmSymbol(fragment.functions.defined[it]) }
469473

470474
fragment.objectInstanceFieldInitializers.forEach { objectInitializer ->
471475
val functionSymbol = WasmSymbol(fragment.functions.defined[objectInitializer]!!)
@@ -483,6 +487,11 @@ class WasmCompiledModuleFragment(
483487
}
484488
}
485489

490+
stringAddressesAndLengthsInitializer ?: compilationException("stringAddressesAndLengths initializer not found!", type = null)
491+
expression.add(
492+
0,
493+
WasmInstrWithoutLocation(WasmOp.CALL, listOf(WasmImmediate.FuncIdx(stringAddressesAndLengthsInitializer)))
494+
)
486495
stringPoolInitializer ?: compilationException("stringPool initializer not found!", type = null)
487496
expression.add(
488497
0,
@@ -543,6 +552,7 @@ class WasmCompiledModuleFragment(
543552
val stringDataSectionBytes = mutableListOf<Byte>()
544553
var stringDataSectionStart = 0
545554
val stringAddressAndId = mutableMapOf<String, Pair<Int, Int>>()
555+
val addressesAndLengths = mutableListOf<Long>()
546556
wasmCompiledFileFragments.forEach { fragment ->
547557
for ((string, literalAddressSymbol) in fragment.stringLiteralAddress.unbound) {
548558
val currentStringAddress: Int
@@ -552,6 +562,7 @@ class WasmCompiledModuleFragment(
552562
currentStringAddress = stringDataSectionStart
553563
currentStringId = stringAddressAndId.size
554564
stringAddressAndId[string] = currentStringAddress to currentStringId
565+
addressesAndLengths.add(currentStringAddress.toLong() or (string.length.toLong() shl 32))
555566

556567
val fitsOneByte = if (string.all { it.code in 0..255 }) 1 else 0
557568

@@ -575,6 +586,8 @@ class WasmCompiledModuleFragment(
575586
}
576587

577588
data.add(WasmData(WasmDataMode.Passive, stringDataSectionBytes.toByteArray()))
589+
val constDataAddressesAndLengths = ConstantDataIntegerArray(addressesAndLengths, LONG_SIZE_BYTES)
590+
data.add(WasmData(WasmDataMode.Passive, constDataAddressesAndLengths.toBytes()))
578591
}
579592

580593
private fun bindConstantArrayDataSegmentIds(data: MutableList<WasmData>) {

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmModuleCodegenContext.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ class WasmFileCodegenContext(
111111
wasmFileFragment.stringPoolFieldInitializer = initializer.getReferenceKey()
112112
}
113113

114+
fun setStringAddressesAndLengthsInitializer(initializer: IrFunctionSymbol) {
115+
wasmFileFragment.stringAddressesAndLengthsInitializer = initializer.getReferenceKey()
116+
}
117+
114118
fun addNonConstantFieldInitializers(initializer: IrFunctionSymbol) {
115119
wasmFileFragment.nonConstantFieldInitializers.add(initializer.getReferenceKey())
116120
}

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmModuleFragmentGenerator.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ private fun compileIrFile(
111111
fileContext.stringPoolFieldInitializer?.apply {
112112
wasmFileCodegenContext.setStringPoolFieldInitializer(symbol)
113113
}
114+
fileContext.stringAddressesAndLengthsInitializer?.apply {
115+
wasmFileCodegenContext.setStringAddressesAndLengthsInitializer(symbol)
116+
}
114117
fileContext.nonConstantFieldInitializer?.apply {
115118
wasmFileCodegenContext.addNonConstantFieldInitializers(symbol)
116119
}

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/FieldInitializersLowering.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ import org.jetbrains.kotlin.name.Name
3838
*/
3939
class FieldInitializersLowering(val context: WasmBackendContext) : FileLoweringPass {
4040
private val stringPoolFqName = FqName("kotlin.wasm.internal.stringPool")
41+
private val stringAddressesAndLengthsFqName = FqName("kotlin.wasm.internal.stringAddressesAndLengths")
4142

4243
override fun lower(irFile: IrFile) {
4344
var nonConstantFieldInitializer: IrSimpleFunction? = null
4445
var objectInstanceFieldInitializer: IrSimpleFunction? = null
4546
var stringPoolFieldInitializer: IrSimpleFunction? = null
47+
var stringAddressesAndLengthsInitializer: IrSimpleFunction? = null
4648

4749
irFile.acceptVoid(object : IrVisitorVoid() {
4850
override fun visitElement(element: IrElement) {
@@ -84,6 +86,7 @@ class FieldInitializersLowering(val context: WasmBackendContext) : FileLoweringP
8486
val initializeFunction = when {
8587
declaration.isObjectInstanceField() -> objectInstanceFieldInitializer
8688
declaration.fqNameWhenAvailable == stringPoolFqName -> stringPoolFieldInitializer
89+
declaration.fqNameWhenAvailable == stringAddressesAndLengthsFqName -> stringAddressesAndLengthsInitializer
8790
else -> nonConstantFieldInitializer
8891
}
8992

@@ -94,6 +97,7 @@ class FieldInitializersLowering(val context: WasmBackendContext) : FileLoweringP
9497
when {
9598
declaration.isObjectInstanceField() -> objectInstanceFieldInitializer = it
9699
declaration.fqNameWhenAvailable == stringPoolFqName -> stringPoolFieldInitializer = it
100+
declaration.fqNameWhenAvailable == stringAddressesAndLengthsFqName -> stringAddressesAndLengthsInitializer = it
97101
else -> nonConstantFieldInitializer = it
98102
}
99103
}
@@ -111,10 +115,11 @@ class FieldInitializersLowering(val context: WasmBackendContext) : FileLoweringP
111115
}
112116
})
113117

114-
if (objectInstanceFieldInitializer != null || stringPoolFieldInitializer != null || nonConstantFieldInitializer != null) {
118+
if (objectInstanceFieldInitializer != null || stringPoolFieldInitializer != null || nonConstantFieldInitializer != null || stringAddressesAndLengthsInitializer != null) {
115119
with(context.getFileContext(irFile)) {
116120
this.objectInstanceFieldInitializer = objectInstanceFieldInitializer?.also { irFile.declarations.add(it) }
117121
this.stringPoolFieldInitializer = stringPoolFieldInitializer?.also { irFile.declarations.add(it) }
122+
this.stringAddressesAndLengthsInitializer = stringAddressesAndLengthsInitializer?.also { irFile.declarations.add(it) }
118123
this.nonConstantFieldInitializer = nonConstantFieldInitializer?.also { irFile.declarations.add(it) }
119124
}
120125
}

compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/serialization/WasmDeserializer.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ class WasmDeserializer(inputStream: InputStream, private val skipLocalNames: Boo
612612
rttiElements = deserializeRttiElements(),
613613
objectInstanceFieldInitializers = deserializeList(::deserializeIdSignature),
614614
stringPoolFieldInitializer = deserializeNullable(::deserializeIdSignature),
615+
stringAddressesAndLengthsInitializer = deserializeNullable(::deserializeIdSignature),
615616
nonConstantFieldInitializers = deserializeList(::deserializeIdSignature),
616617
)
617618

0 commit comments

Comments
 (0)