[K/N] Reuse mark queue ^KT-51436
Merge-request: KT-MR-5819 Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
committed by
Space
parent
14dc20186d
commit
964edbaf91
@@ -85,6 +85,7 @@ gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep(
|
||||
objectFactory_(objectFactory),
|
||||
gcScheduler_(gcScheduler),
|
||||
finalizerProcessor_(make_unique<FinalizerProcessor>([this](int64_t epoch) { state_.finalized(epoch); })) {
|
||||
graySet_.reserve(1000);
|
||||
gcScheduler_.SetScheduleGC([this]() NO_INLINE {
|
||||
RuntimeLogDebug({kTagGC}, "Scheduling GC by thread %d", konan::currentThreadId());
|
||||
// This call acquires a lock, so we need to ensure that we're in the safe state.
|
||||
@@ -142,15 +143,15 @@ bool gc::ConcurrentMarkAndSweep::PerformFullGC(int64_t epoch) noexcept {
|
||||
state_.start(epoch);
|
||||
RuntimeLogInfo(
|
||||
{kTagGC}, "Started GC epoch %" PRId64 ". Time since last GC %" PRIu64 " microseconds", epoch, timeStartUs - lastGCTimestampUs_);
|
||||
auto graySet = collectRootSet();
|
||||
collectRootSet(graySet_);
|
||||
auto timeRootSetUs = konan::getTimeMicros();
|
||||
// Can be unsafe, because we've stopped the world.
|
||||
|
||||
auto objectsCountBefore = objectFactory_.GetSizeUnsafe();
|
||||
RuntimeLogInfo(
|
||||
{kTagGC}, "Collected root set of size %zu in %" PRIu64 " microseconds", graySet.size(),
|
||||
{kTagGC}, "Collected root set of size %zu in %" PRIu64 " microseconds", graySet_.size(),
|
||||
timeRootSetUs - timeSuspendUs);
|
||||
auto markStats = gc::Mark<MarkTraits>(std::move(graySet));
|
||||
auto markStats = gc::Mark<MarkTraits>(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);
|
||||
scheduler.gcData().UpdateAliveSetBytes(markStats.aliveHeapSetBytes);
|
||||
|
||||
@@ -88,6 +88,8 @@ private:
|
||||
GCStateHolder state_;
|
||||
ScopedThread gcThread_;
|
||||
KStdUniquePtr<FinalizerProcessor> finalizerProcessor_;
|
||||
|
||||
KStdVector<ObjHeader*> graySet_;
|
||||
};
|
||||
|
||||
} // namespace gc
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
KStdVector<ObjHeader*> kotlin::gc::collectRootSet() {
|
||||
KStdVector<ObjHeader*> graySet;
|
||||
void kotlin::gc::collectRootSet(KStdVector<ObjHeader*>& graySet) {
|
||||
graySet.clear();
|
||||
for (auto& thread : mm::GlobalData::Instance().threadRegistry().LockForIter()) {
|
||||
// TODO: Maybe it's more efficient to do by the suspending thread?
|
||||
thread.Publish();
|
||||
@@ -53,5 +53,4 @@ KStdVector<ObjHeader*> kotlin::gc::collectRootSet() {
|
||||
}
|
||||
}
|
||||
RuntimeLogDebug({kTagGC}, "Collected global root set global=%zu stableRef=%zu", global, stableRef);
|
||||
return graySet;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ struct MarkStats {
|
||||
|
||||
// TODO: Because of `graySet` this implementation may allocate heap memory during GC.
|
||||
template <typename Traits>
|
||||
MarkStats Mark(KStdVector<ObjHeader*> graySet) noexcept {
|
||||
MarkStats Mark(KStdVector<ObjHeader*>& graySet) noexcept {
|
||||
MarkStats stats;
|
||||
while (!graySet.empty()) {
|
||||
ObjHeader* top = graySet.back();
|
||||
@@ -111,7 +111,7 @@ typename Traits::ObjectFactory::FinalizerQueue Sweep(typename Traits::ObjectFact
|
||||
return Sweep<Traits>(iter);
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> collectRootSet();
|
||||
void collectRootSet(KStdVector<ObjHeader*>& graySet);
|
||||
|
||||
} // namespace gc
|
||||
} // namespace kotlin
|
||||
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
gc::MarkStats Mark(std::initializer_list<std::reference_wrapper<BaseObject>> graySet) {
|
||||
KStdVector<ObjHeader*> objects;
|
||||
for (auto& object : graySet) objects.push_back(object.get().GetObjHeader());
|
||||
return gc::Mark<ScopedMarkTraits>(std::move(objects));
|
||||
return gc::Mark<ScopedMarkTraits>(objects);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -104,6 +104,7 @@ NO_INLINE void gc::SameThreadMarkAndSweep::ThreadData::SafePointSlowPath(Safepoi
|
||||
gc::SameThreadMarkAndSweep::SameThreadMarkAndSweep(
|
||||
mm::ObjectFactory<SameThreadMarkAndSweep>& objectFactory, GCScheduler& gcScheduler) noexcept :
|
||||
objectFactory_(objectFactory), gcScheduler_(gcScheduler) {
|
||||
graySet_.reserve(1000);
|
||||
gcScheduler_.SetScheduleGC([]() {
|
||||
// TODO: CMS is also responsible for avoiding scheduling while GC hasn't started running.
|
||||
// Investigate, if it's possible to move this logic into the scheduler.
|
||||
@@ -142,15 +143,15 @@ bool gc::SameThreadMarkAndSweep::PerformFullGC() noexcept {
|
||||
|
||||
RuntimeLogInfo(
|
||||
{kTagGC}, "Started GC epoch %zu. Time since last GC %" PRIu64 " microseconds", epoch_, timeStartUs - lastGCTimestampUs_);
|
||||
auto graySet = collectRootSet();
|
||||
collectRootSet(graySet_);
|
||||
auto timeRootSetUs = konan::getTimeMicros();
|
||||
// Can be unsafe, because we've stopped the world.
|
||||
auto objectsCountBefore = objectFactory_.GetSizeUnsafe();
|
||||
|
||||
RuntimeLogInfo(
|
||||
{kTagGC}, "Collected root set of size %zu in %" PRIu64 " microseconds", graySet.size(),
|
||||
{kTagGC}, "Collected root set of size %zu in %" PRIu64 " microseconds", graySet_.size(),
|
||||
timeRootSetUs - timeSuspendUs);
|
||||
auto markStats = gc::Mark<MarkTraits>(std::move(graySet));
|
||||
auto markStats = gc::Mark<MarkTraits>(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);
|
||||
scheduler.gcData().UpdateAliveSetBytes(markStats.aliveHeapSetBytes);
|
||||
|
||||
@@ -85,6 +85,8 @@ private:
|
||||
|
||||
mm::ObjectFactory<SameThreadMarkAndSweep>& objectFactory_;
|
||||
GCScheduler& gcScheduler_;
|
||||
|
||||
KStdVector<ObjHeader*> graySet_;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
Reference in New Issue
Block a user