[K/N] Extract collecting root set to utils

This commit is contained in:
Pavel Kunyavskiy
2021-11-24 15:33:45 +03:00
committed by Space
parent 7373183e6f
commit dd2849b7e7
3 changed files with 56 additions and 42 deletions
@@ -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<ObjHeader*> kotlin::gc::collectRootSet() {
KStdVector<ObjHeader*> 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;
}
@@ -105,6 +105,8 @@ typename Traits::ObjectFactory::FinalizerQueue Sweep(typename Traits::ObjectFact
return finalizerQueue;
}
KStdVector<ObjHeader*> collectRootSet();
} // namespace gc
} // namespace kotlin
@@ -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<ObjHeader*> 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<MarkTraits>(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);