From a57616084797ddab5a1e782ab2f894d951c4f22d Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Wed, 18 Aug 2021 17:45:25 +0500 Subject: [PATCH] [K/N][IR][codegen] Lazy initialization fix for new GC A mutable field should be registered in GC even if its initializer is a const --- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 13 +++++++------ .../backend/konan/lower/FileInitializersLowering.kt | 6 +++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 05fff2c2724..e3557d2d056 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -70,6 +70,12 @@ internal val IrField.storageKind: FieldStorageKind get() { } } +internal fun IrField.needsGCRegistration(context: Context) = + context.memoryModel == MemoryModel.EXPERIMENTAL && // only for the new MM + type.binaryTypeIsReference() && // only for references + (initializer?.expression !is IrConst<*>? || // which are initialized from heap object + !isFinal) // or are not final + internal fun IrClass.storageKind(context: Context): ObjectStorageKind = when { this.annotations.hasAnnotation(KonanFqNames.threadLocal) && context.config.threadsAreAllowed -> ObjectStorageKind.THREAD_LOCAL @@ -341,12 +347,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map { require(kPropertiesField == null) { "Expected at most one kProperties field" } @@ -133,6 +134,9 @@ internal class FileInitializersLowering(val context: Context) : FileLoweringPass irFile.declarations.add(0, this) } + private val IrField.needsInitializationAtRuntime: Boolean + get() = hasNonConstInitializer || needsGCRegistration(context) + private val IrField.hasNonConstInitializer: Boolean get() = initializer?.expression.let { it != null && it !is IrConst<*> } } \ No newline at end of file