本文档详细介绍了中间表示(IR)如何序列化为二进制格式,以便在多模块编译、增量编译和创建 Kotlin 库(KLIB)产物中使用。有关 IR 结构本身的信息,请参阅 IR(中间表示)。有关 IR 中的函数内联,请参阅 函数内联。
IR 序列化是 Kotlin 编译器的一个关键组成部分,它支持
序列化系统使用 Protocol Buffers 将内存中的 IR 结构转换为二进制格式,保留了之后反序列化所需的所有必要信息。
来源:compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/serializeModuleIntoKlib.kt compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt
IR 序列化系统围绕几个关键组件构建,这些组件协同工作以序列化 IR 结构的各个方面
来源:compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt114-308 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt21-86 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSerializationSettings.kt19-46 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt15-26 compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleSerializer.kt15-34
序列化过程由各种设置控制,这些设置会影响序列化的内容以及序列化方式
这些设置支持多种重要用例
| 设置 | 目的 |
|---|---|
publicAbiOnly | 如果为 true,则创建“头 KLIB”,其中仅包含公共 API 声明 |
bodiesOnlyForInlines | 在 JVM 后端中使用,仅为内联函数序列化函数体 |
abiCompatibilityLevel | 控制 KLIB 消费者的 ABI 版本兼容性 |
reuseExistingSignaturesForSymbols | 针对 IR 内联器集成的优化 |
来源:compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSerializationSettings.kt36-46 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt15-26 compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleSerializer.kt15-34
ID 签名是 IR 序列化的基本组成部分,为声明提供唯一的标识符,可用于在模块边界之间引用它们。这些签名对于多模块编译期间的链接至关重要。
不同类型的签名用于不同类型的声明
| 签名类型 | 用于 | 示例 |
|---|---|---|
CommonSignature | 公共声明 | 顶层函数、公共类成员 |
FileLocalSignature | 文件私有声明 | 私有顶层函数 |
AccessorSignature | 属性访问器 | getter 和 setter |
ScopeLocalDeclaration | 局部变量 | 函数体内的变量 |
CompositeSignature | 嵌套声明 | 内部类、类型参数 |
FileSignature | 文件级实体 | 包片段 |
签名系统旨在处理复杂的场景,例如
来源:compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IdSignature.kt222-1116 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/signature/IdSignatureComputers.kt22-265 compiler/ir/serialization.common/src/KotlinIr.proto33-83
序列化过程将内存中的 IR 数据结构转换为二进制 Protocol Buffer 格式
序列化过程的关键方面
声明序列化:
ProtoDeclaration类型序列化:
ProtoType 消息函数体序列化:
文件结构:
来源:compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt207-1134 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/serializeModuleIntoKlib.kt103-202
反序列化过程将 IR 数据结构从其二进制格式重建为 IR 数据结构
反序列化过程的关键方面
两阶段反序列化:
符号解析:
函数体反序列化:
去重:
部分链接支持:
来源:compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt32-275 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt64-391 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt85-321
IR 序列化是 KLIB(Kotlin 库)格式的关键组成部分
创建 KLIB 包括以下步骤
serializeModuleIntoKlib 函数协调此过程
特殊的 KLIB 变体包括
头 KLIBs:
publicAbiOnly = true 创建特定平台的 KLIBs:
来源: compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/serializeModuleIntoKlib.kt103-202 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt80-112 kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/WriteKlib.kt29-92
每个 Kotlin 后端都有专门的序列化组件来处理平台特定的问题
来源: compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/JvmIrSerializerSession.kt20-128 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt15-26 compiler/ir/serialization.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleSerializer.kt15-34
IR 序列化在增量编译中起着关键作用
IR 增量编译的关键方面
JavaScript 后端尤其包含详细的增量编译支持
这些指纹存储在 KLIB manifest 中,用于检测跨编译会话的更改。
来源: compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt389-516 js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt189-231
IR 序列化是 Kotlin 编译器基础设施的基本组成部分,它支持几项关键功能
序列化系统由多个层组成,处理不同的方面
理解 IR 序列化对于处理 Kotlin 编译器内部至关重要,尤其是在处理跨模块依赖、增量编译和 KLIB 操作时。