From 3798920183e9180795726ac89d18c4355dac4520 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Wed, 19 Jan 2022 16:15:20 +0300 Subject: [PATCH] [K/N] Any.isFrozen is now always false when freezing is disabled --- .../kotlin/backend/konan/Freezing.kt | 9 +++-- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 1 + .../backend.native/tests/build.gradle | 32 ++++++++++++---- .../tests/interop/objc/tests/sharing.kt | 17 +++++---- .../tests/objcexport/expectedLazy.h | 1 + .../expectedLazyLegacySuspendUnit.h | 1 + .../tests/objcexport/expectedLazyNoGenerics.h | 1 + .../backend.native/tests/objcexport/values.kt | 1 + .../tests/objcexport/values.swift | 3 ++ .../tests/runtime/collections/typed_array1.kt | 38 ++++++++++--------- .../concurrent/worker_bound_reference0.kt | 6 +++ .../tests/runtime/workers/atomic0.kt | 22 ++++++----- .../tests/runtime/workers/lazy1.kt | 8 ++-- .../src/main/cpp/CompilerConstants.cpp | 5 +++ .../src/main/cpp/CompilerConstants.hpp | 2 + .../runtime/src/main/cpp/Runtime.cpp | 4 ++ kotlin-native/runtime/src/main/cpp/Worker.cpp | 1 + .../src/main/kotlin/kotlin/native/Platform.kt | 12 ++++++ kotlin-native/runtime/src/mm/cpp/Freezing.cpp | 1 + kotlin-native/runtime/src/mm/cpp/Memory.cpp | 1 + 20 files changed, 116 insertions(+), 50 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Freezing.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Freezing.kt index fecf196c7bb..f0bcfa033c3 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Freezing.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Freezing.kt @@ -11,22 +11,23 @@ package org.jetbrains.kotlin.backend.konan * * If [enableFreezeAtRuntime] is false then `Any.freeze()` and `checkIfFrozen(ref: Any?)` are no-op. * [freezeImplicit] enabled freezing for @Frozen types and @SharedImmutable globals (i.e. implicit calls to `Any.freeze()`). + * If [enableFreezeChecks] is false, than `Any.isFrozen() will always return false, and no [InvalidMutabilityException] can be thrown */ -enum class Freezing(val enableFreezeAtRuntime: Boolean, val freezeImplicit: Boolean) { +enum class Freezing(val enableFreezeAtRuntime: Boolean, val freezeImplicit: Boolean, val enableFreezeChecks: Boolean) { /** * Enable freezing in `Any.freeze()` as well as for @Frozen types and @SharedImmutable globals. */ - Full(true, true), + Full(true, true, true), /** * Enable freezing only in explicit calls to `Any.freeze()`. */ - ExplicitOnly(true, false), + ExplicitOnly(true, false, true), /** * No freezing at all. */ - Disabled(false, false); + Disabled(false, false, false); companion object { // Users might depend on runtime guarantees of freezing, so it should be enabled by default. 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 267e5d431a3..15a895c39dd 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 @@ -2742,6 +2742,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map null diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index d818760baa0..bff8d39b426 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -1152,52 +1152,68 @@ standaloneTest("worker_threadlocal_no_leak") { source = "runtime/workers/worker_threadlocal_no_leak.kt" } -task freeze0(type: KonanLocalTest) { +standaloneTest("freeze0") { enabled = (project.testTarget != 'wasm32') // No workers on WASM. useGoldenData = true + flags = ["-Xbinary=freezing=full", "-tr"] source = "runtime/workers/freeze0.kt" + testLogger = KonanTest.Logger.SILENT } -task freeze1(type: KonanLocalTest) { +standaloneTest("freeze1") { enabled = (project.testTarget != 'wasm32') // No exceptions on WASM. useGoldenData = true + flags = ["-Xbinary=freezing=full", "-tr"] source = "runtime/workers/freeze1.kt" + testLogger = KonanTest.Logger.SILENT } -task freeze_stress(type: KonanLocalTest) { +standaloneTest("freeze_stress") { enabled = (project.testTarget != 'wasm32') // No exceptions on WASM. useGoldenData = true + flags = ["-Xbinary=freezing=full", "-tr"] source = "runtime/workers/freeze_stress.kt" + testLogger = KonanTest.Logger.SILENT } -task freeze2(type: KonanLocalTest) { +standaloneTest("freeze2") { enabled = (project.testTarget != 'wasm32') // No exceptions on WASM. useGoldenData = true + flags = ["-Xbinary=freezing=full", "-tr"] source = "runtime/workers/freeze2.kt" + testLogger = KonanTest.Logger.SILENT } -task freeze3(type: KonanLocalTest) { +standaloneTest("freeze3") { enabled = (project.testTarget != 'wasm32') // No exceptions on WASM. useGoldenData = true + flags = ["-Xbinary=freezing=full", "-tr"] source = "runtime/workers/freeze3.kt" + testLogger = KonanTest.Logger.SILENT } -task freeze4(type: KonanLocalTest) { +standaloneTest("freeze4") { enabled = (project.testTarget != 'wasm32') // No exceptions on WASM. useGoldenData = true + flags = ["-Xbinary=freezing=full", "-tr"] source = "runtime/workers/freeze4.kt" + testLogger = KonanTest.Logger.SILENT } -task freeze5(type: KonanLocalTest) { +standaloneTest("freeze5") { useGoldenData = true + flags = ["-Xbinary=freezing=full", "-tr"] source = "runtime/workers/freeze5.kt" + testLogger = KonanTest.Logger.SILENT } -task freeze6(type: KonanLocalTest) { +standaloneTest("freeze6") { enabled = (project.testTarget != 'wasm32') && // No exceptions on WASM. !isNoopGC useGoldenData = true + flags = ["-Xbinary=freezing=full", "-tr"] source = "runtime/workers/freeze6.kt" + testLogger = KonanTest.Logger.SILENT } task atomic0(type: KonanLocalTest) { diff --git a/kotlin-native/backend.native/tests/interop/objc/tests/sharing.kt b/kotlin-native/backend.native/tests/interop/objc/tests/sharing.kt index 0d72e58337c..6755484edd0 100644 --- a/kotlin-native/backend.native/tests/interop/objc/tests/sharing.kt +++ b/kotlin-native/backend.native/tests/interop/objc/tests/sharing.kt @@ -15,17 +15,18 @@ private class NSObjectImpl : NSObject() { assertFalse(obj.isFrozen) obj.x = 222 - obj.freeze() - assertTrue(obj.isFrozen) - runInWorker { - val obj1 = array.objectAtIndex(0) as NSObjectImpl - assertFailsWith { - obj1.x = 333 + if (Platform.isFreezingEnabled) { + obj.freeze() + assertTrue(obj.isFrozen) + runInWorker { + val obj1 = array.objectAtIndex(0) as NSObjectImpl + assertFailsWith { + obj1.x = 333 + } } + assertEquals(222, obj.x) } - assertEquals(222, obj.x) - // TODO: test [obj release] etc. } diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h index 2826ec0ebae..7a6a71e082b 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h @@ -2627,6 +2627,7 @@ __attribute__((swift_name("ValuesKt"))) + (KtTripleVals * _Nullable)getValue3:(id _Nullable)receiver __attribute__((swift_name("getValue3(_:)"))); + (KtTripleVals * _Nullable)getValueOrNull3:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull3(_:)"))); + (BOOL)isFrozenObj:(id)obj __attribute__((swift_name("isFrozen(obj:)"))); ++ (BOOL)isFreezingEnabled __attribute__((swift_name("isFreezingEnabled()"))); + (id)kotlinLambdaBlock:(id (^)(id))block __attribute__((swift_name("kotlinLambda(block:)"))); + (int64_t)multiplyInt:(int32_t)int_ long:(int64_t)long_ __attribute__((swift_name("multiply(int:long:)"))); diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h b/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h index 380ad6b770f..92c3ac6692c 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazyLegacySuspendUnit.h @@ -2569,6 +2569,7 @@ __attribute__((swift_name("ValuesKt"))) + (KtTripleVals * _Nullable)getValue3:(id _Nullable)receiver __attribute__((swift_name("getValue3(_:)"))); + (KtTripleVals * _Nullable)getValueOrNull3:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull3(_:)"))); + (BOOL)isFrozenObj:(id)obj __attribute__((swift_name("isFrozen(obj:)"))); ++ (BOOL)isFreezingEnabled __attribute__((swift_name("isFreezingEnabled()"))); + (id)kotlinLambdaBlock:(id (^)(id))block __attribute__((swift_name("kotlinLambda(block:)"))); + (int64_t)multiplyInt:(int32_t)int_ long:(int64_t)long_ __attribute__((swift_name("multiply(int:long:)"))); diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h b/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h index b67af84fb78..5474544e019 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazyNoGenerics.h @@ -2569,6 +2569,7 @@ __attribute__((swift_name("ValuesKt"))) + (KtTripleVals * _Nullable)getValue3:(id _Nullable)receiver __attribute__((swift_name("getValue3(_:)"))); + (KtTripleVals * _Nullable)getValueOrNull3:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull3(_:)"))); + (BOOL)isFrozenObj:(id)obj __attribute__((swift_name("isFrozen(obj:)"))); ++ (BOOL)isFreezingEnabled __attribute__((swift_name("isFreezingEnabled()"))); + (id)kotlinLambdaBlock:(id (^)(id))block __attribute__((swift_name("kotlinLambda(block:)"))); + (int64_t)multiplyInt:(int32_t)int_ long:(int64_t)long_ __attribute__((swift_name("multiply(int:long:)"))); diff --git a/kotlin-native/backend.native/tests/objcexport/values.kt b/kotlin-native/backend.native/tests/objcexport/values.kt index 922fce309fe..e3c7fb94fd3 100644 --- a/kotlin-native/backend.native/tests/objcexport/values.kt +++ b/kotlin-native/backend.native/tests/objcexport/values.kt @@ -250,6 +250,7 @@ fun IC3.getValue3() = value fun IC3?.getValueOrNull3() = this?.value fun isFrozen(obj: Any): Boolean = obj.isFrozen +fun isFreezingEnabled() = Platform.isFreezingEnabled fun kotlinLambda(block: (Any) -> Any): Any = block fun multiply(int: Int, long: Long) = int * long diff --git a/kotlin-native/backend.native/tests/objcexport/values.swift b/kotlin-native/backend.native/tests/objcexport/values.swift index e03fa5834bc..89e4f478923 100644 --- a/kotlin-native/backend.native/tests/objcexport/values.swift +++ b/kotlin-native/backend.native/tests/objcexport/values.swift @@ -590,6 +590,9 @@ class TestSharedIImpl : NSObject, I { } func testShared() throws { + if !ValuesKt.isFreezingEnabled() { + return; + } func assertFrozen(_ obj: AnyObject) throws { try assertTrue(ValuesKt.isFrozen(obj: obj), "isFrozen(\(obj))") } diff --git a/kotlin-native/backend.native/tests/runtime/collections/typed_array1.kt b/kotlin-native/backend.native/tests/runtime/collections/typed_array1.kt index 62f49a5b17d..76518e0ba9f 100644 --- a/kotlin-native/backend.native/tests/runtime/collections/typed_array1.kt +++ b/kotlin-native/backend.native/tests/runtime/collections/typed_array1.kt @@ -50,24 +50,26 @@ import kotlin.native.concurrent.* } expect(0) { results.size } - array.freeze() - assertFailsWith { - array.setShortAt(0, 2.toShort()) - } - assertFailsWith { - array.setCharAt(0, 'a') - } - assertFailsWith { - array.setIntAt(0, 2) - } - assertFailsWith { - array.setLongAt(0, 2) - } - assertFailsWith { - array.setFloatAt(0, 1.0f) - } - assertFailsWith { - array.setDoubleAt(0, 1.0) + if (Platform.isFreezingEnabled) { + array.freeze() + assertFailsWith { + array.setShortAt(0, 2.toShort()) + } + assertFailsWith { + array.setCharAt(0, 'a') + } + assertFailsWith { + array.setIntAt(0, 2) + } + assertFailsWith { + array.setLongAt(0, 2) + } + assertFailsWith { + array.setFloatAt(0, 1.0f) + } + assertFailsWith { + array.setDoubleAt(0, 1.0) + } } println("OK") } \ No newline at end of file diff --git a/kotlin-native/backend.native/tests/runtime/concurrent/worker_bound_reference0.kt b/kotlin-native/backend.native/tests/runtime/concurrent/worker_bound_reference0.kt index edf2cd2bb4f..50346c9c929 100644 --- a/kotlin-native/backend.native/tests/runtime/concurrent/worker_bound_reference0.kt +++ b/kotlin-native/backend.native/tests/runtime/concurrent/worker_bound_reference0.kt @@ -9,6 +9,7 @@ import kotlin.test.* import kotlin.native.concurrent.* import kotlin.native.internal.GC +import kotlin.native.* import kotlin.native.ref.WeakReference import kotlin.text.Regex @@ -600,6 +601,7 @@ fun createCyclicGarbageFrozen(): Triple @Test fun doesNotCollectCyclicGarbageFrozen() { + if (!Platform.isFreezingEnabled) return val (ref1Owner, ref1Weak, ref2Weak) = createCyclicGarbageFrozen() ref1Owner.value = null @@ -630,6 +632,7 @@ fun createCrossThreadCyclicGarbageFrozen( @Test fun doesNotCollectCrossThreadCyclicGarbageFrozen() { + if (!Platform.isFreezingEnabled) return val worker = Worker.start() val (ref1Owner, ref1Weak, ref2Weak) = createCrossThreadCyclicGarbageFrozen(worker) @@ -674,6 +677,7 @@ fun dispose(refOwner: AtomicReference?>) { @Test fun doesNotCollectCyclicGarbageWithAtomicsFrozen() { + if (!Platform.isFreezingEnabled) return val (ref1Owner, ref1Weak, ref2Weak) = createCyclicGarbageWithAtomicsFrozen() ref1Owner.value = null @@ -723,6 +727,7 @@ fun createCrossThreadCyclicGarbageWithAtomicsFrozen( @Test fun doesNotCollectCrossThreadCyclicGarbageWithAtomicsFrozen() { + if (!Platform.isFreezingEnabled) return val worker = Worker.start() val (ref1Owner, ref1Weak, ref2Weak) = createCrossThreadCyclicGarbageWithAtomicsFrozen(worker) @@ -835,6 +840,7 @@ fun testDoubleFreeze() { @Test fun testDoubleFreezeWithFreezeBlocker() { + if (!Platform.isFreezingEnabled) return val ref = WorkerBoundReference(A(3)) val wrapper = Wrapper(ref) wrapper.ensureNeverFrozen() diff --git a/kotlin-native/backend.native/tests/runtime/workers/atomic0.kt b/kotlin-native/backend.native/tests/runtime/workers/atomic0.kt index 0a3a4f101f0..c30743249fb 100644 --- a/kotlin-native/backend.native/tests/runtime/workers/atomic0.kt +++ b/kotlin-native/backend.native/tests/runtime/workers/atomic0.kt @@ -93,10 +93,12 @@ fun test4() { ref.compareAndSwap(null, Data(2)) assertEquals(2, ref.value!!.value) } - run { - val ref = AtomicReference(null).freeze() - assertFailsWith { - ref.compareAndSwap(null, Data(2)) + if (Platform.isFreezingEnabled) { + run { + val ref = AtomicReference(null).freeze() + assertFailsWith { + ref.compareAndSwap(null, Data(2)) + } } } } @@ -137,11 +139,13 @@ fun test7() { ref.value = Array(1) { "po" } assertEquals(ref.value[0], "po") ref.freeze() - assertFailsWith { - ref.value = Array(1) { "no" } - } - assertFailsWith { - ref.value[0] = "go" + if (Platform.isFreezingEnabled) { + assertFailsWith { + ref.value = Array(1) { "no" } + } + assertFailsWith { + ref.value[0] = "go" + } } ref.value = Array(1) { "so" }.freeze() assertEquals(ref.value[0], "so") diff --git a/kotlin-native/backend.native/tests/runtime/workers/lazy1.kt b/kotlin-native/backend.native/tests/runtime/workers/lazy1.kt index d22a174b7c0..36da4acf9ad 100644 --- a/kotlin-native/backend.native/tests/runtime/workers/lazy1.kt +++ b/kotlin-native/backend.native/tests/runtime/workers/lazy1.kt @@ -81,9 +81,11 @@ private val checkedLazyModes = @Test fun runTest3() { - for (mode in checkedLazyModes) { - assertFailsWith { - println(Lazy(mode).freezer) + if (Platform.isFreezingEnabled) { + for (mode in checkedLazyModes) { + assertFailsWith { + println(Lazy(mode).freezer) + } } } } diff --git a/kotlin-native/runtime/src/main/cpp/CompilerConstants.cpp b/kotlin-native/runtime/src/main/cpp/CompilerConstants.cpp index 48deebe89c6..4e716062fba 100644 --- a/kotlin-native/runtime/src/main/cpp/CompilerConstants.cpp +++ b/kotlin-native/runtime/src/main/cpp/CompilerConstants.cpp @@ -15,6 +15,7 @@ RUNTIME_WEAK int32_t Kotlin_destroyRuntimeMode = 1; RUNTIME_WEAK int32_t Kotlin_gcSchedulerType = 2; RUNTIME_WEAK int32_t Kotlin_workerExceptionHandling = 0; RUNTIME_WEAK int32_t Kotlin_freezingEnabled = 1; +RUNTIME_WEAK int32_t Kotlin_freezingChecksEnabled = 1; RUNTIME_WEAK const Kotlin_getSourceInfo_FunctionType Kotlin_getSourceInfo_Function = nullptr; #ifdef KONAN_ANDROID RUNTIME_WEAK int32_t Kotlin_printToAndroidLogcat = 1; @@ -32,6 +33,10 @@ ALWAYS_INLINE bool compiler::freezingEnabled() noexcept { return Kotlin_freezingEnabled != 0; } +ALWAYS_INLINE bool compiler::freezingChecksEnabled() noexcept { + return Kotlin_freezingChecksEnabled != 0; +} + ALWAYS_INLINE compiler::GCSchedulerType compiler::getGCSchedulerType() noexcept { return static_cast(Kotlin_gcSchedulerType); } diff --git a/kotlin-native/runtime/src/main/cpp/CompilerConstants.hpp b/kotlin-native/runtime/src/main/cpp/CompilerConstants.hpp index d64ddb266eb..5f8affebab8 100644 --- a/kotlin-native/runtime/src/main/cpp/CompilerConstants.hpp +++ b/kotlin-native/runtime/src/main/cpp/CompilerConstants.hpp @@ -79,6 +79,8 @@ ALWAYS_INLINE inline std::string_view runtimeLogs() noexcept { } bool freezingEnabled() noexcept; +bool freezingChecksEnabled() noexcept; + ALWAYS_INLINE inline int getSourceInfo(void* addr, SourceInfo *result, int result_size) { if (Kotlin_getSourceInfo_Function == nullptr) { diff --git a/kotlin-native/runtime/src/main/cpp/Runtime.cpp b/kotlin-native/runtime/src/main/cpp/Runtime.cpp index 4cb3a31d3a2..e14701c553d 100644 --- a/kotlin-native/runtime/src/main/cpp/Runtime.cpp +++ b/kotlin-native/runtime/src/main/cpp/Runtime.cpp @@ -365,6 +365,10 @@ KBoolean Konan_Platform_isDebugBinary() { return kotlin::compiler::shouldContainDebugInfo(); } +KBoolean Konan_Platform_isFreezingEnabled() { + return kotlin::compiler::freezingChecksEnabled(); +} + bool Kotlin_memoryLeakCheckerEnabled() { return g_checkLeaks; } diff --git a/kotlin-native/runtime/src/main/cpp/Worker.cpp b/kotlin-native/runtime/src/main/cpp/Worker.cpp index 1fff95e2c62..48885f8208a 100644 --- a/kotlin-native/runtime/src/main/cpp/Worker.cpp +++ b/kotlin-native/runtime/src/main/cpp/Worker.cpp @@ -1208,6 +1208,7 @@ void Kotlin_Worker_freezeInternal(KRef object) { } KBoolean Kotlin_Worker_isFrozenInternal(KRef object) { + if (!compiler::freezingChecksEnabled()) return false; return object == nullptr || isPermanentOrFrozen(object); } diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/Platform.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/Platform.kt index 2bbfb8f019a..4fa46fbed13 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/Platform.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/Platform.kt @@ -87,6 +87,15 @@ public object Platform { public val isDebugBinary: Boolean get() = Platform_isDebugBinary() + /** + * If freezing is enabled. + * + * This value would be false, only if binary option `freezing` is equal to `disabled`. This is default when + * [memoryModel] is equal to [MemoryModel.EXPERIMENTAL]. + */ + public val isFreezingEnabled: Boolean + get() = Platform_isFreezingEnabled() + /** * If the memory leak checker is activated, by default `true` in debug mode, `false` in release. * When memory leak checker is activated, and leak is detected during last Kotlin context @@ -145,6 +154,9 @@ private external fun Platform_getMemoryModel(): Int @GCUnsafeCall("Konan_Platform_isDebugBinary") private external fun Platform_isDebugBinary(): Boolean +@GCUnsafeCall("Konan_Platform_isFreezingEnabled") +private external fun Platform_isFreezingEnabled(): Boolean + @GCUnsafeCall("Konan_Platform_getMemoryLeakChecker") private external fun Platform_getMemoryLeakChecker(): Boolean diff --git a/kotlin-native/runtime/src/mm/cpp/Freezing.cpp b/kotlin-native/runtime/src/mm/cpp/Freezing.cpp index 6c8ecfd2287..553ebb1a4d1 100644 --- a/kotlin-native/runtime/src/mm/cpp/Freezing.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Freezing.cpp @@ -15,6 +15,7 @@ using namespace kotlin; bool mm::IsFrozen(const ObjHeader* object) noexcept { + if (!compiler::freezingChecksEnabled()) return false; if (object->permanent()) { return true; } diff --git a/kotlin-native/runtime/src/mm/cpp/Memory.cpp b/kotlin-native/runtime/src/mm/cpp/Memory.cpp index ec663285d79..b0b179eaeb8 100644 --- a/kotlin-native/runtime/src/mm/cpp/Memory.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Memory.cpp @@ -91,6 +91,7 @@ void ObjHeader::destroyMetaObject(ObjHeader* object) { ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj) { // TODO: Freeze TF_IMMUTABLE objects upon creation. + if (!compiler::freezingChecksEnabled()) return false; return mm::IsFrozen(obj) || ((obj->type_info()->flags_ & TF_IMMUTABLE) != 0); }