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 73b7ece16fa..54fba7661ec 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 @@ -1092,9 +1092,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, val ctor = codegen.llvmFunction(defaultConstructor) val initFunction = if (storageKind == ObjectStorageKind.SHARED && context.config.threadsAreAllowed) { - context.llvm.initSharedInstanceFunction + context.llvm.initSingletonFunction } else { - context.llvm.initInstanceFunction + context.llvm.initThreadLocalSingleton } val args = listOf(objectPtr, typeInfo, ctor) val newValue = call(initFunction, args, Lifetime.GLOBAL, exceptionHandler) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index 7489df0b056..05ecc700e61 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -499,8 +499,9 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { val allocInstanceFunction = importRtFunction("AllocInstance") val allocArrayFunction = importRtFunction("AllocArrayInstance") - val initInstanceFunction = importRtFunction("InitInstance") - val initSharedInstanceFunction = importRtFunction("InitSharedInstance") + val initThreadLocalSingleton = importRtFunction("InitThreadLocalSingleton") + val initSingletonFunction = importRtFunction("InitSingleton") + val initAndRegisterGlobalFunction = importRtFunction("InitAndRegisterGlobal") val updateHeapRefFunction = importRtFunction("UpdateHeapRef") val updateStackRefFunction = importRtFunction("UpdateStackRef") val updateReturnRefFunction = importRtFunction("UpdateReturnRef") 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 613f0c9fa08..6897fe8715f 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 @@ -412,15 +412,28 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map - if (irField.initializer?.expression !is IrConst<*>?) { - if (irField.storageKind != FieldStorageKind.THREAD_LOCAL) { + if (irField.storageKind != FieldStorageKind.THREAD_LOCAL) { + val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress( + functionGenerationContext + ) + val initialValue = if (irField.initializer?.expression !is IrConst<*>?) { val initialization = evaluateExpression(irField.initializer!!.expression) - val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress( - functionGenerationContext - ) if (irField.storageKind == FieldStorageKind.SHARED_FROZEN) freeze(initialization, currentCodeContext.exceptionHandler) - storeAny(initialization, address, false) + initialization + } else { + null + } + val needRegistration = + context.memoryModel == MemoryModel.EXPERIMENTAL && // only for the new MM + irField.type.binaryTypeIsReference() && // only for references + (initialValue != null || // which are initialized from heap object + !irField.isFinal) // or are not final + if (needRegistration) { + call(context.llvm.initAndRegisterGlobalFunction, listOf(address, initialValue + ?: kNullObjHeaderPtr)) + } else if (initialValue != null) { + storeAny(initialValue, address, false) } } } diff --git a/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp b/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp index 03bd85fdc84..c7b6c8d6a9d 100644 --- a/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp +++ b/kotlin-native/runtime/src/legacymm/cpp/Memory.cpp @@ -2320,7 +2320,7 @@ OBJ_GETTER(allocArrayInstance, const TypeInfo* type_info, int32_t elements) { } template -OBJ_GETTER(initInstance, +OBJ_GETTER(initThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { ObjHeader* value = *location; if (value != nullptr) { @@ -2345,8 +2345,7 @@ OBJ_GETTER(initInstance, } template -OBJ_GETTER(initSharedInstance, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { +OBJ_GETTER(initSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { #if KONAN_NO_THREADS ObjHeader* value = *location; if (value != nullptr) { @@ -3328,22 +3327,22 @@ OBJ_GETTER(AllocArrayInstanceRelaxed, const TypeInfo* typeInfo, int32_t elements RETURN_RESULT_OF(allocArrayInstance, typeInfo, elements); } -OBJ_GETTER(InitInstanceStrict, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RETURN_RESULT_OF(initInstance, location, typeInfo, ctor); +OBJ_GETTER(InitThreadLocalSingletonStrict, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { + RETURN_RESULT_OF(initThreadLocalSingleton, location, typeInfo, ctor); } -OBJ_GETTER(InitInstanceRelaxed, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RETURN_RESULT_OF(initInstance, location, typeInfo, ctor); +OBJ_GETTER(InitThreadLocalSingletonRelaxed, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { + RETURN_RESULT_OF(initThreadLocalSingleton, location, typeInfo, ctor); } -OBJ_GETTER(InitSharedInstanceStrict, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RETURN_RESULT_OF(initSharedInstance, location, typeInfo, ctor); +OBJ_GETTER(InitSingletonStrict, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { + RETURN_RESULT_OF(initSingleton, location, typeInfo, ctor); } -OBJ_GETTER(InitSharedInstanceRelaxed, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RETURN_RESULT_OF(initSharedInstance, location, typeInfo, ctor); +OBJ_GETTER(InitSingletonRelaxed, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { + RETURN_RESULT_OF(initSingleton, location, typeInfo, ctor); +} + +void RUNTIME_NOTHROW InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) { + RuntimeCheck(false, "Global registration is impossible in legacy MM"); } RUNTIME_NOTHROW void SetStackRefStrict(ObjHeader** location, const ObjHeader* object) { diff --git a/kotlin-native/runtime/src/legacymm/cpp/MemoryPrivate.hpp b/kotlin-native/runtime/src/legacymm/cpp/MemoryPrivate.hpp index 034bf339c55..01deeccecd0 100644 --- a/kotlin-native/runtime/src/legacymm/cpp/MemoryPrivate.hpp +++ b/kotlin-native/runtime/src/legacymm/cpp/MemoryPrivate.hpp @@ -309,15 +309,11 @@ OBJ_GETTER(AllocInstanceRelaxed, const TypeInfo* type_info) RUNTIME_NOTHROW; OBJ_GETTER(AllocArrayInstanceStrict, const TypeInfo* type_info, int32_t elements); OBJ_GETTER(AllocArrayInstanceRelaxed, const TypeInfo* type_info, int32_t elements); -OBJ_GETTER(InitInstanceStrict, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); -OBJ_GETTER(InitInstanceRelaxed, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); +OBJ_GETTER(InitThreadLocalSingletonStrict, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); +OBJ_GETTER(InitThreadLocalSingletonRelaxed, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); -OBJ_GETTER(InitSharedInstanceStrict, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); -OBJ_GETTER(InitSharedInstanceRelaxed, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); +OBJ_GETTER(InitSingletonStrict, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); +OBJ_GETTER(InitSingletonRelaxed, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); MODEL_VARIANTS(void, SetStackRef, ObjHeader** location, const ObjHeader* object); MODEL_VARIANTS(void, SetHeapRef, ObjHeader** location, const ObjHeader* object); diff --git a/kotlin-native/runtime/src/main/cpp/CompilerExport.cpp b/kotlin-native/runtime/src/main/cpp/CompilerExport.cpp index a9341926cc2..8f9ce315cc5 100644 --- a/kotlin-native/runtime/src/main/cpp/CompilerExport.cpp +++ b/kotlin-native/runtime/src/main/cpp/CompilerExport.cpp @@ -25,8 +25,9 @@ void ensureUsed(Ret (*f)(Args...)) { void EnsureDeclarationsEmitted() { ensureUsed(AllocInstance); ensureUsed(AllocArrayInstance); - ensureUsed(InitInstance); - ensureUsed(InitSharedInstance); + ensureUsed(InitThreadLocalSingleton); + ensureUsed(InitSingleton); + ensureUsed(InitAndRegisterGlobal); ensureUsed(UpdateHeapRef); ensureUsed(UpdateStackRef); ensureUsed(UpdateReturnRef); diff --git a/kotlin-native/runtime/src/main/cpp/Memory.h b/kotlin-native/runtime/src/main/cpp/Memory.h index 2e06eb9e030..82c58fde4b6 100644 --- a/kotlin-native/runtime/src/main/cpp/Memory.h +++ b/kotlin-native/runtime/src/main/cpp/Memory.h @@ -142,11 +142,14 @@ OBJ_GETTER(AllocInstance, const TypeInfo* type_info) RUNTIME_NOTHROW; OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, int32_t elements); -OBJ_GETTER(InitInstance, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); +OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); -OBJ_GETTER(InitSharedInstance, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); +OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); + +// `initialValue` may be `nullptr`, which signifies that the appropriate initial value was already +// set by static initialization. +// TODO: When global initialization becomes lazy, this signature won't do. +void InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) RUNTIME_NOTHROW; // // Object reference management. diff --git a/kotlin-native/runtime/src/main/cpp/MultiSourceQueue.hpp b/kotlin-native/runtime/src/main/cpp/MultiSourceQueue.hpp new file mode 100644 index 00000000000..cafcf355dee --- /dev/null +++ b/kotlin-native/runtime/src/main/cpp/MultiSourceQueue.hpp @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef RUNTIME_MULTI_SOURCE_QUEUE_H +#define RUNTIME_MULTI_SOURCE_QUEUE_H + +#include + +namespace kotlin { + +// A queue that is constructed by collecting subqueues from several `Producer`s. +template +class MultiSourceQueue { +public: + class Producer { + public: + void Insert(const T& value) noexcept { queue_.push_back(value); } + + private: + friend class MultiSourceQueue; + + std::list queue_; + }; + + using Iterator = typename std::list::iterator; + + Iterator begin() noexcept { return commonQueue_.begin(); } + Iterator end() noexcept { return commonQueue_.end(); } + + // Merge `producer`s queue with `this`. `producer` will have empty queue after the call. + // This call is performed without heap allocations. TODO: Test that no allocations are happening. + void Collect(Producer* producer) noexcept { commonQueue_.splice(commonQueue_.end(), producer->queue_); } + +private: + // Using `std::list` as it allows to implement `Collect` without memory allocations, + // which is important for GC mark phase. + std::list commonQueue_; +}; + +} // namespace kotlin + +#endif // RUNTIME_MULTI_SOURCE_QUEUE_H diff --git a/kotlin-native/runtime/src/main/cpp/MultiSourceQueueTest.cpp b/kotlin-native/runtime/src/main/cpp/MultiSourceQueueTest.cpp new file mode 100644 index 00000000000..e6622edc099 --- /dev/null +++ b/kotlin-native/runtime/src/main/cpp/MultiSourceQueueTest.cpp @@ -0,0 +1,89 @@ +/* + * 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 "MultiSourceQueue.hpp" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace kotlin; + +using IntQueue = MultiSourceQueue; + +TEST(MultiSourceQueueTest, Empty) { + IntQueue queue; + + std::vector actual; + for (int element : queue) { + actual.push_back(element); + } + + EXPECT_THAT(actual, testing::IsEmpty()); +} + +TEST(MultiSourceQueueTest, DoNotCollect) { + IntQueue queue; + IntQueue::Producer producer; + + producer.Insert(1); + producer.Insert(2); + + std::vector actual; + for (int element : queue) { + actual.push_back(element); + } + + EXPECT_THAT(actual, testing::IsEmpty()); +} + +TEST(MultiSourceQueueTest, Collect) { + IntQueue queue; + IntQueue::Producer producer1; + IntQueue::Producer producer2; + + producer1.Insert(1); + producer1.Insert(2); + producer2.Insert(10); + producer2.Insert(20); + + queue.Collect(&producer1); + queue.Collect(&producer2); + + std::vector actual; + for (int element : queue) { + actual.push_back(element); + } + + EXPECT_THAT(actual, testing::ElementsAre(1, 2, 10, 20)); +} + +TEST(MultiSourceQueueTest, CollectSeveralTimes) { + IntQueue queue; + IntQueue::Producer producer; + + // Add 2 elements and collect. + producer.Insert(1); + producer.Insert(2); + queue.Collect(&producer); + + // Add another element and collect. + producer.Insert(3); + queue.Collect(&producer); + + // Collect without adding elements. + queue.Collect(&producer); + + // Add yet another two elements and collect. + producer.Insert(4); + producer.Insert(5); + queue.Collect(&producer); + + std::vector actual; + for (int element : queue) { + actual.push_back(element); + } + + EXPECT_THAT(actual, testing::ElementsAre(1, 2, 3, 4, 5)); +} diff --git a/kotlin-native/runtime/src/mm/cpp/GlobalData.hpp b/kotlin-native/runtime/src/mm/cpp/GlobalData.hpp index a75f67ce962..e063b4e0865 100644 --- a/kotlin-native/runtime/src/mm/cpp/GlobalData.hpp +++ b/kotlin-native/runtime/src/mm/cpp/GlobalData.hpp @@ -6,6 +6,7 @@ #ifndef RUNTIME_MM_GLOBAL_DATA_H #define RUNTIME_MM_GLOBAL_DATA_H +#include "GlobalsRegistry.hpp" #include "ThreadRegistry.hpp" #include "Utils.hpp" @@ -18,6 +19,7 @@ public: static GlobalData& Instance() noexcept { return instance_; } ThreadRegistry& threadRegistry() { return threadRegistry_; } + GlobalsRegistry& globalsRegistry() { return globalsRegistry_; } private: GlobalData(); @@ -26,6 +28,7 @@ private: static GlobalData instance_; ThreadRegistry threadRegistry_; + GlobalsRegistry globalsRegistry_; }; } // namespace mm diff --git a/kotlin-native/runtime/src/mm/cpp/GlobalsRegistry.cpp b/kotlin-native/runtime/src/mm/cpp/GlobalsRegistry.cpp new file mode 100644 index 00000000000..96f80fd9ea4 --- /dev/null +++ b/kotlin-native/runtime/src/mm/cpp/GlobalsRegistry.cpp @@ -0,0 +1,30 @@ +/* + * 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 "GlobalsRegistry.hpp" + +#include + +#include "GlobalData.hpp" +#include "ThreadData.hpp" + +using namespace kotlin; + +// static +mm::GlobalsRegistry& mm::GlobalsRegistry::Instance() noexcept { + return GlobalData::Instance().globalsRegistry(); +} + +void mm::GlobalsRegistry::RegisterStorageForGlobal(mm::ThreadData* threadData, ObjHeader** location) noexcept { + threadData->globalsThreadQueue()->Insert(location); +} + +void mm::GlobalsRegistry::ProcessThread(mm::ThreadData* threadData) noexcept { + RuntimeAssert(threadData->isWaitingForGC(), "Thread must be waiting for GC to complete."); + globals_.Collect(threadData->globalsThreadQueue()); +} + +mm::GlobalsRegistry::GlobalsRegistry() = default; +mm::GlobalsRegistry::~GlobalsRegistry() = default; diff --git a/kotlin-native/runtime/src/mm/cpp/GlobalsRegistry.hpp b/kotlin-native/runtime/src/mm/cpp/GlobalsRegistry.hpp new file mode 100644 index 00000000000..5cb77c91128 --- /dev/null +++ b/kotlin-native/runtime/src/mm/cpp/GlobalsRegistry.hpp @@ -0,0 +1,50 @@ +/* + * 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. + */ + +#ifndef RUNTIME_MM_GLOBALS_REGISTRY_H +#define RUNTIME_MM_GLOBALS_REGISTRY_H + +#include "Memory.h" +#include "MultiSourceQueue.hpp" +#include "ThreadRegistry.hpp" +#include "Utils.hpp" + +namespace kotlin { +namespace mm { + +class GlobalsRegistry : Pinned { +public: + using ThreadQueue = MultiSourceQueue::Producer; + + using Iterator = std::list::iterator; + + static GlobalsRegistry& Instance() noexcept; + + void RegisterStorageForGlobal(mm::ThreadData* threadData, ObjHeader** location) noexcept; + + // Collect globals from thread corresponding to `threadData`. Thread must be waiting for GC. + // Only one thread can call this method. + void ProcessThread(mm::ThreadData* threadData) noexcept; + + // These must be called on the same thread as `ProcessThread` to avoid races. + // TODO: Iteration over `globals_` will be slow, because it's `std::list` collected at different times from + // different threads, and so the nodes are all over the memory. Use metrics to understand how + // much of a problem is it. + Iterator begin() noexcept { return globals_.begin(); } + Iterator end() noexcept { return globals_.end(); } + +private: + friend class GlobalData; + + GlobalsRegistry(); + ~GlobalsRegistry(); + + MultiSourceQueue globals_; +}; + +} // namespace mm +} // namespace kotlin + +#endif // RUNTIME_MM_GLOBALS_REGISTRY_H diff --git a/kotlin-native/runtime/src/mm/cpp/Memory.cpp b/kotlin-native/runtime/src/mm/cpp/Memory.cpp index dd192ee8404..849cf94f0f7 100644 --- a/kotlin-native/runtime/src/mm/cpp/Memory.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Memory.cpp @@ -5,6 +5,7 @@ #include "Memory.h" +#include "GlobalsRegistry.hpp" #include "ThreadData.hpp" #include "ThreadRegistry.hpp" #include "Utils.hpp" @@ -39,3 +40,18 @@ extern "C" MemoryState* InitMemory(bool firstRuntime) { extern "C" void DeinitMemory(MemoryState* state, bool destroyRuntime) { mm::ThreadRegistry::Instance().Unregister(FromMemoryState(state)); } + +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"); +} + +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"); +} diff --git a/kotlin-native/runtime/src/mm/cpp/Stubs.cpp b/kotlin-native/runtime/src/mm/cpp/Stubs.cpp index f43418f967f..8a3c8c499ef 100644 --- a/kotlin-native/runtime/src/mm/cpp/Stubs.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Stubs.cpp @@ -59,11 +59,7 @@ OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, int32_t elements) { RuntimeCheck(false, "Unimplemented"); } -OBJ_GETTER(InitInstance, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RuntimeCheck(false, "Unimplemented"); -} - -OBJ_GETTER(InitSharedInstance, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { +OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RuntimeCheck(false, "Unimplemented"); } diff --git a/kotlin-native/runtime/src/mm/cpp/ThreadData.hpp b/kotlin-native/runtime/src/mm/cpp/ThreadData.hpp index 3dac2cbd733..0b91cae9a06 100644 --- a/kotlin-native/runtime/src/mm/cpp/ThreadData.hpp +++ b/kotlin-native/runtime/src/mm/cpp/ThreadData.hpp @@ -8,6 +8,7 @@ #include +#include "GlobalsRegistry.hpp" #include "Utils.hpp" namespace kotlin { @@ -23,8 +24,16 @@ public: pthread_t threadId() const noexcept { return threadId_; } + bool isWaitingForGC() const noexcept { + // TODO: Implement. + return false; + } + + GlobalsRegistry::ThreadQueue* globalsThreadQueue() noexcept { return &globalsThreadQueue_; } + private: const pthread_t threadId_; + GlobalsRegistry::ThreadQueue globalsThreadQueue_; }; } // namespace mm diff --git a/kotlin-native/runtime/src/relaxed/cpp/MemoryImpl.cpp b/kotlin-native/runtime/src/relaxed/cpp/MemoryImpl.cpp index c0b0b074faf..4bc24d38c6c 100644 --- a/kotlin-native/runtime/src/relaxed/cpp/MemoryImpl.cpp +++ b/kotlin-native/runtime/src/relaxed/cpp/MemoryImpl.cpp @@ -19,14 +19,12 @@ OBJ_GETTER(AllocArrayInstance, const TypeInfo* typeInfo, int32_t elements) { RETURN_RESULT_OF(AllocArrayInstanceRelaxed, typeInfo, elements); } -OBJ_GETTER(InitInstance, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RETURN_RESULT_OF(InitInstanceRelaxed, location, typeInfo, ctor); +OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { + RETURN_RESULT_OF(InitThreadLocalSingletonRelaxed, location, typeInfo, ctor); } -OBJ_GETTER(InitSharedInstance, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RETURN_RESULT_OF(InitSharedInstanceRelaxed, location, typeInfo, ctor); +OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { + RETURN_RESULT_OF(InitSingletonRelaxed, location, typeInfo, ctor); } RUNTIME_NOTHROW void ReleaseHeapRef(const ObjHeader* object) { diff --git a/kotlin-native/runtime/src/strict/cpp/MemoryImpl.cpp b/kotlin-native/runtime/src/strict/cpp/MemoryImpl.cpp index 0b46ae9c20e..413b802258d 100644 --- a/kotlin-native/runtime/src/strict/cpp/MemoryImpl.cpp +++ b/kotlin-native/runtime/src/strict/cpp/MemoryImpl.cpp @@ -19,14 +19,12 @@ OBJ_GETTER(AllocArrayInstance, const TypeInfo* typeInfo, int32_t elements) { RETURN_RESULT_OF(AllocArrayInstanceStrict, typeInfo, elements); } -OBJ_GETTER(InitInstance, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RETURN_RESULT_OF(InitInstanceStrict, location, typeInfo, ctor); +OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { + RETURN_RESULT_OF(InitThreadLocalSingletonStrict, location, typeInfo, ctor); } -OBJ_GETTER(InitSharedInstance, - ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { - RETURN_RESULT_OF(InitSharedInstanceStrict, location, typeInfo, ctor); +OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { + RETURN_RESULT_OF(InitSingletonStrict, location, typeInfo, ctor); } RUNTIME_NOTHROW void ReleaseHeapRef(const ObjHeader* object) {