diff --git a/libpandabase/os/cpu_affinity.h b/libpandabase/os/cpu_affinity.h index 0c7b6f312a5094d966a72eafec548a93db9a77eb..b6d9062fbaec664f8d4271fa90a5cdc879b9c9e0 100644 --- a/libpandabase/os/cpu_affinity.h +++ b/libpandabase/os/cpu_affinity.h @@ -161,6 +161,8 @@ public: return best_and_middle_cpu_set_; } + PANDA_PUBLIC_API static void PringCurrentAffinity(); + /** * Get cpu affinity for current thread * @param tid thread id for getting @@ -176,6 +178,8 @@ public: */ PANDA_PUBLIC_API static bool GetCurrentThreadAffinity(CpuSet &cpuset); + + /** * Get string representation for cpu-set * @tparam StringType type of result string diff --git a/platforms/unix/libpandabase/cpu_affinity.cpp b/platforms/unix/libpandabase/cpu_affinity.cpp index 3c1abb9034dada976fdfd487fb866c9e1da8b356..62f5e4356ef2d654ad1a4142f0195bebbde0d60f 100644 --- a/platforms/unix/libpandabase/cpu_affinity.cpp +++ b/platforms/unix/libpandabase/cpu_affinity.cpp @@ -155,6 +155,13 @@ void CpuAffinityManager::Finalize() weak_cpu_set_.Clear(); } +void CpuAffinityManager::PringCurrentAffinity() +{ + os::CpuSet main_thread_affinity {}; + os::CpuAffinityManager::GetCurrentThreadAffinity(main_thread_affinity); + LOG(INFO, GC) << "Main thread current affinity " << os::CpuAffinityManager::CpuSetToString(main_thread_affinity); +} + /* static */ void CpuAffinityManager::LoadCpuFreq() { @@ -212,6 +219,9 @@ void CpuAffinityManager::LoadCpuFreq() ASSERT(!best_cpu_set_.IsEmpty()); ASSERT(!middle_cpu_set_.IsEmpty()); ASSERT(!weak_cpu_set_.IsEmpty()); + LOG(INFO, GC) << "LoadCpuFreq: \n best " << os::CpuAffinityManager::CpuSetToString(best_cpu_set_); + LOG(INFO, GC) << " middle " << os::CpuAffinityManager::CpuSetToString(middle_cpu_set_); + LOG(INFO, GC) << " weak " << os::CpuAffinityManager::CpuSetToString(weak_cpu_set_); CpuSet::Or(best_and_middle_cpu_set_, best_cpu_set_, middle_cpu_set_); ASSERT(!best_and_middle_cpu_set_.IsEmpty()); for (auto it : cpu) { @@ -246,6 +256,13 @@ bool CpuAffinityManager::SetAffinityForThread(int tid, const CpuSet &cpuset) LOG_IF(!success, DEBUG, COMMON) << "Couldn't set affinity with mask " << CpuSetToString(cpuset) << " for thread with tid = " << (tid != 0 ? tid : thread::GetCurrentThreadId()) << ", error: " << std::strerror(errno); + os::CpuSet local_set; + os::CpuAffinityManager::GetThreadAffinity(tid, local_set); + if (tid == 0) { + LOG(INFO, GC) << "Affinity: \n main thread = " << os::CpuAffinityManager::CpuSetToString(local_set); + } else { + LOG(INFO, GC) << " worker = " << os::CpuAffinityManager::CpuSetToString(local_set); + } return success; } diff --git a/platforms/windows/libpandabase/cpu_affinity.cpp b/platforms/windows/libpandabase/cpu_affinity.cpp index 59c218f8288032582c5237879b984e4bb0691078..f59b887343baf94dacbea2fbac5c35535d295b85 100644 --- a/platforms/windows/libpandabase/cpu_affinity.cpp +++ b/platforms/windows/libpandabase/cpu_affinity.cpp @@ -159,6 +159,8 @@ void CpuAffinityManager::Finalize() weak_cpu_set_.Clear(); } +void CpuAffinityManager::PringCurrentAffinity() {} + /* static */ void CpuAffinityManager::LoadCpuFreq() { diff --git a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp index e1bcc92c5a10fd2394d573ea469f4788cd019c31..c6d7e7cef35b174a1160400fe7f3e5526b1d42bf 100644 --- a/runtime/mem/gc/g1/g1-gc.cpp +++ b/runtime/mem/gc/g1/g1-gc.cpp @@ -14,6 +14,7 @@ */ #include "include/mem/panda_string.h" +#include "mem/gc/gc.h" #include "runtime/include/panda_vm.h" #include "runtime/mem/gc/card_table-inl.h" #include "runtime/mem/gc/dynamic/gc_marker_dynamic-inl.h" @@ -413,6 +414,7 @@ template template void G1GC::RegionCompactingImpl(PandaVector *moved_objects, Region *region) { + ScopedRegionCollectionInfo region_compacting_info(this, "RegionCompactingImpl", region, true, 0); auto object_allocator = this->GetG1ObjectAllocator(); size_t move_size = 0; size_t move_count = 0; @@ -532,6 +534,20 @@ void G1GC::WorkerTaskProcessing(GCWorkersTask *task, [[maybe_unu this->GetInternalAllocator()->Delete(objects_stack); break; } + case GCWorkersTaskTypes::TASK_CONCURRENT_MARK: { + const ReferenceCheckPredicateT &disable_ref_pred = []([[maybe_unused]] const ObjectHeader *obj) { + return false; + }; + auto objects_stack = task->GetMarkingStack(); + auto interrupt_checker = [this, &objects_stack]() { + return !objects_stack->Empty() && !interrupt_concurrent_flag_; + }; + this->MarkStackCond(&marker_, objects_stack, interrupt_checker, disable_ref_pred, + GC::EmptyReferenceProcessPredicate); + ASSERT(objects_stack->Empty()); + this->GetInternalAllocator()->Delete(objects_stack); + break; + } case GCWorkersTaskTypes::TASK_REGION_COMPACTING: { auto data = task->GetRegionData(); PandaVector *moved_objects = data->first; @@ -809,9 +825,12 @@ bool G1GC::HaveGarbageRegions() // Use GetTopGarbageRegions because it doesn't return current regions PandaVector regions = GetG1ObjectAllocator()->template GetTopGarbageRegions(1U); if (regions.empty()) { + LOG_INFO_GC << "HaveGarbageRegions, region vector is empty"; return false; } double garbage_rate = static_cast(regions[0]->GetGarbageBytes()) / regions[0]->Size(); + LOG_INFO_GC << "HaveGarbageRegions, garbage rate is " << garbage_rate << ", compare to options " + << region_garbage_rate_threshold_; return garbage_rate >= region_garbage_rate_threshold_; } @@ -1247,6 +1266,15 @@ void G1GC::FullMarking(panda::GCTask &task) template void G1GC::ConcurrentMarking(panda::GCTask &task) { + static bool concurrent_marking_interrupted = false; + if (concurrent_marking_interrupted) { + bool use_gc_workers = this->GetSettings()->ParallelMarkingEnabled(); + concurrent_marking_stack_.ChangeLimits(use_gc_workers ? this->GetSettings()->GCRootMarkingStackMaxSize() : 0, + use_gc_workers ? this->GetSettings()->GCWorkersMarkingStackMaxSize() : 0, + GCWorkersTaskTypes::TASK_CONCURRENT_MARK, + this->GetSettings()->GCMarkingStackNewTasksFrequency()); + } + GCScope scoped_func(__FUNCTION__, this, GCPhase::GC_PHASE_MARK); { PauseTimeGoalDelay(); // initial mark is always separate pause with pause-time-goal GC trigger @@ -1293,6 +1321,7 @@ void G1GC::ConcurrentMarking(panda::GCTask &task) CollectNonRegularObjects(task); } } else { + LOG_INFO_GC << "Concurrent collection has been interrupted"; concurrent_marking_stack_.Clear(); ClearSatb(); } @@ -1364,10 +1393,11 @@ void G1GC::ConcurrentMark(Marker *marker, GCMarkingStackType *ob const ReferenceCheckPredicateT &ref_pred, const MemRangeChecker &mem_range_checker) { - ConcurrentScope concurrent_scope(this); + ConcurrentScope concurrent_scope(this, true, false); GCScope scope(__FUNCTION__, this, GCPhase::GC_PHASE_MARK); this->MarkImpl(marker, objects_stack, visit_card_table_roots, pred, ref_pred, mem_range_checker); if (interrupt_concurrent_flag_) { + LOG_INFO_GC << "Interrupted during marking"; return; } CalcLiveBytesForMovableTenuredRegions(); @@ -1767,10 +1797,16 @@ MemRange G1GC::CacheRefsFromRemsets() // some cross region refs might be not processed return false; }; - for (auto region : collection_set_) { - region->GetRemSet()->Iterate(RemsetRegionPredicate, visitor); + { + ScopedTiming t1("Iterate over remset in collection set", *this->GetTiming()); + for (auto region : collection_set_) { + region->GetRemSet()->Iterate(RemsetRegionPredicate, visitor); + } + } + { + ScopedTiming t1("Cache refs from durty cards", *this->GetTiming()); + CacheRefsFromDirtyCards(visitor); } - CacheRefsFromDirtyCards(visitor); #ifndef NDEBUG unique_cards_initialized_ = true; #endif // NDEBUG @@ -1786,6 +1822,7 @@ void G1GC::CacheRefsFromDirtyCards(Visitor visitor) { auto card_table = this->GetCardTable(); constexpr size_t MEM_SIZE = DEFAULT_REGION_SIZE / RemSet<>::Bitmap::GetNumBits(); + LOG(INFO, GC) << "Dirty cards size " << dirty_cards_.size(); for (auto it = dirty_cards_.cbegin(); it != dirty_cards_.cend();) { auto range = card_table->GetMemoryRange(*it); auto addr = range.GetStartAddress(); diff --git a/runtime/mem/gc/g1/g1-gc.cpp.rej b/runtime/mem/gc/g1/g1-gc.cpp.rej new file mode 100644 index 0000000000000000000000000000000000000000..aab60acee9372742af4910de028b458c5ae11d25 --- /dev/null +++ b/runtime/mem/gc/g1/g1-gc.cpp.rej @@ -0,0 +1,14 @@ +diff a/runtime/mem/gc/g1/g1-gc.cpp b/runtime/mem/gc/g1/g1-gc.cpp (rejected hunks) +@@ -1274,9 +1296,12 @@ void G1GC::ConcurrentMarking(panda::GCTask &task) + ConcurrentScope concurrent_scope(this); + CollectNonRegularObjects(task); + } ++ concurrent_marking_interrupted = false; ++ concurrent_marking_stack_.ChangeLimits(); + } else { + concurrent_marking_stack_.Clear(); + ClearSatb(); ++ concurrent_marking_interrupted = true; + } + ASSERT(concurrent_marking_stack_.Empty()); + } diff --git a/runtime/mem/gc/g1/update_remset_thread.cpp b/runtime/mem/gc/g1/update_remset_thread.cpp index d3aea7d5f0192146f4255971445534a0034ccbfb..f71bd725dec46ad6ae4b6178405a636d7e1b5e8b 100644 --- a/runtime/mem/gc/g1/update_remset_thread.cpp +++ b/runtime/mem/gc/g1/update_remset_thread.cpp @@ -185,6 +185,7 @@ void UpdateRemsetThread::ThreadLoop() auto phase = gc_->GetGCPhase(); if (phase != GCPhase::GC_PHASE_IDLE) { // means GC is in progress now and we need to process more aggressively + thread_cond_var_.Wait(&loop_lock_); continue; } else if (processed_cards < min_concurrent_cards_to_process_) { // NOLINT(readability-else-after-return) Sleep(); diff --git a/runtime/mem/gc/g1/update_remset_thread.h b/runtime/mem/gc/g1/update_remset_thread.h index 748616000dfb9f1a459d1f1a0e6649fd25fbf9a1..540b7ab23c8e10efe2f0533b1dcdf2397111c2c3 100644 --- a/runtime/mem/gc/g1/update_remset_thread.h +++ b/runtime/mem/gc/g1/update_remset_thread.h @@ -158,7 +158,7 @@ private: void Sleep() { - static constexpr uint64_t SLEEP_MS = 1; + static constexpr uint64_t SLEEP_MS = 10; thread_cond_var_.TimedWait(&loop_lock_, SLEEP_MS); } diff --git a/runtime/mem/gc/gc.cpp b/runtime/mem/gc/gc.cpp index 6ddc986aa627740c6ee504c6f0bd15507d6435ce..1caafabb1e5815198cafd68e28690ce57b231bc1 100644 --- a/runtime/mem/gc/gc.cpp +++ b/runtime/mem/gc/gc.cpp @@ -195,6 +195,7 @@ void GC::SetupCpuAffinity() // secondly try to use best + middle CPUs mask if (!os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST) && !os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST | os::CpuPower::MIDDLE)) { + LOG(INFO, GC) << "SetAffinityForCurrentThread for the main thread failed"; affinity_before_gc_.Clear(); } // Some GCs don't use GC Workers @@ -211,7 +212,9 @@ void GC::SetupCpuAffinityAfterConcurrent() // Try to set GC Thread on best CPUs after concurrent if (!os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST)) { // If it failed for only best CPUs then try to use best + middle CPUs mask after concurrent - os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST | os::CpuPower::MIDDLE); + if (!os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST | os::CpuPower::MIDDLE)) { + LOG(INFO, GC) << "SetupCpuAffinityAfterConcurrent for the main thread failed"; + } } // Some GCs don't use GC Workers if (workers_pool_ != nullptr) { @@ -720,28 +723,33 @@ void GC::PrintDetailedLog() LOG(INFO, GC) << this->GetTiming()->Dump(); } -ConcurrentScope::ConcurrentScope(GC *gc, bool auto_start) +ConcurrentScope::ConcurrentScope(GC *gc, bool auto_start, bool slower_affinity) { + slower_affinity_ = slower_affinity; LOG(DEBUG, GC) << "Start ConcurrentScope"; gc_ = gc; if (auto_start) { - Start(); + Start(slower_affinity); } } ConcurrentScope::~ConcurrentScope() { LOG(DEBUG, GC) << "Stop ConcurrentScope"; - if (started_ && gc_->IsConcurrencyAllowed()) { + if (started_) { gc_->GetPandaVm()->GetRendezvous()->SafepointBegin(); + } + if (gc_->IsConcurrencyAllowed() && slower_affinity_) { gc_->SetupCpuAffinityAfterConcurrent(); } } -NO_THREAD_SAFETY_ANALYSIS void ConcurrentScope::Start() +NO_THREAD_SAFETY_ANALYSIS void ConcurrentScope::Start(bool slower_affinity) { - if (!started_ && gc_->IsConcurrencyAllowed()) { + if (gc_->IsConcurrencyAllowed() && slower_affinity) { gc_->SetupCpuAffinityBeforeConcurrent(); + } + if (!started_) { gc_->GetPandaVm()->GetRendezvous()->SafepointEnd(); started_ = true; } diff --git a/runtime/mem/gc/gc.h b/runtime/mem/gc/gc.h index ab88d1fc742494e9bde9511c80370b11cf0fe408..e6985796ec65058bf2caf1533b19075d5256f7b3 100644 --- a/runtime/mem/gc/gc.h +++ b/runtime/mem/gc/gc.h @@ -816,15 +816,16 @@ GC *CreateGC(GCType gc_type, ObjectAllocatorBase *object_allocator, const GCSett */ class ConcurrentScope final { public: - explicit ConcurrentScope(GC *gc, bool auto_start = true); + explicit ConcurrentScope(GC *gc, bool auto_start = true, bool slower_affinity = true); NO_COPY_SEMANTIC(ConcurrentScope); NO_MOVE_SEMANTIC(ConcurrentScope); ~ConcurrentScope(); - void Start(); + void Start(bool slower_affinity); private: GC *gc_; bool started_ = false; + bool slower_affinity_ = true; }; } // namespace panda::mem diff --git a/runtime/mem/gc/gc_adaptive_stack.cpp b/runtime/mem/gc/gc_adaptive_stack.cpp index 3378439b3b50557c276bedf43b43e4ef420aa898..021257bde02416813ba3a4c296823183f8c3cdd0 100644 --- a/runtime/mem/gc/gc_adaptive_stack.cpp +++ b/runtime/mem/gc/gc_adaptive_stack.cpp @@ -164,4 +164,13 @@ void GCAdaptiveStack::Clear() *stack_dst_ = PandaStack(); } +void GCAdaptiveStack::ChangeLimits(size_t stack_size_limit, size_t new_task_stack_size_limit, GCWorkersTaskTypes task, + uint64_t time_limit_for_new_task_creation) +{ + stack_size_limit_ = stack_size_limit; + new_task_stack_size_limit_ = new_task_stack_size_limit; + time_limit_for_new_task_creation_ = time_limit_for_new_task_creation; + task_type_ = task; +} + } // namespace panda::mem diff --git a/runtime/mem/gc/gc_adaptive_stack.h b/runtime/mem/gc/gc_adaptive_stack.h index d32333c5e3469fbcf79c71e8ce1e66f92ee17d1c..1a2fa41e1ee0e9522af917cf1b6dcf67572137c4 100644 --- a/runtime/mem/gc/gc_adaptive_stack.h +++ b/runtime/mem/gc/gc_adaptive_stack.h @@ -27,6 +27,7 @@ enum class GCWorkersTaskTypes { TASK_MARKING, TASK_REMARK, TASK_FULL_MARK, + TASK_CONCURRENT_MARK, TASK_REGION_COMPACTING, TASK_ROOT_COLLECTION, TASK_MOVE_YOUNG_ALIVE_OBJECTS, @@ -97,6 +98,13 @@ public: */ void Clear(); + /** + * \brief Change stack limits + */ + void ChangeLimits(size_t stack_size_limit = 0, size_t new_task_stack_size_limit = 0, + GCWorkersTaskTypes task = GCWorkersTaskTypes::TASK_EMPTY, + uint64_t time_limit_for_new_task_creation = 0); + private: static constexpr size_t DEFAULT_TASKS_FOR_TIME_CHECK = 10; diff --git a/runtime/mem/gc/gc_trigger.cpp b/runtime/mem/gc/gc_trigger.cpp index 502037cb1452384b892bb1cce6478704a9e95a8c..1a730804193185628041a15867e36b190cf809be 100644 --- a/runtime/mem/gc/gc_trigger.cpp +++ b/runtime/mem/gc/gc_trigger.cpp @@ -91,6 +91,7 @@ void GCTriggerHeap::ComputeNewTargetFootprint(const GCTask &task, size_t heap_si GC *gc = Thread::GetCurrent()->GetVM()->GetGC(); if (gc->IsGenerational() && task.reason == GCTaskCause::YOUNG_GC_CAUSE && task.collection_type != GCCollectionType::MIXED) { + LOG(DEBUG, GC) << "ComputeNewTargetFootprint: skip update"; // we don't want to update heap-trigger on young-gc return; } @@ -101,7 +102,7 @@ void GCTriggerHeap::ComputeNewTargetFootprint(const GCTask &task, size_t heap_si // constraints imposed on other reads or writes target_footprint_.store(target, std::memory_order_relaxed); - LOG(DEBUG, GC_TRIGGER) << "ComputeNewTargetFootprint target_footprint = " << target; + LOG(DEBUG, GC) << "ComputeNewTargetFootprint target_footprint = " << target; } size_t GCTriggerHeap::ComputeTarget(size_t heap_size_before_gc, size_t heap_size) diff --git a/runtime/mem/gc/gc_workers_thread_pool.cpp b/runtime/mem/gc/gc_workers_thread_pool.cpp index 460347fc580912b85743442e4bb893178064330f..4fa42a451d78a2bab2f0e00daf3656745d63487f 100644 --- a/runtime/mem/gc/gc_workers_thread_pool.cpp +++ b/runtime/mem/gc/gc_workers_thread_pool.cpp @@ -15,10 +15,10 @@ #include -#include "os/cpu_affinity.h" #include "runtime/mem/gc/gc.h" #include "runtime/mem/gc/gc_workers_thread_pool.h" #include "runtime/mem/region_space.h" +#include "libpandabase/os/cpu_affinity.h" namespace panda::mem { @@ -89,15 +89,29 @@ GCWorkersThreadPool::~GCWorkersThreadPool() void GCWorkersThreadPool::WaitUntilTasksEnd() { + uint64_t start_helping = time::GetCurrentTimeInNanos(); thread_pool_->Help(); + uint64_t start_waiting = time::GetCurrentTimeInNanos(); + LOG(INFO, GC) << time::GetCurrentTimeString() << "Finished processing task queue, helping consumes " + << Timing::PrettyTimeNs(start_waiting - start_helping); + os::CpuAffinityManager::PringCurrentAffinity(); + for (;;) { os::memory::LockHolder lock(cond_var_lock_); if (GetSolvedTasks() == GetSendedTasks()) { break; } - cond_var_.TimedWait(&cond_var_lock_, ALL_TASK_FINISH_WAIT_TIMEOUT); + LOG(INFO, GC) << time::GetCurrentTimeString() << "Check condition, unsuccessfull, time spent " + << Timing::PrettyTimeNs(time::GetCurrentTimeInNanos() - start_waiting); + os::CpuAffinityManager::PringCurrentAffinity(); + os::CpuAffinityManager::SetAffinityForCurrentThread(os::CpuPower::BEST); + cond_var_.TimedWait(&cond_var_lock_, 0, ALL_TASK_FINISH_WAIT_TIMEOUT, true); } ResetTasks(); + uint64_t end_waiting = time::GetCurrentTimeInNanos(); + LOG(INFO, GC) << time::GetCurrentTimeString() << "Waited for task end for " + << Timing::PrettyTimeNs(end_waiting - start_waiting); + os::CpuAffinityManager::PringCurrentAffinity(); } } // namespace panda::mem diff --git a/runtime/mem/gc/gc_workers_thread_pool.h b/runtime/mem/gc/gc_workers_thread_pool.h index b68ec76b49861f9fb48ff59ab2833df6b6f6981b..8be963652342d9f3cc2cbf8d05b84c35c4c5050a 100644 --- a/runtime/mem/gc/gc_workers_thread_pool.h +++ b/runtime/mem/gc/gc_workers_thread_pool.h @@ -105,7 +105,7 @@ public: explicit GCWorkersTask(GCWorkersTaskTypes type, StackType *marking_stack) : task_type_(type) { ASSERT(type == GCWorkersTaskTypes::TASK_MARKING || type == GCWorkersTaskTypes::TASK_REMARK || - type == GCWorkersTaskTypes::TASK_FULL_MARK); + type == GCWorkersTaskTypes::TASK_CONCURRENT_MARK || type == GCWorkersTaskTypes::TASK_FULL_MARK); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) storage_.marking_stack = marking_stack; } @@ -130,6 +130,7 @@ public: StackType *GetMarkingStack() const { ASSERT(task_type_ == GCWorkersTaskTypes::TASK_MARKING || task_type_ == GCWorkersTaskTypes::TASK_REMARK || + task_type_ == GCWorkersTaskTypes::TASK_CONCURRENT_MARK || task_type_ == GCWorkersTaskTypes::TASK_FULL_MARK); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) return storage_.marking_stack; @@ -287,6 +288,7 @@ public: solved_tasks_++; if (solved_tasks_ == sended_tasks_) { os::memory::LockHolder lock(cond_var_lock_); + LOG(INFO, GC) << time::GetCurrentTimeString() << "IncreaseSolvedTasks, notify waiters"; cond_var_.Signal(); } } diff --git a/runtime/mem/gc/gen-gc/gen-gc.cpp b/runtime/mem/gc/gen-gc/gen-gc.cpp index cdb4ab0c12c2e0c8b086c10be82dd72ea3d974e5..aa01c3ae039693d8ac3cdab209d60b70669e2783 100644 --- a/runtime/mem/gc/gen-gc/gen-gc.cpp +++ b/runtime/mem/gc/gen-gc/gen-gc.cpp @@ -612,7 +612,7 @@ NO_THREAD_SAFETY_ANALYSIS void GenGC::Sweep() }); // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon) if constexpr (CONCURRENT) { - concurrent_scope.Start(); // enable concurrent after GC_PHASE_SWEEP has been set + concurrent_scope.Start(true); // enable concurrent after GC_PHASE_SWEEP has been set } // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon) diff --git a/runtime/mem/gc/generational-gc-base-inl.h b/runtime/mem/gc/generational-gc-base-inl.h index e71e00f8682cd90c1d55f46dfbb401c55ac8d3ca..7828bf871b69c19a5de832a060111ea136ad4649 100644 --- a/runtime/mem/gc/generational-gc-base-inl.h +++ b/runtime/mem/gc/generational-gc-base-inl.h @@ -65,7 +65,11 @@ NO_THREAD_SAFETY_ANALYSIS void GenerationalGC::ConcurrentMark(Ma { GCScope scoped_func(__FUNCTION__, this, GCPhase::GC_PHASE_MARK); ConcurrentScope concurrent_scope(this); - MarkImpl(marker, objects_stack, visit_card_table_roots, pred, ref_pred, mem_range_checker); + MarkImpl(marker, objects_stack, visit_card_table_roots, pred, ref_pred, + mem_range_checker); // CODECHECK-NOLINT(C_RULE_ID_INDENT_CHECK) + if (this->GetSettings()->ParallelMarkingEnabled() && this->GetType() == GCType::G1_GC) { + this->GetWorkersPool()->WaitUntilTasksEnd(); + } } template diff --git a/runtime/thread_pool.h b/runtime/thread_pool.h index f32b0cfa028ccf4afba674fa2957b783bdcd6e71..59ebe0cd179342bd7c643642607d439e4a535698 100644 --- a/runtime/thread_pool.h +++ b/runtime/thread_pool.h @@ -271,7 +271,11 @@ public: } thread_pool->SignalTask(); LOG(DEBUG, RUNTIME) << "Worker " << i << " started to process task"; + uint64_t start = time::GetCurrentTimeInNanos(); + LOG(INFO, GC) << "Worker " << i << " started to process task"; proc->Process(std::move(task)); + uint64_t end = time::GetCurrentTimeInNanos(); + LOG(INFO, GC) << "Finished processing task Worker " << i << ", spent " << Timing::PrettyTimeNs(end - start); } if (!proc->Destroy()) { LOG(FATAL, RUNTIME) << "Cannot destroy worker thread";