[K/N] Add cms related targets and compiler option

This commit is contained in:
Pavel Kunyavskiy
2021-11-23 11:55:06 +03:00
committed by Space
parent 03299023f1
commit df4b367296
8 changed files with 119 additions and 56 deletions
@@ -315,6 +315,10 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
assertGcSupported() assertGcSupported()
GC.SAME_THREAD_MARK_AND_SWEEP GC.SAME_THREAD_MARK_AND_SWEEP
} }
"cms" -> {
assertGcSupported()
GC.CONCURRENT_MARK_AND_SWEEP
}
else -> { else -> {
configuration.report(ERROR, "Unsupported GC ${arguments.gc}") configuration.report(ERROR, "Unsupported GC ${arguments.gc}")
GC.SAME_THREAD_MARK_AND_SWEEP GC.SAME_THREAD_MARK_AND_SWEEP
@@ -8,4 +8,5 @@ package org.jetbrains.kotlin.backend.konan
enum class GC { enum class GC {
NOOP, NOOP,
SAME_THREAD_MARK_AND_SWEEP, SAME_THREAD_MARK_AND_SWEEP,
CONCURRENT_MARK_AND_SWEEP
} }
@@ -235,6 +235,11 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
add("experimental_memory_manager_noop.bc") add("experimental_memory_manager_noop.bc")
add("noop_gc.bc") add("noop_gc.bc")
} }
GC.CONCURRENT_MARK_AND_SWEEP -> {
add("common_gc_cms.bc")
add("experimental_memory_manager_cms.bc")
add("concurrent_ms_gc.bc")
}
} }
} }
} }
+53
View File
@@ -60,9 +60,12 @@ bitcode {
"${target}LegacyMemoryManager", "${target}LegacyMemoryManager",
"${target}ExperimentalMemoryManagerNoop", "${target}ExperimentalMemoryManagerNoop",
"${target}ExperimentalMemoryManagerStms", "${target}ExperimentalMemoryManagerStms",
"${target}ExperimentalMemoryManagerCms",
"${target}CommonGcNoop", "${target}CommonGcNoop",
"${target}CommonGcStms", "${target}CommonGcStms",
"${target}CommonGcCms",
"${target}SameThreadMsGc", "${target}SameThreadMsGc",
"${target}ConcurrentMsGc",
"${target}NoopGc" "${target}NoopGc"
) )
includeRuntime() includeRuntime()
@@ -182,6 +185,11 @@ bitcode {
includeRuntime() includeRuntime()
} }
create("experimental_memory_manager_cms", file("src/mm")) {
headersDirs += files("src/gc/cms/cpp", "src/gc/common/cpp")
includeRuntime()
}
create("common_gc_noop", file("src/gc/common")) { create("common_gc_noop", file("src/gc/common")) {
headersDirs += files("src/gc/noop/cpp", "src/mm/cpp") headersDirs += files("src/gc/noop/cpp", "src/mm/cpp")
includeRuntime() includeRuntime()
@@ -192,6 +200,11 @@ bitcode {
includeRuntime() includeRuntime()
} }
create("common_gc_cms", file("src/gc/common")) {
headersDirs += files("src/gc/cms/cpp", "src/mm/cpp")
includeRuntime()
}
create("noop_gc", file("src/gc/noop")) { create("noop_gc", file("src/gc/noop")) {
headersDirs += files("src/gc/noop/cpp", "src/gc/common/cpp", "src/mm/cpp") headersDirs += files("src/gc/noop/cpp", "src/gc/common/cpp", "src/mm/cpp")
includeRuntime() includeRuntime()
@@ -201,6 +214,11 @@ bitcode {
headersDirs += files("src/gc/stms/cpp", "src/gc/common/cpp", "src/mm/cpp") headersDirs += files("src/gc/stms/cpp", "src/gc/common/cpp", "src/mm/cpp")
includeRuntime() includeRuntime()
} }
create("concurrent_ms_gc", file("src/gc/cms")) {
headersDirs += files("src/gc/cms/cpp", "src/gc/common/cpp", "src/mm/cpp")
includeRuntime()
}
} }
targetList.forEach { targetName -> targetList.forEach { targetName ->
@@ -272,6 +290,41 @@ targetList.forEach { targetName ->
includeRuntime() includeRuntime()
}) })
allTests.addAll(createTestTasks(
project,
targetName,
"${targetName}ExperimentalMMCmsMimallocRuntimeTests",
listOf(
"${targetName}Runtime",
"${targetName}ExperimentalMemoryManagerCms",
"${targetName}CommonGcCms",
"${targetName}ConcurrentMsGc",
"${targetName}Mimalloc",
"${targetName}OptAlloc",
"${targetName}Objc"
)
) {
headersDirs += files("src/gc/cms/cpp", "src/gc/common/cpp", "src/mm/cpp")
includeRuntime()
})
allTests.addAll(createTestTasks(
project,
targetName,
"${targetName}ExperimentalMMCmsStdAllocRuntimeTests",
listOf(
"${targetName}Runtime",
"${targetName}ExperimentalMemoryManagerCms",
"${targetName}CommonGcCms",
"${targetName}ConcurrentMsGc",
"${targetName}StdAlloc",
"${targetName}Objc"
)
) {
headersDirs += files("src/gc/cms/cpp", "src/gc/common/cpp", "src/mm/cpp")
includeRuntime()
})
allTests.addAll(createTestTasks( allTests.addAll(createTestTasks(
project, project,
targetName, targetName,
@@ -3,7 +3,7 @@
* that can be found in the LICENSE file. * that can be found in the LICENSE file.
*/ */
#include "SameThreadMarkAndSweep.hpp" #include "ConcurrentMarkAndSweep.hpp"
#include <cinttypes> #include <cinttypes>
@@ -24,55 +24,55 @@ namespace {
struct MarkTraits { struct MarkTraits {
static bool IsMarked(ObjHeader* object) noexcept { static bool IsMarked(ObjHeader* object) noexcept {
auto& objectData = mm::ObjectFactory<gc::SameThreadMarkAndSweep>::NodeRef::From(object).GCObjectData(); auto& objectData = mm::ObjectFactory<gc::ConcurrentMarkAndSweep>::NodeRef::From(object).GCObjectData();
return objectData.color() == gc::SameThreadMarkAndSweep::ObjectData::Color::kBlack; return objectData.color() == gc::ConcurrentMarkAndSweep::ObjectData::Color::kBlack;
} }
static bool TryMark(ObjHeader* object) noexcept { static bool TryMark(ObjHeader* object) noexcept {
auto& objectData = mm::ObjectFactory<gc::SameThreadMarkAndSweep>::NodeRef::From(object).GCObjectData(); auto& objectData = mm::ObjectFactory<gc::ConcurrentMarkAndSweep>::NodeRef::From(object).GCObjectData();
if (objectData.color() == gc::SameThreadMarkAndSweep::ObjectData::Color::kBlack) return false; if (objectData.color() == gc::ConcurrentMarkAndSweep::ObjectData::Color::kBlack) return false;
objectData.setColor(gc::SameThreadMarkAndSweep::ObjectData::Color::kBlack); objectData.setColor(gc::ConcurrentMarkAndSweep::ObjectData::Color::kBlack);
return true; return true;
}; };
}; };
struct SweepTraits { struct SweepTraits {
using ObjectFactory = mm::ObjectFactory<gc::SameThreadMarkAndSweep>; using ObjectFactory = mm::ObjectFactory<gc::ConcurrentMarkAndSweep>;
using ExtraObjectsFactory = mm::ExtraObjectDataFactory; using ExtraObjectsFactory = mm::ExtraObjectDataFactory;
static bool IsMarkedByExtraObject(mm::ExtraObjectData &object) noexcept { static bool IsMarkedByExtraObject(mm::ExtraObjectData &object) noexcept {
auto *baseObject = object.GetBaseObject(); auto *baseObject = object.GetBaseObject();
if (!baseObject->heap()) return true; if (!baseObject->heap()) return true;
auto& objectData = mm::ObjectFactory<gc::SameThreadMarkAndSweep>::NodeRef::From(baseObject).GCObjectData(); auto& objectData = mm::ObjectFactory<gc::ConcurrentMarkAndSweep>::NodeRef::From(baseObject).GCObjectData();
return objectData.color() == gc::SameThreadMarkAndSweep::ObjectData::Color::kBlack; return objectData.color() == gc::ConcurrentMarkAndSweep::ObjectData::Color::kBlack;
} }
static bool TryResetMark(ObjectFactory::NodeRef node) noexcept { static bool TryResetMark(ObjectFactory::NodeRef node) noexcept {
auto& objectData = node.GCObjectData(); auto& objectData = node.GCObjectData();
if (objectData.color() == gc::SameThreadMarkAndSweep::ObjectData::Color::kWhite) return false; if (objectData.color() == gc::ConcurrentMarkAndSweep::ObjectData::Color::kWhite) return false;
objectData.setColor(gc::SameThreadMarkAndSweep::ObjectData::Color::kWhite); objectData.setColor(gc::ConcurrentMarkAndSweep::ObjectData::Color::kWhite);
return true; return true;
} }
}; };
struct FinalizeTraits { struct FinalizeTraits {
using ObjectFactory = mm::ObjectFactory<gc::SameThreadMarkAndSweep>; using ObjectFactory = mm::ObjectFactory<gc::ConcurrentMarkAndSweep>;
}; };
// Global, because it's accessed on a hot path: avoid memory load from `this`. // Global, because it's accessed on a hot path: avoid memory load from `this`.
std::atomic<gc::SameThreadMarkAndSweep::SafepointFlag> gSafepointFlag = gc::SameThreadMarkAndSweep::SafepointFlag::kNone; std::atomic<gc::ConcurrentMarkAndSweep::SafepointFlag> gSafepointFlag = gc::ConcurrentMarkAndSweep::SafepointFlag::kNone;
} // namespace } // namespace
ALWAYS_INLINE void gc::SameThreadMarkAndSweep::ThreadData::SafePointFunctionPrologue() noexcept { ALWAYS_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointFunctionPrologue() noexcept {
SafePointRegular(GCSchedulerThreadData::kFunctionPrologueWeight); SafePointRegular(GCSchedulerThreadData::kFunctionPrologueWeight);
} }
ALWAYS_INLINE void gc::SameThreadMarkAndSweep::ThreadData::SafePointLoopBody() noexcept { ALWAYS_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointLoopBody() noexcept {
SafePointRegular(GCSchedulerThreadData::kLoopBodyWeight); SafePointRegular(GCSchedulerThreadData::kLoopBodyWeight);
} }
void gc::SameThreadMarkAndSweep::ThreadData::SafePointAllocation(size_t size) noexcept { void gc::ConcurrentMarkAndSweep::ThreadData::SafePointAllocation(size_t size) noexcept {
threadData_.gcScheduler().OnSafePointAllocation(size); threadData_.gcScheduler().OnSafePointAllocation(size);
SafepointFlag flag = gSafepointFlag.load(); SafepointFlag flag = gSafepointFlag.load();
if (flag != SafepointFlag::kNone) { if (flag != SafepointFlag::kNone) {
@@ -80,7 +80,7 @@ void gc::SameThreadMarkAndSweep::ThreadData::SafePointAllocation(size_t size) no
} }
} }
void gc::SameThreadMarkAndSweep::ThreadData::PerformFullGC() noexcept { void gc::ConcurrentMarkAndSweep::ThreadData::PerformFullGC() noexcept {
auto didGC = gc_.PerformFullGC(); auto didGC = gc_.PerformFullGC();
if (!didGC) { if (!didGC) {
@@ -89,12 +89,12 @@ void gc::SameThreadMarkAndSweep::ThreadData::PerformFullGC() noexcept {
} }
} }
void gc::SameThreadMarkAndSweep::ThreadData::OnOOM(size_t size) noexcept { void gc::ConcurrentMarkAndSweep::ThreadData::OnOOM(size_t size) noexcept {
RuntimeLogDebug({kTagGC}, "Attempt to GC on OOM at size=%zu", size); RuntimeLogDebug({kTagGC}, "Attempt to GC on OOM at size=%zu", size);
PerformFullGC(); PerformFullGC();
} }
ALWAYS_INLINE void gc::SameThreadMarkAndSweep::ThreadData::SafePointRegular(size_t weight) noexcept { ALWAYS_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointRegular(size_t weight) noexcept {
threadData_.gcScheduler().OnSafePointRegular(weight); threadData_.gcScheduler().OnSafePointRegular(weight);
SafepointFlag flag = gSafepointFlag.load(); SafepointFlag flag = gSafepointFlag.load();
if (flag != SafepointFlag::kNone) { if (flag != SafepointFlag::kNone) {
@@ -102,7 +102,7 @@ ALWAYS_INLINE void gc::SameThreadMarkAndSweep::ThreadData::SafePointRegular(size
} }
} }
NO_INLINE void gc::SameThreadMarkAndSweep::ThreadData::SafePointSlowPath(SafepointFlag flag) noexcept { NO_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointSlowPath(SafepointFlag flag) noexcept {
RuntimeAssert(flag != SafepointFlag::kNone, "Must've been handled by the caller"); RuntimeAssert(flag != SafepointFlag::kNone, "Must've been handled by the caller");
// No need to check for kNeedsSuspend, because `suspendIfRequested` checks for its own atomic. // No need to check for kNeedsSuspend, because `suspendIfRequested` checks for its own atomic.
threadData_.suspensionData().suspendIfRequested(); threadData_.suspensionData().suspendIfRequested();
@@ -112,14 +112,14 @@ NO_INLINE void gc::SameThreadMarkAndSweep::ThreadData::SafePointSlowPath(Safepoi
} }
} }
gc::SameThreadMarkAndSweep::SameThreadMarkAndSweep() noexcept { gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep() noexcept {
mm::GlobalData::Instance().gcScheduler().SetScheduleGC([]() { mm::GlobalData::Instance().gcScheduler().SetScheduleGC([]() {
RuntimeLogDebug({kTagGC}, "Scheduling GC by thread %d", konan::currentThreadId()); RuntimeLogDebug({kTagGC}, "Scheduling GC by thread %d", konan::currentThreadId());
gSafepointFlag = SafepointFlag::kNeedsGC; gSafepointFlag = SafepointFlag::kNeedsGC;
}); });
} }
bool gc::SameThreadMarkAndSweep::PerformFullGC() noexcept { bool gc::ConcurrentMarkAndSweep::PerformFullGC() noexcept {
RuntimeLogDebug({kTagGC}, "Attempt to suspend threads by thread %d", konan::currentThreadId()); RuntimeLogDebug({kTagGC}, "Attempt to suspend threads by thread %d", konan::currentThreadId());
auto timeStartUs = konan::getTimeMicros(); auto timeStartUs = konan::getTimeMicros();
bool didSuspend = mm::RequestThreadsSuspension(); bool didSuspend = mm::RequestThreadsSuspension();
@@ -132,7 +132,7 @@ bool gc::SameThreadMarkAndSweep::PerformFullGC() noexcept {
RuntimeLogDebug({kTagGC}, "Requested thread suspension by thread %d", konan::currentThreadId()); RuntimeLogDebug({kTagGC}, "Requested thread suspension by thread %d", konan::currentThreadId());
gSafepointFlag = SafepointFlag::kNeedsSuspend; gSafepointFlag = SafepointFlag::kNeedsSuspend;
mm::ObjectFactory<gc::SameThreadMarkAndSweep>::FinalizerQueue finalizerQueue; mm::ObjectFactory<gc::ConcurrentMarkAndSweep>::FinalizerQueue finalizerQueue;
{ {
// Switch state to native to simulate this thread being a GC thread. // Switch state to native to simulate this thread being a GC thread.
ThreadStateGuard guard(ThreadState::kNative); ThreadStateGuard guard(ThreadState::kNative);
@@ -22,7 +22,7 @@ class ThreadData;
namespace gc { namespace gc {
// Stop-the-world Mark-and-Sweep that runs on mutator threads. Can support targets that do not have threads. // Stop-the-world Mark-and-Sweep that runs on mutator threads. Can support targets that do not have threads.
class SameThreadMarkAndSweep : private Pinned { class ConcurrentMarkAndSweep : private Pinned {
public: public:
enum class SafepointFlag { enum class SafepointFlag {
kNone, kNone,
@@ -47,10 +47,10 @@ public:
class ThreadData : private Pinned { class ThreadData : private Pinned {
public: public:
using ObjectData = SameThreadMarkAndSweep::ObjectData; using ObjectData = ConcurrentMarkAndSweep::ObjectData;
using Allocator = AllocatorWithGC<AlignedAllocator, ThreadData>; using Allocator = AllocatorWithGC<AlignedAllocator, ThreadData>;
explicit ThreadData(SameThreadMarkAndSweep& gc, mm::ThreadData& threadData) noexcept : gc_(gc), threadData_(threadData) {} explicit ThreadData(ConcurrentMarkAndSweep& gc, mm::ThreadData& threadData) noexcept : gc_(gc), threadData_(threadData) {}
~ThreadData() = default; ~ThreadData() = default;
void SafePointFunctionPrologue() noexcept; void SafePointFunctionPrologue() noexcept;
@@ -68,14 +68,14 @@ public:
void SafePointRegular(size_t weight) noexcept; void SafePointRegular(size_t weight) noexcept;
void SafePointSlowPath(SafepointFlag flag) noexcept; void SafePointSlowPath(SafepointFlag flag) noexcept;
SameThreadMarkAndSweep& gc_; ConcurrentMarkAndSweep& gc_;
mm::ThreadData& threadData_; mm::ThreadData& threadData_;
}; };
using Allocator = ThreadData::Allocator; using Allocator = ThreadData::Allocator;
SameThreadMarkAndSweep() noexcept; ConcurrentMarkAndSweep() noexcept;
~SameThreadMarkAndSweep() = default; ~ConcurrentMarkAndSweep() = default;
private: private:
// Returns `true` if GC has happened, and `false` if not (because someone else has suspended the threads). // Returns `true` if GC has happened, and `false` if not (because someone else has suspended the threads).
@@ -3,7 +3,7 @@
* that can be found in the LICENSE file. * that can be found in the LICENSE file.
*/ */
#include "SameThreadMarkAndSweep.hpp" #include "ConcurrentMarkAndSweep.hpp"
#include <condition_variable> #include <condition_variable>
#include <future> #include <future>
@@ -23,7 +23,7 @@
using namespace kotlin; using namespace kotlin;
// These tests can only work if `GC` is `SameThreadMarkAndSweep`. // These tests can only work if `GC` is `ConcurrentMarkAndSweep`.
// TODO: Extracting GC into a separate module will help with this. // TODO: Extracting GC into a separate module will help with this.
namespace { namespace {
@@ -197,10 +197,10 @@ KStdVector<ObjHeader*> Alive(mm::ThreadData& threadData) {
return objects; return objects;
} }
using Color = gc::SameThreadMarkAndSweep::ObjectData::Color; using Color = gc::ConcurrentMarkAndSweep::ObjectData::Color;
Color GetColor(ObjHeader* objHeader) { Color GetColor(ObjHeader* objHeader) {
auto nodeRef = mm::ObjectFactory<gc::SameThreadMarkAndSweep>::NodeRef::From(objHeader); auto nodeRef = mm::ObjectFactory<gc::ConcurrentMarkAndSweep>::NodeRef::From(objHeader);
return nodeRef.GCObjectData().color(); return nodeRef.GCObjectData().color();
} }
@@ -214,7 +214,7 @@ WeakCounter& InstallWeakCounter(mm::ThreadData& threadData, ObjHeader* objHeader
return weakCounter; return weakCounter;
} }
class SameThreadMarkAndSweepTest : public testing::Test { class ConcurrentMarkAndSweepTest : public testing::Test {
public: public:
~ConcurrentMarkAndSweepTest() { ~ConcurrentMarkAndSweepTest() {
@@ -231,7 +231,7 @@ private:
} // namespace } // namespace
TEST_F(SameThreadMarkAndSweepTest, RootSet) { TEST_F(ConcurrentMarkAndSweepTest, RootSet) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
GlobalObjectHolder global1{threadData}; GlobalObjectHolder global1{threadData};
GlobalObjectArrayHolder global2{threadData}; GlobalObjectArrayHolder global2{threadData};
@@ -266,7 +266,7 @@ TEST_F(SameThreadMarkAndSweepTest, RootSet) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, InterconnectedRootSet) { TEST_F(ConcurrentMarkAndSweepTest, InterconnectedRootSet) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
GlobalObjectHolder global1{threadData}; GlobalObjectHolder global1{threadData};
GlobalObjectArrayHolder global2{threadData}; GlobalObjectArrayHolder global2{threadData};
@@ -312,7 +312,7 @@ TEST_F(SameThreadMarkAndSweepTest, InterconnectedRootSet) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, FreeObjects) { TEST_F(ConcurrentMarkAndSweepTest, FreeObjects) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
auto& object1 = AllocateObject(threadData); auto& object1 = AllocateObject(threadData);
auto& object2 = AllocateObject(threadData); auto& object2 = AllocateObject(threadData);
@@ -327,7 +327,7 @@ TEST_F(SameThreadMarkAndSweepTest, FreeObjects) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, FreeObjectsWithFinalizers) { TEST_F(ConcurrentMarkAndSweepTest, FreeObjectsWithFinalizers) {
RunInNewThread([this](mm::ThreadData& threadData) { RunInNewThread([this](mm::ThreadData& threadData) {
auto& object1 = AllocateObjectWithFinalizer(threadData); auto& object1 = AllocateObjectWithFinalizer(threadData);
auto& object2 = AllocateObjectWithFinalizer(threadData); auto& object2 = AllocateObjectWithFinalizer(threadData);
@@ -344,7 +344,7 @@ TEST_F(SameThreadMarkAndSweepTest, FreeObjectsWithFinalizers) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, FreeObjectWithFreeWeak) { TEST_F(ConcurrentMarkAndSweepTest, FreeObjectWithFreeWeak) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
auto& object1 = AllocateObject(threadData); auto& object1 = AllocateObject(threadData);
auto& weak1 = ([&threadData, &object1]() -> WeakCounter& { auto& weak1 = ([&threadData, &object1]() -> WeakCounter& {
@@ -363,7 +363,7 @@ TEST_F(SameThreadMarkAndSweepTest, FreeObjectWithFreeWeak) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, FreeObjectWithHoldedWeak) { TEST_F(ConcurrentMarkAndSweepTest, FreeObjectWithHoldedWeak) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
auto& object1 = AllocateObject(threadData); auto& object1 = AllocateObject(threadData);
StackObjectHolder stack{threadData}; StackObjectHolder stack{threadData};
@@ -382,7 +382,7 @@ TEST_F(SameThreadMarkAndSweepTest, FreeObjectWithHoldedWeak) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, ObjectReferencedFromRootSet) { TEST_F(ConcurrentMarkAndSweepTest, ObjectReferencedFromRootSet) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
GlobalObjectHolder global{threadData}; GlobalObjectHolder global{threadData};
StackObjectHolder stack{threadData}; StackObjectHolder stack{threadData};
@@ -422,7 +422,7 @@ TEST_F(SameThreadMarkAndSweepTest, ObjectReferencedFromRootSet) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, ObjectsWithCycles) { TEST_F(ConcurrentMarkAndSweepTest, ObjectsWithCycles) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
GlobalObjectHolder global{threadData}; GlobalObjectHolder global{threadData};
StackObjectHolder stack{threadData}; StackObjectHolder stack{threadData};
@@ -471,7 +471,7 @@ TEST_F(SameThreadMarkAndSweepTest, ObjectsWithCycles) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, ObjectsWithCyclesAndFinalizers) { TEST_F(ConcurrentMarkAndSweepTest, ObjectsWithCyclesAndFinalizers) {
RunInNewThread([this](mm::ThreadData& threadData) { RunInNewThread([this](mm::ThreadData& threadData) {
GlobalObjectHolder global{threadData}; GlobalObjectHolder global{threadData};
StackObjectHolder stack{threadData}; StackObjectHolder stack{threadData};
@@ -522,7 +522,7 @@ TEST_F(SameThreadMarkAndSweepTest, ObjectsWithCyclesAndFinalizers) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, ObjectsWithCyclesIntoRootSet) { TEST_F(ConcurrentMarkAndSweepTest, ObjectsWithCyclesIntoRootSet) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
GlobalObjectHolder global{threadData}; GlobalObjectHolder global{threadData};
StackObjectHolder stack{threadData}; StackObjectHolder stack{threadData};
@@ -550,7 +550,7 @@ TEST_F(SameThreadMarkAndSweepTest, ObjectsWithCyclesIntoRootSet) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, RunGCTwice) { TEST_F(ConcurrentMarkAndSweepTest, RunGCTwice) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
GlobalObjectHolder global{threadData}; GlobalObjectHolder global{threadData};
StackObjectHolder stack{threadData}; StackObjectHolder stack{threadData};
@@ -600,7 +600,7 @@ TEST_F(SameThreadMarkAndSweepTest, RunGCTwice) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, PermanentObjects) { TEST_F(ConcurrentMarkAndSweepTest, PermanentObjects) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
GlobalPermanentObjectHolder global1{threadData}; GlobalPermanentObjectHolder global1{threadData};
GlobalObjectHolder global2{threadData}; GlobalObjectHolder global2{threadData};
@@ -622,7 +622,7 @@ TEST_F(SameThreadMarkAndSweepTest, PermanentObjects) {
}); });
} }
TEST_F(SameThreadMarkAndSweepTest, SameObjectInRootSet) { TEST_F(ConcurrentMarkAndSweepTest, SameObjectInRootSet) {
RunInNewThread([](mm::ThreadData& threadData) { RunInNewThread([](mm::ThreadData& threadData) {
GlobalObjectHolder global{threadData}; GlobalObjectHolder global{threadData};
StackObjectHolder stack(*global); StackObjectHolder stack(*global);
@@ -746,7 +746,7 @@ private:
} // namespace } // namespace
TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsCollect) { TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsCollect) {
KStdVector<Mutator> mutators(kDefaultThreadCount); KStdVector<Mutator> mutators(kDefaultThreadCount);
KStdVector<ObjHeader*> globals(kDefaultThreadCount); KStdVector<ObjHeader*> globals(kDefaultThreadCount);
KStdVector<ObjHeader*> locals(kDefaultThreadCount); KStdVector<ObjHeader*> locals(kDefaultThreadCount);
@@ -802,7 +802,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsCollect) {
} }
} }
TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAllCollect) { TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAllCollect) {
KStdVector<Mutator> mutators(kDefaultThreadCount); KStdVector<Mutator> mutators(kDefaultThreadCount);
KStdVector<ObjHeader*> globals(kDefaultThreadCount); KStdVector<ObjHeader*> globals(kDefaultThreadCount);
KStdVector<ObjHeader*> locals(kDefaultThreadCount); KStdVector<ObjHeader*> locals(kDefaultThreadCount);
@@ -852,7 +852,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAllCollect) {
} }
} }
TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRequested) { TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRequested) {
KStdVector<Mutator> mutators(kDefaultThreadCount); KStdVector<Mutator> mutators(kDefaultThreadCount);
KStdVector<ObjHeader*> globals(kDefaultThreadCount); KStdVector<ObjHeader*> globals(kDefaultThreadCount);
KStdVector<ObjHeader*> locals(kDefaultThreadCount); KStdVector<ObjHeader*> locals(kDefaultThreadCount);
@@ -924,7 +924,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRe
} }
} }
TEST_F(SameThreadMarkAndSweepTest, CrossThreadReference) { TEST_F(ConcurrentMarkAndSweepTest, CrossThreadReference) {
KStdVector<Mutator> mutators(kDefaultThreadCount); KStdVector<Mutator> mutators(kDefaultThreadCount);
KStdVector<ObjHeader*> globals(kDefaultThreadCount); KStdVector<ObjHeader*> globals(kDefaultThreadCount);
KStdVector<ObjHeader*> locals(kDefaultThreadCount); KStdVector<ObjHeader*> locals(kDefaultThreadCount);
@@ -990,7 +990,7 @@ TEST_F(SameThreadMarkAndSweepTest, CrossThreadReference) {
} }
} }
TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsWeaks) { TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsWeaks) {
KStdVector<Mutator> mutators(kDefaultThreadCount); KStdVector<Mutator> mutators(kDefaultThreadCount);
ObjHeader* globalRoot = nullptr; ObjHeader* globalRoot = nullptr;
WeakCounter* weak = nullptr; WeakCounter* weak = nullptr;
@@ -1042,7 +1042,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsWeaks) {
} }
} }
TEST_F(SameThreadMarkAndSweepTest, NewThreadsWhileRequestingCollection) { TEST_F(ConcurrentMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
KStdVector<Mutator> mutators(kDefaultThreadCount); KStdVector<Mutator> mutators(kDefaultThreadCount);
KStdVector<ObjHeader*> globals(2 * kDefaultThreadCount); KStdVector<ObjHeader*> globals(2 * kDefaultThreadCount);
KStdVector<ObjHeader*> locals(2 * kDefaultThreadCount); KStdVector<ObjHeader*> locals(2 * kDefaultThreadCount);
@@ -1124,7 +1124,7 @@ TEST_F(SameThreadMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
} }
TEST_F(SameThreadMarkAndSweepTest, FreeObjectWithFreeWeakReversedOrder) { TEST_F(ConcurrentMarkAndSweepTest, FreeObjectWithFreeWeakReversedOrder) {
KStdVector<Mutator> mutators(2); KStdVector<Mutator> mutators(2);
std::atomic<test_support::Object<Payload>*> object1 = nullptr; std::atomic<test_support::Object<Payload>*> object1 = nullptr;
std::atomic<WeakCounter*> weak = nullptr; std::atomic<WeakCounter*> weak = nullptr;
+2 -2
View File
@@ -5,12 +5,12 @@
#pragma once #pragma once
#include "SameThreadMarkAndSweep.hpp" #include "ConcurrentMarkAndSweep.hpp"
namespace kotlin { namespace kotlin {
namespace gc { namespace gc {
using GC = kotlin::gc::SameThreadMarkAndSweep; using GC = kotlin::gc::ConcurrentMarkAndSweep;
inline constexpr bool kSupportsMultipleMutators = true; inline constexpr bool kSupportsMultipleMutators = true;