diff --git a/kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.cpp b/kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.cpp index 69e6f9c51bf..09867b9c56e 100644 --- a/kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.cpp +++ b/kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.cpp @@ -4,3 +4,54 @@ */ #include "MarkAndSweepUtils.hpp" +#include "CompilerConstants.hpp" +#include "GlobalData.hpp" +#include "Logging.hpp" +#include "Memory.h" +#include "RootSet.hpp" +#include "ThreadData.hpp" + +using namespace kotlin; + +KStdVector kotlin::gc::collectRootSet() { + KStdVector graySet; + for (auto& thread : mm::GlobalData::Instance().threadRegistry().LockForIter()) { + // TODO: Maybe it's more efficient to do by the suspending thread? + thread.Publish(); + thread.gcScheduler().OnStoppedForGC(); + size_t stack = 0; + size_t tls = 0; + for (auto value : mm::ThreadRootSet(thread)) { + if (!isNullOrMarker(value.object)) { + graySet.push_back(value.object); + switch (value.source) { + case mm::ThreadRootSet::Source::kStack: + ++stack; + break; + case mm::ThreadRootSet::Source::kTLS: + ++tls; + break; + } + } + } + RuntimeLogDebug({kTagGC}, "Collected root set for thread stack=%zu tls=%zu", stack, tls); + } + mm::StableRefRegistry::Instance().ProcessDeletions(); + size_t global = 0; + size_t stableRef = 0; + for (auto value : mm::GlobalRootSet()) { + if (!isNullOrMarker(value.object)) { + graySet.push_back(value.object); + switch (value.source) { + case mm::GlobalRootSet::Source::kGlobal: + ++global; + break; + case mm::GlobalRootSet::Source::kStableRef: + ++stableRef; + break; + } + } + } + RuntimeLogDebug({kTagGC}, "Collected global root set global=%zu stableRef=%zu", global, stableRef); + return graySet; +} diff --git a/kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.hpp b/kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.hpp index 803df164b16..cb80f6e34e9 100644 --- a/kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.hpp +++ b/kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.hpp @@ -105,6 +105,8 @@ typename Traits::ObjectFactory::FinalizerQueue Sweep(typename Traits::ObjectFact return finalizerQueue; } +KStdVector collectRootSet(); + } // namespace gc } // namespace kotlin diff --git a/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.cpp b/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.cpp index 2bac0374617..5546fad2a49 100644 --- a/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.cpp +++ b/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.cpp @@ -146,53 +146,14 @@ bool gc::SameThreadMarkAndSweep::PerformFullGC() noexcept { RuntimeLogInfo( {kTagGC}, "Started GC epoch %zu. Time since last GC %" PRIu64 " microseconds", epoch_, timeStartUs - lastGCTimestampUs_); - KStdVector graySet; - for (auto& thread : mm::GlobalData::Instance().threadRegistry().LockForIter()) { - // TODO: Maybe it's more efficient to do by the suspending thread? - thread.Publish(); - thread.gcScheduler().OnStoppedForGC(); - size_t stack = 0; - size_t tls = 0; - for (auto value : mm::ThreadRootSet(thread)) { - if (!isNullOrMarker(value.object)) { - graySet.push_back(value.object); - switch (value.source) { - case mm::ThreadRootSet::Source::kStack: - ++stack; - break; - case mm::ThreadRootSet::Source::kTLS: - ++tls; - break; - } - } - } - RuntimeLogDebug({kTagGC}, "Collected root set for thread stack=%zu tls=%zu", stack, tls); - } - mm::StableRefRegistry::Instance().ProcessDeletions(); - size_t global = 0; - size_t stableRef = 0; - for (auto value : mm::GlobalRootSet()) { - if (!isNullOrMarker(value.object)) { - graySet.push_back(value.object); - switch (value.source) { - case mm::GlobalRootSet::Source::kGlobal: - ++global; - break; - case mm::GlobalRootSet::Source::kStableRef: - ++stableRef; - break; - } - } - } + auto graySet = collectRootSet(); auto timeRootSetUs = konan::getTimeMicros(); - RuntimeLogDebug({kTagGC}, "Collected global root set global=%zu stableRef=%zu", global, stableRef); - // Can be unsafe, because we've stopped the world. auto objectsCountBefore = mm::GlobalData::Instance().objectFactory().GetSizeUnsafe(); RuntimeLogInfo( - {kTagGC}, "Collected root set of size %zu of which %zu are stable refs in %" PRIu64 " microseconds", graySet.size(), - stableRef, timeRootSetUs - timeSuspendUs); + {kTagGC}, "Collected root set of size %zu in %" PRIu64 " microseconds", graySet.size(), + timeRootSetUs - timeSuspendUs); auto markStats = gc::Mark(std::move(graySet)); auto timeMarkUs = konan::getTimeMicros(); RuntimeLogDebug({kTagGC}, "Marked %zu objects in %" PRIu64 " microseconds. Processed %zu duplicate entries in the gray set", markStats.aliveHeapSet, timeMarkUs - timeRootSetUs, markStats.duplicateEntries);