JS IR: JsMapping serialization
This commit is contained in:
committed by
TeamCityServer
parent
ba5582de99
commit
c224dd4cb1
@@ -36,18 +36,18 @@ interface Mapping {
|
||||
}
|
||||
}
|
||||
|
||||
open class DefaultMapping : Mapping {
|
||||
interface DelegateFactory {
|
||||
fun <K : IrDeclaration, V : IrDeclaration> newDeclarationToDeclarationMapping(): Mapping.Delegate<K, V>
|
||||
|
||||
override val defaultArgumentsDispatchFunction: Mapping.Delegate<IrFunction, IrFunction> = newMapping()
|
||||
override val defaultArgumentsOriginalFunction: Mapping.Delegate<IrFunction, IrFunction> = newMapping()
|
||||
override val suspendFunctionToCoroutineConstructor: Mapping.Delegate<IrFunction, IrConstructor> = newMapping()
|
||||
override val lateInitFieldToNullableField: Mapping.Delegate<IrField, IrField> = newMapping()
|
||||
override val inlineClassMemberToStatic: Mapping.Delegate<IrFunction, IrSimpleFunction> = newMapping()
|
||||
override val capturedFields: Mapping.Delegate<IrClass, Collection<IrField>> = newMapping()
|
||||
override val capturedConstructors: Mapping.Delegate<IrConstructor, IrConstructor> = newMapping()
|
||||
override val reflectedNameAccessor: Mapping.Delegate<IrClass, IrSimpleFunction> = newMapping()
|
||||
fun <K : IrDeclaration, V : Collection<IrDeclaration>> newDeclarationToDeclarationCollectionMapping(): Mapping.Delegate<K, V>
|
||||
}
|
||||
|
||||
protected open fun <K : IrDeclaration, V> newMapping() = object : Mapping.Delegate<K, V>() {
|
||||
private object DefaultDelegateFactory : DelegateFactory {
|
||||
override fun <K : IrDeclaration, V : IrDeclaration> newDeclarationToDeclarationMapping(): Mapping.Delegate<K, V> = newMappingImpl()
|
||||
|
||||
override fun <K : IrDeclaration, V : Collection<IrDeclaration>> newDeclarationToDeclarationCollectionMapping(): Mapping.Delegate<K, V> = newMappingImpl()
|
||||
|
||||
private fun <K : IrDeclaration, V> newMappingImpl() = object : Mapping.Delegate<K, V>() {
|
||||
private val map: MutableMap<K, V> = ConcurrentHashMap()
|
||||
|
||||
override operator fun get(key: K): V? {
|
||||
@@ -70,6 +70,17 @@ open class DefaultMapping : Mapping {
|
||||
}
|
||||
}
|
||||
|
||||
open class DefaultMapping(delegateFactory: DelegateFactory = DefaultDelegateFactory) : Mapping {
|
||||
override val defaultArgumentsDispatchFunction: Mapping.Delegate<IrFunction, IrFunction> = delegateFactory.newDeclarationToDeclarationMapping()
|
||||
override val defaultArgumentsOriginalFunction: Mapping.Delegate<IrFunction, IrFunction> = delegateFactory.newDeclarationToDeclarationMapping()
|
||||
override val suspendFunctionToCoroutineConstructor: Mapping.Delegate<IrFunction, IrConstructor> = delegateFactory.newDeclarationToDeclarationMapping()
|
||||
override val lateInitFieldToNullableField: Mapping.Delegate<IrField, IrField> = delegateFactory.newDeclarationToDeclarationMapping()
|
||||
override val inlineClassMemberToStatic: Mapping.Delegate<IrFunction, IrSimpleFunction> = delegateFactory.newDeclarationToDeclarationMapping()
|
||||
override val capturedFields: Mapping.Delegate<IrClass, Collection<IrField>> = delegateFactory.newDeclarationToDeclarationCollectionMapping()
|
||||
override val capturedConstructors: Mapping.Delegate<IrConstructor, IrConstructor> = delegateFactory.newDeclarationToDeclarationMapping()
|
||||
override val reflectedNameAccessor: Mapping.Delegate<IrClass, IrSimpleFunction> = delegateFactory.newDeclarationToDeclarationMapping()
|
||||
}
|
||||
|
||||
fun <V : Any> KMutableProperty0<V?>.getOrPut(fn: () -> V) = this.get() ?: fn().also {
|
||||
this.set(it)
|
||||
}
|
||||
|
||||
@@ -6,52 +6,197 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DefaultMapping
|
||||
import org.jetbrains.kotlin.backend.common.DelegateFactory
|
||||
import org.jetbrains.kotlin.backend.common.Mapping
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.library.impl.*
|
||||
|
||||
class JsMapping(private val irFactory: IrFactory) : DefaultMapping() {
|
||||
val outerThisFieldSymbols = newMapping<IrClass, IrField>()
|
||||
val innerClassConstructors = newMapping<IrConstructor, IrConstructor>()
|
||||
val originalInnerClassPrimaryConstructorByClass = newMapping<IrClass, IrConstructor>()
|
||||
val secondaryConstructorToDelegate = newMapping<IrConstructor, IrSimpleFunction>()
|
||||
val secondaryConstructorToFactory = newMapping<IrConstructor, IrSimpleFunction>()
|
||||
val objectToGetInstanceFunction = newMapping<IrClass, IrSimpleFunction>()
|
||||
val objectToInstanceField = newMapping<IrClass, IrField>()
|
||||
val classToSyntheticPrimaryConstructor = newMapping<IrClass, IrConstructor>()
|
||||
val privateMemberToCorrespondingStatic = newMapping<IrFunction, IrSimpleFunction>()
|
||||
fun JsMapping(irFactory: IrFactory) = JsMapping(JsMappingState(irFactory))
|
||||
|
||||
val constructorToInitFunction = newMapping<IrConstructor, IrSimpleFunction>()
|
||||
class JsMapping(val state: JsMappingState) : DefaultMapping(state) {
|
||||
val outerThisFieldSymbols = state.newDeclarationToDeclarationMapping<IrClass, IrField>()
|
||||
val innerClassConstructors = state.newDeclarationToDeclarationMapping<IrConstructor, IrConstructor>()
|
||||
val originalInnerClassPrimaryConstructorByClass = state.newDeclarationToDeclarationMapping<IrClass, IrConstructor>()
|
||||
val secondaryConstructorToDelegate = state.newDeclarationToDeclarationMapping<IrConstructor, IrSimpleFunction>()
|
||||
val secondaryConstructorToFactory = state.newDeclarationToDeclarationMapping<IrConstructor, IrSimpleFunction>()
|
||||
val objectToGetInstanceFunction = state.newDeclarationToDeclarationMapping<IrClass, IrSimpleFunction>()
|
||||
val objectToInstanceField = state.newDeclarationToDeclarationMapping<IrClass, IrField>()
|
||||
val classToSyntheticPrimaryConstructor = state.newDeclarationToDeclarationMapping<IrClass, IrConstructor>()
|
||||
val privateMemberToCorrespondingStatic = state.newDeclarationToDeclarationMapping<IrFunction, IrSimpleFunction>()
|
||||
|
||||
val enumEntryToGetInstanceFun = newMapping<IrEnumEntry, IrSimpleFunction>()
|
||||
val enumEntryToInstanceField = newMapping<IrEnumEntry, IrField>()
|
||||
val enumConstructorToNewConstructor = newMapping<IrConstructor, IrConstructor>()
|
||||
val enumClassToCorrespondingEnumEntry = newMapping<IrClass, IrEnumEntry>()
|
||||
val enumConstructorOldToNewValueParameters = newMapping<IrValueDeclaration, IrValueParameter>()
|
||||
val enumEntryToCorrespondingField = newMapping<IrEnumEntry, IrField>()
|
||||
val enumClassToInitEntryInstancesFun = newMapping<IrClass, IrSimpleFunction>()
|
||||
val constructorToInitFunction = state.newDeclarationToDeclarationMapping<IrConstructor, IrSimpleFunction>()
|
||||
|
||||
// Triggers `StageController.lazyLower` on access
|
||||
override fun <K : IrDeclaration, V> newMapping(): Mapping.Delegate<K, V> = object : Mapping.Delegate<K, V>() {
|
||||
private val map: MutableMap<K, V> = mutableMapOf()
|
||||
val enumEntryToGetInstanceFun = state.newDeclarationToDeclarationMapping<IrEnumEntry, IrSimpleFunction>()
|
||||
val enumEntryToInstanceField = state.newDeclarationToDeclarationMapping<IrEnumEntry, IrField>()
|
||||
val enumConstructorToNewConstructor = state.newDeclarationToDeclarationMapping<IrConstructor, IrConstructor>()
|
||||
val enumClassToCorrespondingEnumEntry = state.newDeclarationToDeclarationMapping<IrClass, IrEnumEntry>()
|
||||
val enumConstructorOldToNewValueParameters = state.newDeclarationToDeclarationMapping<IrValueDeclaration, IrValueParameter>()
|
||||
val enumEntryToCorrespondingField = state.newDeclarationToDeclarationMapping<IrEnumEntry, IrField>()
|
||||
val enumClassToInitEntryInstancesFun = state.newDeclarationToDeclarationMapping<IrClass, IrSimpleFunction>()
|
||||
}
|
||||
|
||||
override operator fun get(key: K): V? {
|
||||
irFactory.stageController.lazyLower(key)
|
||||
return map[key]
|
||||
|
||||
class JsMappingState(val irFactory: IrFactory) : DelegateFactory {
|
||||
override fun <K : IrDeclaration, V : IrDeclaration> newDeclarationToDeclarationMapping(): Mapping.Delegate<K, V> {
|
||||
return JsMappingDelegate<K, V>(irFactory).also {
|
||||
allMappings += it
|
||||
}
|
||||
}
|
||||
|
||||
override fun <K : IrDeclaration, V : Collection<IrDeclaration>> newDeclarationToDeclarationCollectionMapping(): Mapping.Delegate<K, V> {
|
||||
return JsMappingCollectionDelegate<K, V>(irFactory).also {
|
||||
allMappings += it
|
||||
}
|
||||
}
|
||||
|
||||
private val allMappings = mutableListOf<SerializableMapping>()
|
||||
|
||||
fun serializeMappings(declarations: Iterable<IrDeclaration>, symbolSerializer: (IrSymbol) -> Long): SerializedMappings {
|
||||
return SerializedMappings(allMappings.map { mapping ->
|
||||
val keys = mutableListOf<Long>()
|
||||
val values = mutableListOf<ByteArray>()
|
||||
declarations.forEach { d ->
|
||||
mapping.serializeMapping(d, symbolSerializer)?.let { bytes ->
|
||||
keys += symbolSerializer((d as IrSymbolOwner).symbol)
|
||||
values += bytes
|
||||
}
|
||||
}
|
||||
|
||||
SerializedMapping(
|
||||
IrMemoryLongArrayWriter(keys).writeIntoMemory(),
|
||||
IrMemoryArrayWriter(values).writeIntoMemory(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fun mappingsDeserializer(mapping: SerializedMappings, signatureDeserializer: (Long) -> IdSignature, symbolDeserializer: (Long) -> IrSymbol): (IdSignature, IrDeclaration) -> Unit {
|
||||
if (allMappings.size != mapping.mappings.size) error("Mapping size mismatch")
|
||||
|
||||
val index = Array<Map<IdSignature, ByteArray>>(allMappings.size) { i ->
|
||||
val bytes = mapping.mappings[i]
|
||||
val s = IrLongArrayMemoryReader(bytes.keys).array.map(signatureDeserializer)
|
||||
val v = IrArrayMemoryReader(bytes.values).toArray()
|
||||
|
||||
if (s.size != v.size) error("Keys size != values size")
|
||||
|
||||
s.withIndex().associate { it.value to v[it.index] }
|
||||
}
|
||||
|
||||
override operator fun set(key: K, value: V?) {
|
||||
irFactory.stageController.lazyLower(key)
|
||||
if (value == null) {
|
||||
map.remove(key)
|
||||
} else {
|
||||
map[key] = value
|
||||
return { signature, declaration ->
|
||||
for (i in allMappings.indices) {
|
||||
index[i][signature]?.let { bytes ->
|
||||
allMappings[i].loadMapping(declaration, bytes, symbolDeserializer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val keys: Set<K>
|
||||
get() = map.keys
|
||||
|
||||
override val values: Collection<V>
|
||||
get() = map.values
|
||||
}
|
||||
}
|
||||
|
||||
class SerializedMappings(
|
||||
val mappings: List<SerializedMapping>
|
||||
)
|
||||
|
||||
class SerializedMapping(
|
||||
val keys: ByteArray,
|
||||
val values: ByteArray,
|
||||
)
|
||||
|
||||
private interface SerializableMapping {
|
||||
fun serializeMapping(declaration: IrDeclaration, symbolSerializer: (IrSymbol) -> Long): ByteArray?
|
||||
|
||||
fun loadMapping(declaration: IrDeclaration, mapping: ByteArray, symbolDeserializer: (Long) -> IrSymbol)
|
||||
}
|
||||
|
||||
private class JsMappingDelegate<K : IrDeclaration, V : IrDeclaration>(val irFactory: IrFactory) : Mapping.Delegate<K, V>(), SerializableMapping {
|
||||
|
||||
private val map: MutableMap<IrSymbol, IrSymbol> = mutableMapOf()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override operator fun get(key: K): V? {
|
||||
irFactory.stageController.lazyLower(key)
|
||||
return map[(key as IrSymbolOwner).symbol]?.owner as? V
|
||||
}
|
||||
|
||||
override operator fun set(key: K, value: V?) {
|
||||
irFactory.stageController.lazyLower(key)
|
||||
if (value == null) {
|
||||
map.remove((key as IrSymbolOwner).symbol)
|
||||
} else {
|
||||
map[(key as IrSymbolOwner).symbol] = (value as IrSymbolOwner).symbol
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeMapping(declaration: IrDeclaration, symbolSerializer: (IrSymbol) -> Long): ByteArray? {
|
||||
return map[(declaration as IrSymbolOwner).symbol]?.let { symbol ->
|
||||
symbolSerializer(symbol).toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadMapping(declaration: IrDeclaration, mapping: ByteArray, symbolDeserializer: (Long) -> IrSymbol) {
|
||||
map[(declaration as IrSymbolOwner).symbol] = symbolDeserializer(mapping.toLong())
|
||||
}
|
||||
|
||||
override val keys: Set<K>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override val values: Collection<V>
|
||||
get() = TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private class JsMappingCollectionDelegate<K : IrDeclaration, V : Collection<IrDeclaration>>(val irFactory: IrFactory) : Mapping.Delegate<K, V>(), SerializableMapping {
|
||||
private val map: MutableMap<IrSymbol, Collection<IrSymbol>> = mutableMapOf()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override operator fun get(key: K): V? {
|
||||
irFactory.stageController.lazyLower(key)
|
||||
return map[(key as IrSymbolOwner).symbol]?.map { it.owner as IrDeclaration } as? V
|
||||
}
|
||||
|
||||
override operator fun set(key: K, value: V?) {
|
||||
irFactory.stageController.lazyLower(key)
|
||||
if (value == null) {
|
||||
map.remove((key as IrSymbolOwner).symbol)
|
||||
} else {
|
||||
map[(key as IrSymbolOwner).symbol] = value.map { (it as IrSymbolOwner).symbol }
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeMapping(declaration: IrDeclaration, symbolSerializer: (IrSymbol) -> Long): ByteArray? {
|
||||
return map[(declaration as IrSymbolOwner).symbol]?.let { symbols ->
|
||||
IrMemoryLongArrayWriter(symbols.map(symbolSerializer)).writeIntoMemory()
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadMapping(declaration: IrDeclaration, mapping: ByteArray, symbolDeserializer: (Long) -> IrSymbol) {
|
||||
map[(declaration as IrSymbolOwner).symbol] = IrLongArrayMemoryReader(mapping).array.map(symbolDeserializer)
|
||||
}
|
||||
|
||||
override val keys: Set<K>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override val values: Collection<V>
|
||||
get() = TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
fun ByteArray.toLong(): Long {
|
||||
var result = this[0].toLong() and 0xFFL
|
||||
for (i in 1..7) {
|
||||
result = (result shl 8) or (this[i].toLong() and 0xFFL)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun Long.toByteArray(): ByteArray {
|
||||
val result = ByteArray(8)
|
||||
|
||||
var self = this
|
||||
|
||||
for (i in 7 downTo 0) {
|
||||
result[i] = self.toByte()
|
||||
self = self ushr 8
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user