mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
[K/N] Enable lazy property initialization with the new MM
This commit is contained in:
committed by
Space
parent
b5fa129540
commit
a7460e9061
@@ -328,7 +328,20 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
||||
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
|
||||
|
||||
@@ -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 = "<mode>", description = "Enable asserts in runtime. Possible values: 'ignore', 'log', 'panic'")
|
||||
var runtimeAssertsMode: String? = "ignore"
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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<*> }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user