[K/N] New Version of memoryModel option
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 bf52f48..5d55596 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
@@ -249,19 +249,24 @@
put(ENABLE_ASSERTIONS, arguments.enableAssertions)
- val memoryModelFromArgument = when (arguments.memoryModel) {
- "relaxed" -> MemoryModel.RELAXED
- "strict" -> MemoryModel.STRICT
- "experimental" -> MemoryModel.EXPERIMENTAL
+ val memoryManagerFromArgument = when (arguments.memoryModel) {
+ null -> null
+ "strict" -> MemoryManager.LEGACY
+ "experimental" -> MemoryManager.UNRESTRICTED
else -> {
configuration.report(ERROR, "Unsupported memory model ${arguments.memoryModel}")
- MemoryModel.STRICT
+ null
}
+ }?.also {
+ configuration.report(WARNING, "-memory-model option is deprecated, use binary option memoryManager instead")
}
// TODO: revise priority and/or report conflicting values.
- val memoryModel = get(BinaryOptions.memoryModel) ?: memoryModelFromArgument
- put(BinaryOptions.memoryModel, memoryModel)
+ val memoryManager = get(BinaryOptions.memoryManager) ?: memoryManagerFromArgument ?: MemoryManager.LEGACY
+ if (memoryManagerFromArgument != null && memoryManager != memoryManagerFromArgument) {
+ configuration.report(ERROR, "Conflicting values on -memory-model le")
+ }
+ put(BinaryOptions.memoryManager, memoryManager)
when {
arguments.generateWorkerTestRunner -> put(GENERATE_TEST_RUNNER, TestRunnerKind.WORKER)
@@ -317,8 +322,8 @@
DestroyRuntimeMode.ON_SHUTDOWN
}
})
- if (arguments.gc != null && memoryModel != MemoryModel.EXPERIMENTAL) {
- configuration.report(ERROR, "-Xgc is only supported for -memory-model experimental")
+ if (arguments.gc != null && memoryManager != MemoryManager.UNRESTRICTED) {
+ configuration.report(ERROR, "-Xgc is only supported for unrestricted memory manager")
}
putIfNotNull(GARBAGE_COLLECTOR, when (arguments.gc) {
null -> null
@@ -332,8 +337,8 @@
})
put(PROPERTY_LAZY_INITIALIZATION, when (arguments.propertyLazyInitialization) {
null -> {
- when (memoryModel) {
- MemoryModel.EXPERIMENTAL -> true
+ when (memoryManager) {
+ MemoryManager.UNRESTRICTED -> true
else -> false
}
}
@@ -346,8 +351,8 @@
})
put(ALLOCATION_MODE, when (arguments.allocator) {
null -> {
- when (memoryModel) {
- MemoryModel.EXPERIMENTAL -> "mimalloc"
+ when (memoryManager) {
+ MemoryManager.UNRESTRICTED -> "mimalloc"
else -> "std"
}
}
@@ -359,7 +364,7 @@
}
})
put(WORKER_EXCEPTION_HANDLING, when (arguments.workerExceptionHandling) {
- null -> if (memoryModel == MemoryModel.EXPERIMENTAL) WorkerExceptionHandling.USE_HOOK else WorkerExceptionHandling.LEGACY
+ null -> if (memoryManager == MemoryManager.UNRESTRICTED) WorkerExceptionHandling.USE_HOOK else WorkerExceptionHandling.LEGACY
"legacy" -> WorkerExceptionHandling.LEGACY
"use-hook" -> WorkerExceptionHandling.USE_HOOK
else -> {
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 1545894..91abf35 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
@@ -48,7 +48,7 @@
var manifestFile: String? = null
@Argument(value="-memory-model", valueDescription = "<model>", description = "Memory model to use, 'strict' and 'experimental' are currently supported")
- var memoryModel: String? = "strict"
+ var memoryModel: String? = null
@Argument(value="-module-name", deprecatedName = "-module_name", valueDescription = "<name>", description = "Specify a name for the compilation module")
var moduleName: String? = null
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BinaryOptions.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BinaryOptions.kt
index a043051..c84b91d 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BinaryOptions.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BinaryOptions.kt
@@ -8,13 +8,23 @@
import org.jetbrains.kotlin.config.CompilerConfigurationKey
import kotlin.properties.PropertyDelegateProvider
import kotlin.properties.ReadOnlyProperty
+import kotlin.reflect.*
// Note: options defined in this class are a part of user interface, including the names:
// users can pass these options using a -Xbinary=name=value compiler argument or corresponding Gradle DSL.
object BinaryOptions : BinaryOptionRegistry() {
val runtimeAssertionsMode by option<RuntimeAssertsMode>()
- val memoryModel by option<MemoryModel>()
+ val memoryManager by option<MemoryManager>()
+
+ @Deprecated("Use memoryManager instead")
+ val memoryModel by option<MemoryModel>().replacedBy(this::memoryManager) {
+ when (it) {
+ MemoryModel.RELAXED -> null
+ MemoryModel.STRICT -> MemoryManager.LEGACY
+ MemoryModel.EXPERIMENTAL -> MemoryManager.UNRESTRICTED
+ }
+ }
val freezing by option<Freezing>()
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt
index b77ed5c..774df37 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt
@@ -54,7 +54,7 @@
val ignoreReason = when {
configuration.getBoolean(KonanConfigKeys.OPTIMIZATION) -> "for optimized compilation"
- configuration.get(BinaryOptions.memoryModel) == MemoryModel.EXPERIMENTAL -> "with experimental memory model"
+ configuration.get(BinaryOptions.memoryManager) == MemoryManager.UNRESTRICTED -> "with unrestricted memory manager"
configuration.getBoolean(KonanConfigKeys.PROPERTY_LAZY_INITIALIZATION) -> "with experimental lazy top levels initialization"
configuration.get(BinaryOptions.stripDebugInfoFromNativeLibs) == false -> "with native libs debug info"
else -> null
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt
index 9a416ff..c9827ff 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt
@@ -41,7 +41,6 @@
import kotlin.reflect.KProperty
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyToWithoutSuperTypes
-import org.jetbrains.kotlin.backend.konan.ir.getSuperClassNotAny
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker
@@ -460,7 +459,7 @@
fun ghaEnabled() = ::globalHierarchyAnalysisResult.isInitialized
fun useLazyFileInitializers() = config.propertyLazyInitialization
- val memoryModel = config.memoryModel
+ val memoryManager = config.memoryManager
override var inVerbosePhase = false
override fun log(message: () -> String) {
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
index d8950b4..2c99c24 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
@@ -56,26 +56,20 @@
?: target.family.isAppleFamily // Default is true for Apple targets.
val generateDebugTrampoline = debug && configuration.get(KonanConfigKeys.GENERATE_DEBUG_TRAMPOLINE) ?: false
- val memoryModel: MemoryModel by lazy {
- when (configuration.get(BinaryOptions.memoryModel)!!) {
- MemoryModel.STRICT -> MemoryModel.STRICT
- MemoryModel.RELAXED -> {
- configuration.report(CompilerMessageSeverity.ERROR,
- "Relaxed memory model is deprecated and isn't expected to work right way with current Kotlin version." +
- " Use strict as default. ")
- MemoryModel.STRICT
- }
- MemoryModel.EXPERIMENTAL -> {
+ val memoryManager: MemoryManager by lazy {
+ when (configuration.get(BinaryOptions.memoryManager)!!) {
+ MemoryManager.LEGACY -> MemoryManager.LEGACY
+ MemoryManager.UNRESTRICTED -> {
if (!target.supportsThreads()) {
configuration.report(CompilerMessageSeverity.STRONG_WARNING,
- "Experimental memory model requires threads, which are not supported on target ${target.name}. Used strict memory model.")
- MemoryModel.STRICT
+ "Unrestricted memory manager requires threads, which are not supported on target ${target.name}. Used legacy memory manager.")
+ MemoryManager.LEGACY
} else if (destroyRuntimeMode == DestroyRuntimeMode.LEGACY) {
configuration.report(CompilerMessageSeverity.STRONG_WARNING,
- "Experimental memory model is incompatible with 'legacy' destroy runtime mode. Used strict memory model.")
- MemoryModel.STRICT
+ "Unrestricted memory manager is incompatible with 'legacy' destroy runtime mode. Used legacy memory manager.")
+ MemoryManager.LEGACY
} else {
- MemoryModel.EXPERIMENTAL
+ MemoryManager.UNRESTRICTED
}
}
}
@@ -100,11 +94,11 @@
val freezing: Freezing by lazy {
val freezingMode = configuration.get(BinaryOptions.freezing)
when {
- freezingMode == null -> when (memoryModel) {
- MemoryModel.EXPERIMENTAL -> Freezing.Disabled
+ freezingMode == null -> when (memoryManager) {
+ MemoryManager.UNRESTRICTED -> Freezing.Disabled
else -> Freezing.Full
}
- memoryModel != MemoryModel.EXPERIMENTAL && freezingMode != Freezing.Full -> {
+ memoryManager != MemoryManager.UNRESTRICTED && freezingMode != Freezing.Full -> {
configuration.report(
CompilerMessageSeverity.ERROR,
"`freezing` can only be adjusted with experimental MM. Falling back to default behavior.")
@@ -227,16 +221,12 @@
} else {
false
}
- when (memoryModel) {
- MemoryModel.STRICT -> {
+ when (memoryManager) {
+ MemoryManager.LEGACY -> {
add("strict.bc")
add("legacy_memory_manager.bc")
}
- MemoryModel.RELAXED -> {
- add("relaxed.bc")
- add("legacy_memory_manager.bc")
- }
- MemoryModel.EXPERIMENTAL -> {
+ MemoryManager.UNRESTRICTED -> {
add("common_gc.bc")
add("experimental_memory_manager.bc")
when (gc) {
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/MemoryManager.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/MemoryManager.kt
new file mode 100644
index 0000000..a07ab8a
--- /dev/null
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/MemoryManager.kt
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.backend.konan
+
+enum class MemoryManager {
+ LEGACY,
+ UNRESTRICTED
+}
\ No newline at end of file
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt
index 7916b9c..6ff2489 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt
@@ -266,7 +266,7 @@
}
internal fun IrClass.isFrozen(context: Context): Boolean {
- val isLegacyMM = context.memoryModel != MemoryModel.EXPERIMENTAL
+ val isLegacyMM = context.memoryManager == MemoryManager.LEGACY
return when {
!context.config.freezing.freezeImplicit -> false
annotations.hasAnnotation(KonanFqNames.frozen) -> true
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt
index 088b859..7cdaa60 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt
@@ -281,7 +281,7 @@
fun isEmpty() = stackLocals.isEmpty()
private fun FunctionGenerationContext.createRootSetSlot() =
- if (context.memoryModel == MemoryModel.EXPERIMENTAL) alloca(kObjHeaderPtr) else null
+ if (context.memoryManager == MemoryManager.UNRESTRICTED) alloca(kObjHeaderPtr) else null
override fun alloc(irClass: IrClass, cleanFieldsExplicitly: Boolean): LLVMValueRef = with(functionGenerationContext) {
val type = context.llvmDeclarations.forClass(irClass).bodyType
@@ -478,13 +478,13 @@
// because there is no guarantee of catching Kotlin exception in Kotlin code.
protected open val needCleanupLandingpadAndLeaveFrame: Boolean
get() = irFunction?.annotations?.hasAnnotation(RuntimeNames.exportForCppRuntime) == true || // Exported to foreign code
- (!stackLocalsManager.isEmpty() && context.memoryModel != MemoryModel.EXPERIMENTAL) ||
+ (!stackLocalsManager.isEmpty() && context.memoryManager != MemoryManager.UNRESTRICTED) ||
switchToRunnable
private var setCurrentFrameIsCalled: Boolean = false
private val switchToRunnable: Boolean =
- context.memoryModel == MemoryModel.EXPERIMENTAL && switchToRunnable
+ context.memoryManager == MemoryManager.UNRESTRICTED && switchToRunnable
val stackLocalsManager = StackLocalsManagerImpl(this, stackLocalsInitBb)
@@ -619,12 +619,12 @@
}
fun checkGlobalsAccessible(exceptionHandler: ExceptionHandler) {
- if (context.memoryModel == MemoryModel.STRICT)
+ if (context.memoryManager == MemoryManager.LEGACY)
call(context.llvm.checkGlobalsAccessible, emptyList(), Lifetime.IRRELEVANT, exceptionHandler)
}
private fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) {
- if (context.memoryModel == MemoryModel.STRICT)
+ if (context.memoryManager == MemoryManager.LEGACY)
store(value, address)
else
call(context.llvm.updateReturnRefFunction, listOf(address, value))
@@ -632,7 +632,7 @@
private fun updateRef(value: LLVMValueRef, address: LLVMValueRef, onStack: Boolean) {
if (onStack) {
- if (context.memoryModel == MemoryModel.STRICT)
+ if (context.memoryManager == MemoryManager.LEGACY)
store(value, address)
else
call(context.llvm.updateStackRefFunction, listOf(address, value))
@@ -644,7 +644,7 @@
//-------------------------------------------------------------------------//
fun switchThreadState(state: ThreadState) {
- check(context.memoryModel == MemoryModel.EXPERIMENTAL) {
+ check(context.memoryManager == MemoryManager.UNRESTRICTED) {
"Thread state switching is allowed in the experimental memory model only."
}
check(!forbidRuntime) {
@@ -657,7 +657,7 @@
}
fun switchThreadStateIfExperimentalMM(state: ThreadState) {
- if (context.memoryModel == MemoryModel.EXPERIMENTAL) {
+ if (context.memoryManager == MemoryManager.UNRESTRICTED) {
switchThreadState(state)
}
}
@@ -1501,7 +1501,7 @@
} else {
check(!setCurrentFrameIsCalled)
}
- if (context.memoryModel == MemoryModel.EXPERIMENTAL && !forbidRuntime) {
+ if (context.memoryManager == MemoryManager.UNRESTRICTED && !forbidRuntime) {
call(context.llvm.Kotlin_mm_safePointFunctionPrologue, emptyList())
}
resetDebugLocation()
@@ -1699,7 +1699,7 @@
call(context.llvm.leaveFrameFunction,
listOf(slotsPhi!!, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm))
}
- if (!stackLocalsManager.isEmpty() && context.memoryModel != MemoryModel.EXPERIMENTAL) {
+ if (!stackLocalsManager.isEmpty() && context.memoryManager != MemoryManager.UNRESTRICTED) {
stackLocalsManager.clean(refsOnly = true) // Only bother about not leaving any dangling references.
}
}
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt
index 2a5002f..1d9690e 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt
@@ -2,9 +2,7 @@
import kotlinx.cinterop.cValuesOf
import llvm.*
-import org.jetbrains.kotlin.backend.konan.KonanFqNames
-import org.jetbrains.kotlin.backend.konan.MemoryModel
-import org.jetbrains.kotlin.backend.konan.RuntimeNames
+import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue
import org.jetbrains.kotlin.backend.konan.descriptors.isConstantConstructorIntrinsic
import org.jetbrains.kotlin.backend.konan.descriptors.isTypedIntrinsic
@@ -304,7 +302,7 @@
args.single()
private fun FunctionGenerationContext.emitIsExperimentalMM(): LLVMValueRef =
- Int1(context.memoryModel == MemoryModel.EXPERIMENTAL).llvm
+ Int1(context.memoryManager == MemoryManager.UNRESTRICTED).llvm
private fun FunctionGenerationContext.emitGetNativeNullPtr(): LLVMValueRef =
kNullInt8Ptr
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 15a895c..79b2167 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
@@ -59,7 +59,7 @@
internal fun IrField.storageKind(context: Context): FieldStorageKind {
// TODO: Is this correct?
val annotations = correspondingPropertySymbol?.owner?.annotations ?: annotations
- val isLegacyMM = context.memoryModel != MemoryModel.EXPERIMENTAL
+ val isLegacyMM = context.memoryManager != MemoryManager.UNRESTRICTED
// TODO: simplify, once IR types are fully there.
val typeAnnotations = (type.classifierOrNull?.owner as? IrAnnotationContainer)?.annotations
val typeFrozen = typeAnnotations?.hasAnnotation(KonanFqNames.frozen) == true ||
@@ -75,7 +75,7 @@
}
internal fun IrField.needsGCRegistration(context: Context) =
- context.memoryModel == MemoryModel.EXPERIMENTAL && // only for the new MM
+ context.memoryManager == MemoryManager.UNRESTRICTED && // only for the new MM
type.binaryTypeIsReference() && // only for references
(hasNonConstInitializer || // which are initialized from heap object
!isFinal) // or are not final
@@ -1352,7 +1352,7 @@
functionGenerationContext.condBr(condition, loopBody, loopScope.loopExit)
functionGenerationContext.positionAtEnd(loopBody)
- if (context.memoryModel == MemoryModel.EXPERIMENTAL)
+ if (context.memoryManager == MemoryManager.UNRESTRICTED)
call(context.llvm.Kotlin_mm_safePointWhileLoopBody, emptyList())
loop.body?.generate()
@@ -1374,7 +1374,7 @@
functionGenerationContext.br(loopBody)
functionGenerationContext.positionAtEnd(loopBody)
- if (context.memoryModel == MemoryModel.EXPERIMENTAL)
+ if (context.memoryManager == MemoryManager.UNRESTRICTED)
call(context.llvm.Kotlin_mm_safePointWhileLoopBody, emptyList())
loop.body?.generate()
functionGenerationContext.br(loopScope.loopCheck)
@@ -2600,7 +2600,7 @@
private val IrFunction.needsNativeThreadState: Boolean
get() {
// We assume that call site thread state switching is required for interop calls only.
- val result = context.memoryModel == MemoryModel.EXPERIMENTAL && origin == CBridgeOrigin.KOTLIN_TO_C_BRIDGE
+ val result = context.memoryManager == MemoryManager.UNRESTRICTED && origin == CBridgeOrigin.KOTLIN_TO_C_BRIDGE
if (result) {
check(isExternal)
check(!annotations.hasAnnotation(KonanFqNames.gcUnsafeCall))
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt
index 4843cb4..4f50593 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt
@@ -12,6 +12,7 @@
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_ENUM
+import org.jetbrains.kotlin.backend.konan.MemoryManager
import org.jetbrains.kotlin.backend.konan.MemoryModel
import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType
import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType
@@ -299,7 +300,7 @@
}
}
// Needed for legacy MM targets that do not support threads.
- if (this@EnumClassLowering.context.memoryModel != MemoryModel.EXPERIMENTAL) {
+ if (this@EnumClassLowering.context.memoryManager != MemoryManager.UNRESTRICTED) {
+irCall(this@EnumClassLowering.context.ir.symbols.freeze, listOf(arrayType)).apply {
extensionReceiver = irGet(receiver)
}