diff --git a/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp b/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp index e46ef5aad73..54e7f287e7e 100644 --- a/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp +++ b/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp @@ -73,6 +73,10 @@ namespace { +ALWAYS_INLINE bool IsStrictMemoryModel() noexcept { + return CurrentMemoryModel == MemoryModel::kStrict; +} + typedef uint32_t container_size_t; // Granularity of arena container chunks. @@ -1026,7 +1030,7 @@ inline void unlock(KInt* spinlock) { } inline bool canFreeze(ContainerHeader* container) { - if (IsStrictMemoryModel) + if (IsStrictMemoryModel()) // In strict memory model we ignore permanent, frozen and shared object when recursively freezing. return container != nullptr && !container->shareable(); else @@ -1393,14 +1397,14 @@ inline void decrementRC(ContainerHeader* container) { inline void decrementRC(ContainerHeader* container) { auto* state = memoryState; - RuntimeAssert(!IsStrictMemoryModel || state->gcInProgress, "Must only be called during GC"); + RuntimeAssert(!IsStrictMemoryModel() || state->gcInProgress, "Must only be called during GC"); // TODO: enable me, once account for inner references in frozen objects correctly. // RuntimeAssert(container->refCount() > 0, "Must be positive"); bool useCycleCollector = container->local(); if (container->decRefCount() == 0) { freeContainer(container); } else if (useCycleCollector && state->toFree != nullptr) { - RuntimeAssert(IsStrictMemoryModel, "No cycle collector in relaxed mode yet"); + RuntimeAssert(IsStrictMemoryModel(), "No cycle collector in relaxed mode yet"); RuntimeAssert(container->refCount() > 0, "Must be positive"); RuntimeAssert(!container->shareable(), "Cycle collector shalln't be used with shared objects yet"); RuntimeAssert(container->objectCount() == 1, "cycle collector shall only work with single object containers"); @@ -1819,7 +1823,7 @@ void incrementStack(MemoryState* state) { } void processDecrements(MemoryState* state) { - RuntimeAssert(IsStrictMemoryModel, "Only works in strict model now"); + RuntimeAssert(IsStrictMemoryModel(), "Only works in strict model now"); auto* toRelease = state->toRelease; state->gcSuspendCount++; while (toRelease->size() > 0) { @@ -1840,7 +1844,7 @@ void processDecrements(MemoryState* state) { } void decrementStack(MemoryState* state) { - RuntimeAssert(IsStrictMemoryModel, "Only works in strict model now"); + RuntimeAssert(IsStrictMemoryModel(), "Only works in strict model now"); state->gcSuspendCount++; FrameOverlay* frame = currentFrame; while (frame != nullptr) { @@ -1868,7 +1872,7 @@ void garbageCollect(MemoryState* state, bool force) { #endif // TRACE_GC state->allocSinceLastGc = 0; - if (!IsStrictMemoryModel) { + if (!IsStrictMemoryModel()) { // In relaxed model we just process finalizer queue and be done with it. processFinalizerQueue(state); return; @@ -1988,7 +1992,7 @@ void garbageCollect() { #endif // USE_GC ForeignRefManager* initLocalForeignRef(ObjHeader* object) { - if (!IsStrictMemoryModel) return nullptr; + if (!IsStrictMemoryModel()) return nullptr; return memoryState->foreignRefManager; } @@ -1996,7 +2000,7 @@ ForeignRefManager* initLocalForeignRef(ObjHeader* object) { ForeignRefManager* initForeignRef(ObjHeader* object) { addHeapRef(object); - if (!IsStrictMemoryModel) return nullptr; + if (!IsStrictMemoryModel()) return nullptr; // Note: it is possible to return nullptr for shared object as an optimization, // but this will force the implementation to release objects on uninitialized threads @@ -2007,7 +2011,7 @@ ForeignRefManager* initForeignRef(ObjHeader* object) { } bool isForeignRefAccessible(ObjHeader* object, ForeignRefManager* manager) { - if (!IsStrictMemoryModel) return true; + if (!IsStrictMemoryModel()) return true; if (manager == memoryState->foreignRefManager) { // Note: it is important that this code neither crashes nor returns false-negative result @@ -2021,7 +2025,7 @@ bool isForeignRefAccessible(ObjHeader* object, ForeignRefManager* manager) { } void deinitForeignRef(ObjHeader* object, ForeignRefManager* manager) { - if (IsStrictMemoryModel) { + if (IsStrictMemoryModel()) { if (memoryState != nullptr && isForeignRefAccessible(object, manager)) { releaseHeapRef(object); } else { @@ -2127,13 +2131,13 @@ void deinitMemory(MemoryState* memoryState, bool destroyRuntime) { atomicAdd(&pendingDeinit, -1); #if TRACE_MEMORY - if (IsStrictMemoryModel && destroyRuntime && allocCount > 0) { + if (IsStrictMemoryModel() && destroyRuntime && allocCount > 0) { MEMORY_LOG("*** Memory leaks, leaked %d containers ***\n", allocCount); dumpReachable("", memoryState->containers); } #else #if USE_GC - if (IsStrictMemoryModel && allocCount > 0 && checkLeaks) { + if (IsStrictMemoryModel() && allocCount > 0 && checkLeaks) { konan::consoleErrorf( "Memory leaks detected, %d objects leaked!\n" "Use `Platform.isMemoryLeakCheckerActive = false` to avoid this check.\n", allocCount); @@ -2441,7 +2445,7 @@ OBJ_GETTER(swapHeapRefLocked, lock(spinlock); ObjHeader* oldValue = *location; bool shallRemember = false; - if (IsStrictMemoryModel) { + if (IsStrictMemoryModel()) { auto realCookie = computeCookie(); shallRemember = *cookie != realCookie; if (shallRemember) *cookie = realCookie; @@ -2455,7 +2459,7 @@ OBJ_GETTER(swapHeapRefLocked, } UpdateReturnRef(OBJ_RESULT, oldValue); - if (IsStrictMemoryModel && shallRemember && oldValue != nullptr && oldValue != expectedValue) { + if (IsStrictMemoryModel() && shallRemember && oldValue != nullptr && oldValue != expectedValue) { // Only remember container if it is not known to this thread (i.e. != expectedValue). rememberNewContainer(containerFor(oldValue)); } @@ -2491,7 +2495,7 @@ OBJ_GETTER(readHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t* if (shallRemember) *cookie = realCookie; UpdateReturnRef(OBJ_RESULT, value); #if USE_GC - if (IsStrictMemoryModel && shallRemember && value != nullptr) { + if (IsStrictMemoryModel() && shallRemember && value != nullptr) { auto* container = containerFor(value); rememberNewContainer(container); } @@ -2506,7 +2510,7 @@ OBJ_GETTER(readHeapRefNoLock, ObjHeader* object, KInt index) { reinterpret_cast(object) + object->type_info()->objOffsets_[index]); ObjHeader* value = *location; #if USE_GC - if (IsStrictMemoryModel && (value != nullptr)) { + if (IsStrictMemoryModel() && (value != nullptr)) { // Maybe not so good to do that under lock. rememberNewContainer(containerFor(value)); } @@ -3300,7 +3304,7 @@ bool IsForeignRefAccessible(ObjHeader* object, ForeignRefContext context) { void AdoptReferenceFromSharedVariable(ObjHeader* object) { #if USE_GC - if (IsStrictMemoryModel && object != nullptr && isShareable(containerFor(object))) + if (IsStrictMemoryModel() && object != nullptr && isShareable(containerFor(object))) rememberNewContainer(containerFor(object)); #endif // USE_GC } diff --git a/kotlin-native/runtime/src/main/cpp/KAssert.h b/kotlin-native/runtime/src/main/cpp/KAssert.h index c111c1783fa..aa8edac245b 100644 --- a/kotlin-native/runtime/src/main/cpp/KAssert.h +++ b/kotlin-native/runtime/src/main/cpp/KAssert.h @@ -27,6 +27,19 @@ RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* message); +namespace internal { + +inline RUNTIME_NORETURN void TODOImpl(const char* location) { + RuntimeAssertFailed(location, "Unimplemented"); +} + +// TODO: Support format string when `RuntimeAssertFailed` supports it. +inline RUNTIME_NORETURN void TODOImpl(const char* location, const char* message) { + RuntimeAssertFailed(location, message); +} + +} // namespace internal + // During codegeneration we set this constant to 1 or 0 to allow bitcode optimizer // to get rid of code behind condition. extern "C" const int KonanNeedDebugInfo; @@ -48,4 +61,9 @@ if (KonanNeedDebugInfo && (!(condition))) { \ RuntimeAssertFailed(nullptr, message); \ } +#define TODO(...) \ + do { \ + ::internal::TODOImpl(__FILE__ ":" TOSTRING(__LINE__), ##__VA_ARGS__); \ + } while (false) + #endif // RUNTIME_ASSERT_H diff --git a/kotlin-native/runtime/src/main/cpp/KAssertTest.cpp b/kotlin-native/runtime/src/main/cpp/KAssertTest.cpp new file mode 100644 index 00000000000..4460db8515a --- /dev/null +++ b/kotlin-native/runtime/src/main/cpp/KAssertTest.cpp @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +#include "KAssert.h" + +#include "gtest/gtest.h" + +TEST(TODODeathTest, EmptyTODO) { + EXPECT_DEATH({ + TODO(); + }, "KAssertTest.cpp:12: runtime assert: Unimplemented"); +} + +TEST(TODODeathTest, TODOWithMessage) { + EXPECT_DEATH({ + TODO("Nope"); + }, "KAssertTest.cpp:18: runtime assert: Nope"); +} diff --git a/kotlin-native/runtime/src/main/cpp/Memory.h b/kotlin-native/runtime/src/main/cpp/Memory.h index 82c58fde4b6..94b7a94b85d 100644 --- a/kotlin-native/runtime/src/main/cpp/Memory.h +++ b/kotlin-native/runtime/src/main/cpp/Memory.h @@ -173,8 +173,15 @@ void InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) // in intermediate frames when throwing // +// NOTE: Must match `MemoryModel` in `Platform.kt` +enum class MemoryModel { + kStrict = 0, + kRelaxed = 1, + kExperimental = 2, +}; + // Controls the current memory model, is compile-time constant. -extern const bool IsStrictMemoryModel; +extern const MemoryModel CurrentMemoryModel; // Sets stack location. void SetStackRef(ObjHeader** location, const ObjHeader* object) RUNTIME_NOTHROW; diff --git a/kotlin-native/runtime/src/main/cpp/Runtime.cpp b/kotlin-native/runtime/src/main/cpp/Runtime.cpp index faa29a629de..88ebcdf8e60 100644 --- a/kotlin-native/runtime/src/main/cpp/Runtime.cpp +++ b/kotlin-native/runtime/src/main/cpp/Runtime.cpp @@ -314,7 +314,7 @@ KInt Konan_Platform_getCpuArchitecture() { } KInt Konan_Platform_getMemoryModel() { - return IsStrictMemoryModel ? 0 : 1; + return static_cast(CurrentMemoryModel); } KBoolean Konan_Platform_isDebugBinary() { 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 6ca425e88fa..39da7b97961 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/Platform.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/Platform.kt @@ -36,9 +36,11 @@ public enum class CpuArchitecture(val bitness: Int) { /** * Memory model. */ +// NOTE: Must match `MemoryModel` in `Memory.h` public enum class MemoryModel { STRICT, - RELAXED + RELAXED, + EXPERIMENTAL, } /** diff --git a/kotlin-native/runtime/src/mm/cpp/Memory.cpp b/kotlin-native/runtime/src/mm/cpp/Memory.cpp index ba9ab725eeb..184736dc66d 100644 --- a/kotlin-native/runtime/src/mm/cpp/Memory.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Memory.cpp @@ -6,6 +6,8 @@ #include "Memory.h" #include "GlobalsRegistry.hpp" +#include "KAssert.h" +#include "Porting.h" #include "StableRefRegistry.hpp" #include "ThreadData.hpp" #include "ThreadRegistry.hpp" @@ -55,6 +57,11 @@ ALWAYS_INLINE mm::ThreadData* GetThreadData(MemoryState* state) { } // namespace +ALWAYS_INLINE bool isShareable(const ObjHeader* obj) { + // TODO: Remove when legacy MM is gone. + return true; +} + extern "C" MemoryState* InitMemory(bool firstRuntime) { return ToMemoryState(mm::ThreadRegistry::Instance().RegisterCurrentThread()); } @@ -63,21 +70,27 @@ extern "C" void DeinitMemory(MemoryState* state, bool destroyRuntime) { mm::ThreadRegistry::Instance().Unregister(FromMemoryState(state)); } +extern "C" void RestoreMemory(MemoryState*) { + // TODO: Remove when legacy MM is gone. +} + extern "C" OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); // TODO: This should only be called if singleton is actually created here. It's possible that the // singleton will be created on a different thread and here we should check that, instead of creating // another one (and registering `location` twice). mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(threadData, location); - RuntimeCheck(false, "Unimplemented"); + TODO(); } extern "C" RUNTIME_NOTHROW void InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(threadData, location); - RuntimeCheck(false, "Unimplemented"); + TODO(); } +extern "C" const MemoryModel CurrentMemoryModel = MemoryModel::kExperimental; + extern "C" RUNTIME_NOTHROW void AddTLSRecord(MemoryState* memory, void** key, int size) { GetThreadData(memory)->tls().AddRecord(key, size); } @@ -94,6 +107,31 @@ extern "C" RUNTIME_NOTHROW ObjHeader** LookupTLS(void** key, int index) { return mm::ThreadRegistry::Instance().CurrentThreadData()->tls().Lookup(key, index); } +extern "C" RUNTIME_NOTHROW void GC_RegisterWorker(void* worker) { + // TODO: Remove when legacy MM is gone. + // Nothing to do +} + +extern "C" RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) { + // TODO: Remove when legacy MM is gone. + // Nothing to do +} + +extern "C" RUNTIME_NOTHROW void GC_CollectorCallback(void* worker) { + // TODO: Remove when legacy MM is gone. + // Nothing to do +} + +extern "C" bool Kotlin_Any_isShareable(ObjHeader* thiz) { + // TODO: Remove when legacy MM is gone. + return true; +} + +extern "C" RUNTIME_NOTHROW bool ClearSubgraphReferences(ObjHeader* root, bool checked) { + // TODO: Remove when legacy MM is gone. + return true; +} + extern "C" RUNTIME_NOTHROW void* CreateStablePointer(ObjHeader* object) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); return mm::StableRefRegistry::Instance().RegisterStableRef(threadData, object); @@ -120,6 +158,14 @@ extern "C" RUNTIME_NOTHROW OBJ_GETTER(AdoptStablePointer, void* pointer) { return object; } +extern "C" RUNTIME_NOTHROW void CheckLifetimesConstraint(ObjHeader* obj, ObjHeader* pointee) { + if (!obj->local() && pointee != nullptr && pointee->local()) { + konan::consolePrintf("Attempt to store a stack object %p into a heap object %p\n", pointee, obj); + konan::consolePrintf("This is a compiler bug, please report it to https://kotl.in/issue\n"); + konan::abort(); + } +} + extern "C" ForeignRefContext InitForeignRef(ObjHeader* object) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); auto* node = mm::StableRefRegistry::Instance().RegisterStableRef(threadData, object); @@ -142,3 +188,8 @@ extern "C" void AdoptReferenceFromSharedVariable(ObjHeader* object) { // TODO: Remove when legacy MM is gone. // Nothing to do. } + +void CheckGlobalsAccessible() { + // TODO: Remove when legacy MM is gone. + // Always accessible +} diff --git a/kotlin-native/runtime/src/mm/cpp/Stubs.cpp b/kotlin-native/runtime/src/mm/cpp/Stubs.cpp index 5b67ff9f063..bc79217b2cd 100644 --- a/kotlin-native/runtime/src/mm/cpp/Stubs.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Stubs.cpp @@ -5,181 +5,145 @@ #include "Memory.h" +#include "KAssert.h" + ALWAYS_INLINE bool isFrozen(const ObjHeader* obj) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj) { - RuntimeCheck(false, "Unimplemented"); -} - -ALWAYS_INLINE bool isShareable(const ObjHeader* obj) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } ObjHeader** ObjHeader::GetWeakCounterLocation() { - RuntimeCheck(false, "Unimplemented"); + TODO(); } #ifdef KONAN_OBJC_INTEROP void* ObjHeader::GetAssociatedObject() { - RuntimeCheck(false, "Unimplemented"); + TODO(); } void** ObjHeader::GetAssociatedObjectLocation() { - RuntimeCheck(false, "Unimplemented"); + TODO(); } void ObjHeader::SetAssociatedObject(void* obj) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } #endif // KONAN_OBJC_INTEROP static MetaObjHeader* createMetaObject(TypeInfo** location) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } static void destroyMetaObject(TypeInfo** location) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } extern "C" { -void RestoreMemory(MemoryState*) { - // TODO: Remove this function when legacy MM is gone. -} - RUNTIME_NOTHROW OBJ_GETTER(AllocInstance, const TypeInfo* type_info) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, int32_t elements) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } -extern const bool IsStrictMemoryModel = true; - RUNTIME_NOTHROW void SetStackRef(ObjHeader** location, const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void SetHeapRef(ObjHeader** location, const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void ZeroHeapRef(ObjHeader** location) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void ZeroArrayRefs(ArrayHeader* array) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void ZeroStackRef(ObjHeader** location) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void UpdateHeapRef(ObjHeader** location, const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void UpdateHeapRefIfNull(ObjHeader** location, const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void UpdateReturnRef(ObjHeader** returnSlot, const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW OBJ_GETTER( SwapHeapRefLocked, ObjHeader** location, ObjHeader* expectedValue, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void SetHeapRefLocked(ObjHeader** location, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW OBJ_GETTER(ReadHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t* cookie) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void EnterFrame(ObjHeader** start, int parameters, int count) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) { - RuntimeCheck(false, "Unimplemented"); -} - -RUNTIME_NOTHROW bool ClearSubgraphReferences(ObjHeader* root, bool checked) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } void MutationCheck(ObjHeader* obj) { - RuntimeCheck(false, "Unimplemented"); -} - -RUNTIME_NOTHROW void CheckLifetimesConstraint(ObjHeader* obj, ObjHeader* pointee) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } void FreezeSubgraph(ObjHeader* obj) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } void EnsureNeverFrozen(ObjHeader* obj) { - RuntimeCheck(false, "Unimplemented"); -} - -RUNTIME_NOTHROW void GC_RegisterWorker(void* worker) { - RuntimeCheck(false, "Unimplemented"); -} - -RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) { - RuntimeCheck(false, "Unimplemented"); -} - -RUNTIME_NOTHROW void GC_CollectorCallback(void* worker) { - RuntimeCheck(false, "Unimplemented"); -} - -bool Kotlin_Any_isShareable(ObjHeader* thiz) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void PerformFullGC(MemoryState* memory) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } bool TryAddHeapRef(const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void ReleaseHeapRef(const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } RUNTIME_NOTHROW void ReleaseHeapRefNoCollect(const ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); + TODO(); } ForeignRefContext InitLocalForeignRef(ObjHeader* object) { - RuntimeCheck(false, "Unimplemented"); -} - -void CheckGlobalsAccessible() { - // Globals are always accessible. + TODO(); } } // extern "C" diff --git a/kotlin-native/runtime/src/relaxed/cpp/MemoryImpl.cpp b/kotlin-native/runtime/src/relaxed/cpp/MemoryImpl.cpp index 4bc24d38c6c..458d2177ae1 100644 --- a/kotlin-native/runtime/src/relaxed/cpp/MemoryImpl.cpp +++ b/kotlin-native/runtime/src/relaxed/cpp/MemoryImpl.cpp @@ -9,7 +9,7 @@ extern "C" { -const bool IsStrictMemoryModel = false; +const MemoryModel CurrentMemoryModel = MemoryModel::kRelaxed; OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) { RETURN_RESULT_OF(AllocInstanceRelaxed, typeInfo); diff --git a/kotlin-native/runtime/src/strict/cpp/MemoryImpl.cpp b/kotlin-native/runtime/src/strict/cpp/MemoryImpl.cpp index 413b802258d..8c0b65891d3 100644 --- a/kotlin-native/runtime/src/strict/cpp/MemoryImpl.cpp +++ b/kotlin-native/runtime/src/strict/cpp/MemoryImpl.cpp @@ -9,7 +9,7 @@ extern "C" { -const bool IsStrictMemoryModel = true; +const MemoryModel CurrentMemoryModel = MemoryModel::kStrict; OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) { RETURN_RESULT_OF(AllocInstanceStrict, typeInfo);