From a7460e906161a315e84a6c99fd603ef69399565c Mon Sep 17 00:00:00 2001 From: Alexander Shabalin Date: Thu, 19 Aug 2021 18:23:01 +0000 Subject: [PATCH] [K/N] Enable lazy property initialization with the new MM --- .../org/jetbrains/kotlin/cli/bc/K2Native.kt | 15 +++++++- .../cli/bc/K2NativeCompilerArguments.kt | 4 +-- .../backend/konan/lower/DelegationLowering.kt | 4 +-- .../konan/lower/FileInitializersLowering.kt | 35 +++---------------- .../backend.native/tests/build.gradle | 18 +++++----- 5 files changed, 32 insertions(+), 44 deletions(-) diff --git a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index 43bab44bd16..7903ad5969f 100644 --- a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -328,7 +328,20 @@ class K2Native : CLICompiler() { RuntimeAssertsMode.IGNORE } }) - put(PROPERTY_LAZY_INITIALIZATION, arguments.propertyLazyInitialization) + put(PROPERTY_LAZY_INITIALIZATION, when (arguments.propertyLazyInitialization) { + null -> { + when (memoryModel) { + MemoryModel.EXPERIMENTAL -> true + else -> false + } + } + "enable" -> true + "disable" -> false + else -> { + configuration.report(ERROR, "Expected 'enable' or 'disable' for lazy property initialization") + false + } + }) put(WORKER_EXCEPTION_HANDLING, when (arguments.workerExceptionHandling) { null -> if (memoryModel == MemoryModel.EXPERIMENTAL) WorkerExceptionHandling.USE_HOOK else WorkerExceptionHandling.LEGACY "legacy" -> WorkerExceptionHandling.LEGACY diff --git a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt index 50dcffc68b6..3b7093f6274 100644 --- a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt +++ b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt @@ -323,8 +323,8 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @Argument(value="-Xgc-aggressive", description = "Make GC agressive. Works only with -memory-model experimental") var gcAggressive: Boolean = false - @Argument(value = "-Xir-property-lazy-initialization", description = "Initialize top level properties lazily per file") - var propertyLazyInitialization: Boolean = false + @Argument(value = "-Xir-property-lazy-initialization", valueDescription = "{disable|enable}", description = "Initialize top level properties lazily per file") + var propertyLazyInitialization: String? = null @Argument(value="-Xruntime-asserts-mode", valueDescription = "", description = "Enable asserts in runtime. Possible values: 'ignore', 'log', 'panic'") var runtimeAssertsMode: String? = "ignore" diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt index 0bf43d188ca..0ec9d24a6d4 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt @@ -29,8 +29,6 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name -internal object DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION : IrDeclarationOriginImpl("KPROPERTIES_FOR_DELEGATION") - internal class PropertyDelegationLowering(val context: Context) : FileLoweringPass { private var tempIndex = 0 @@ -292,4 +290,6 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa } return type.classifier == expectedClass } + + private object DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION : IrDeclarationOriginImpl("KPROPERTIES_FOR_DELEGATION") } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FileInitializersLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FileInitializersLowering.kt index 2c160f7659c..b4984af54a6 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FileInitializersLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FileInitializersLowering.kt @@ -53,25 +53,19 @@ internal class FileInitializersLowering(val context: Context) : FileLoweringPass override fun lower(irFile: IrFile) { var requireGlobalInitializer = false var requireThreadLocalInitializer = false - var kPropertiesField: IrField? = null for (declaration in irFile.declarations) { val irField = (declaration as? IrField) ?: (declaration as? IrProperty)?.backingField if (irField == null || !irField.needsInitializationAtRuntime || irField.shouldBeInitializedEagerly) continue - when { - irField.origin == DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION -> { - require(kPropertiesField == null) { "Expected at most one kProperties field" } - kPropertiesField = irField - } - irField.storageKind == FieldStorageKind.SHARED_FROZEN -> requireGlobalInitializer = true - else -> requireThreadLocalInitializer = true // Either marked with thread local or only main thread visible. + if (irField.storageKind == FieldStorageKind.SHARED_FROZEN) { + requireGlobalInitializer = true + } else { + requireThreadLocalInitializer = true // Either marked with thread local or only main thread visible. } } // TODO: think about pure initializers. if (!requireGlobalInitializer && !requireThreadLocalInitializer) { - kPropertiesField?.let { transformKPropertiesInitializerToModuleInitializer(irFile, it) } return } - kPropertiesField?.let { requireGlobalInitializer = true } val globalInitFunction = if (requireGlobalInitializer) @@ -102,25 +96,6 @@ internal class FileInitializersLowering(val context: Context) : FileLoweringPass }) } - private fun transformKPropertiesInitializerToModuleInitializer(irFile: IrFile, irField: IrField) { - val initializer = context.irFactory.buildFun { - startOffset = irField.startOffset - endOffset = irField.endOffset - origin = DECLARATION_ORIGIN_MODULE_GLOBAL_INITIALIZER - name = Name.identifier("\$kProperties_init") - visibility = DescriptorVisibilities.PRIVATE - returnType = context.irBuiltIns.unitType - }.apply { - val function = this - parent = irFile - body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody { - +irSetField(null, irField, irField.initializer!!.expression.also { it.setDeclarationsParent(function) }) - } - } - irField.initializer = null - irFile.declarations.add(initializer) - } - private fun buildInitFileFunction(irFile: IrFile, name: String, origin: IrDeclarationOrigin) = context.irFactory.buildFun { startOffset = SYNTHETIC_OFFSET endOffset = SYNTHETIC_OFFSET @@ -139,4 +114,4 @@ internal class FileInitializersLowering(val context: Context) : FileLoweringPass private val IrField.hasNonConstInitializer: Boolean get() = initializer?.expression.let { it != null && it !is IrConst<*> } -} \ No newline at end of file +} diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index d8acae09973..41a7a652833 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -1486,22 +1486,22 @@ standaloneTest("initializers_globalInitedBeforeThreadLocal") { } standaloneTest("initializers_eagerInitializationGlobal1") { - enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization') + enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization=enable') || isExperimentalMM source = "codegen/initializers/eagerInitializationGlobal1.kt" } standaloneTest("initializers_eagerInitializationGlobal2") { - enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization') + enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization=enable') || isExperimentalMM source = "codegen/initializers/eagerInitializationGlobal2.kt" } standaloneTest("initializers_eagerInitializationThreadLocal1") { - enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization') + enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization=enable') || isExperimentalMM source = "codegen/initializers/eagerInitializationThreadLocal1.kt" } standaloneTest("initializers_eagerInitializationThreadLocal2") { - enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization') + enabled = project.globalTestArgs.contains('-Xir-property-lazy-initialization=enable') || isExperimentalMM source = "codegen/initializers/eagerInitializationThreadLocal2.kt" } @@ -1521,28 +1521,28 @@ standaloneTest("initializers_failInInitializer1") { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. source = "codegen/initializers/failInInitializer1.kt" goldValue = "caught\n" - flags = ['-Xir-property-lazy-initialization'] + flags = ['-Xir-property-lazy-initialization=enable'] } standaloneTest("initializers_failInInitializer2") { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. source = "codegen/initializers/failInInitializer2.kt" goldValue = "caught\ncaught2\n" - flags = ['-Xir-property-lazy-initialization'] + flags = ['-Xir-property-lazy-initialization=enable'] } standaloneTest("initializers_failInInitializer3") { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. source = "codegen/initializers/failInInitializer3.kt" goldValue = "caught\ncaught2\n" - flags = ['-Xir-property-lazy-initialization'] + flags = ['-Xir-property-lazy-initialization=enable'] } standaloneTest("initializers_failInInitializer4") { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. source = "codegen/initializers/failInInitializer4.kt" goldValue = "caught\ncaught2\n" - flags = ['-Xir-property-lazy-initialization'] + flags = ['-Xir-property-lazy-initialization=enable'] } standaloneTest("initializers_when1") { @@ -2367,7 +2367,7 @@ standaloneTest("link_testLib_explicitly") { enabled = project.target.name == project.hostName dependsOn installTestLib - if (project.globalTestArgs.contains('-Xir-property-lazy-initialization')) + if (project.globalTestArgs.contains('-Xir-property-lazy-initialization=enable') || isExperimentalMM) goldValue = "Hello\n" else goldValue = "This is a side effect of a test library linked into the binary.\nYou should not be seeing this.\n\nHello\n"