Commit 6f3aae99 authored by Michael Lippautz's avatar Michael Lippautz Committed by V8 LUCI CQ

cppgc: Move sweeper to regular tasks

- Use non-idle tasks to be able to process finalizers on time.
- Only process finalizers while concurrent marking is still running.

Bug: v8:13294
Change-Id: I1a2812c3fc350ea679c4c916c230cf736f2aa3ea
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3904648
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarAnton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83367}
parent d5a94229
...@@ -3105,6 +3105,7 @@ filegroup( ...@@ -3105,6 +3105,7 @@ filegroup(
"src/heap/cppgc/stats-collector.h", "src/heap/cppgc/stats-collector.h",
"src/heap/cppgc/sweeper.cc", "src/heap/cppgc/sweeper.cc",
"src/heap/cppgc/sweeper.h", "src/heap/cppgc/sweeper.h",
"src/heap/cppgc/heap-config.h",
"src/heap/cppgc/task-handle.h", "src/heap/cppgc/task-handle.h",
"src/heap/cppgc/trace-event.h", "src/heap/cppgc/trace-event.h",
"src/heap/cppgc/trace-trait.cc", "src/heap/cppgc/trace-trait.cc",
......
...@@ -5860,6 +5860,7 @@ v8_source_set("cppgc_base") { ...@@ -5860,6 +5860,7 @@ v8_source_set("cppgc_base") {
"src/heap/cppgc/globals.h", "src/heap/cppgc/globals.h",
"src/heap/cppgc/heap-base.cc", "src/heap/cppgc/heap-base.cc",
"src/heap/cppgc/heap-base.h", "src/heap/cppgc/heap-base.h",
"src/heap/cppgc/heap-config.h",
"src/heap/cppgc/heap-consistency.cc", "src/heap/cppgc/heap-consistency.cc",
"src/heap/cppgc/heap-growing.cc", "src/heap/cppgc/heap-growing.cc",
"src/heap/cppgc/heap-growing.h", "src/heap/cppgc/heap-growing.h",
......
...@@ -753,14 +753,14 @@ void CppHeap::TraceEpilogue() { ...@@ -753,14 +753,14 @@ void CppHeap::TraceEpilogue() {
{ {
cppgc::subtle::NoGarbageCollectionScope no_gc(*this); cppgc::subtle::NoGarbageCollectionScope no_gc(*this);
cppgc::internal::Sweeper::SweepingConfig::CompactableSpaceHandling cppgc::internal::SweepingConfig::CompactableSpaceHandling
compactable_space_handling = compactor_.CompactSpacesIfEnabled(); compactable_space_handling = compactor_.CompactSpacesIfEnabled();
const cppgc::internal::Sweeper::SweepingConfig sweeping_config{ const cppgc::internal::SweepingConfig sweeping_config{
SelectSweepingType(), compactable_space_handling, SelectSweepingType(), compactable_space_handling,
ShouldReduceMemory(current_gc_flags_) ShouldReduceMemory(current_gc_flags_)
? cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling:: ? cppgc::internal::SweepingConfig::FreeMemoryHandling::
kDiscardWherePossible kDiscardWherePossible
: cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling:: : cppgc::internal::SweepingConfig::FreeMemoryHandling::
kDoNotDiscard}; kDoNotDiscard};
DCHECK_IMPLIES(!isolate_, DCHECK_IMPLIES(!isolate_,
SweepingType::kAtomic == sweeping_config.sweeping_type); SweepingType::kAtomic == sweeping_config.sweeping_type);
...@@ -928,8 +928,8 @@ class CollectCustomSpaceStatisticsAtLastGCTask final : public v8::Task { ...@@ -928,8 +928,8 @@ class CollectCustomSpaceStatisticsAtLastGCTask final : public v8::Task {
void Run() final { void Run() final {
cppgc::internal::Sweeper& sweeper = heap_.sweeper(); cppgc::internal::Sweeper& sweeper = heap_.sweeper();
if (sweeper.PerformSweepOnMutatorThread( if (sweeper.PerformSweepOnMutatorThread(
heap_.platform()->MonotonicallyIncreasingTime() + kStepSizeMs,
kStepSizeMs.InSecondsF())) { cppgc::internal::StatsCollector::kSweepInTaskForStatistics)) {
// Sweeping is done. // Sweeping is done.
DCHECK(!sweeper.IsSweepingInProgress()); DCHECK(!sweeper.IsSweepingInProgress());
ReportCustomSpaceStatistics(heap_.raw_heap(), std::move(custom_spaces_), ReportCustomSpaceStatistics(heap_.raw_heap(), std::move(custom_spaces_),
......
...@@ -13,8 +13,7 @@ namespace cppgc { ...@@ -13,8 +13,7 @@ namespace cppgc {
namespace internal { namespace internal {
class V8_EXPORT_PRIVATE Compactor final { class V8_EXPORT_PRIVATE Compactor final {
using CompactableSpaceHandling = using CompactableSpaceHandling = SweepingConfig::CompactableSpaceHandling;
Sweeper::SweepingConfig::CompactableSpaceHandling;
public: public:
explicit Compactor(RawHeap&); explicit Compactor(RawHeap&);
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
#define V8_HEAP_CPPGC_GARBAGE_COLLECTOR_H_ #define V8_HEAP_CPPGC_GARBAGE_COLLECTOR_H_
#include "include/cppgc/common.h" #include "include/cppgc/common.h"
#include "src/heap/cppgc/heap-config.h"
#include "src/heap/cppgc/marker.h" #include "src/heap/cppgc/marker.h"
#include "src/heap/cppgc/sweeper.h"
namespace cppgc { namespace cppgc {
namespace internal { namespace internal {
...@@ -20,8 +20,8 @@ class GarbageCollector { ...@@ -20,8 +20,8 @@ class GarbageCollector {
using CollectionType = Marker::MarkingConfig::CollectionType; using CollectionType = Marker::MarkingConfig::CollectionType;
using StackState = cppgc::Heap::StackState; using StackState = cppgc::Heap::StackState;
using MarkingType = Marker::MarkingConfig::MarkingType; using MarkingType = Marker::MarkingConfig::MarkingType;
using SweepingType = Sweeper::SweepingConfig::SweepingType; using SweepingType = SweepingConfig::SweepingType;
using FreeMemoryHandling = Sweeper::SweepingConfig::FreeMemoryHandling; using FreeMemoryHandling = SweepingConfig::FreeMemoryHandling;
using IsForcedGC = Marker::MarkingConfig::IsForcedGC; using IsForcedGC = Marker::MarkingConfig::IsForcedGC;
static constexpr Config ConservativeAtomicConfig() { static constexpr Config ConservativeAtomicConfig() {
......
...@@ -259,9 +259,8 @@ void HeapBase::Terminate() { ...@@ -259,9 +259,8 @@ void HeapBase::Terminate() {
ExecutePreFinalizers(); ExecutePreFinalizers();
// TODO(chromium:1029379): Prefinalizers may black-allocate objects (under a // TODO(chromium:1029379): Prefinalizers may black-allocate objects (under a
// compile-time option). Run sweeping with forced finalization here. // compile-time option). Run sweeping with forced finalization here.
sweeper().Start( sweeper().Start({SweepingConfig::SweepingType::kAtomic,
{Sweeper::SweepingConfig::SweepingType::kAtomic, SweepingConfig::CompactableSpaceHandling::kSweep});
Sweeper::SweepingConfig::CompactableSpaceHandling::kSweep});
in_atomic_pause_ = false; in_atomic_pause_ = false;
sweeper().NotifyDoneIfNeeded(); sweeper().NotifyDoneIfNeeded();
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_CPPGC_HEAP_CONFIG_H_
#define V8_HEAP_CPPGC_HEAP_CONFIG_H_
#include "include/cppgc/heap.h"
namespace cppgc::internal {
struct SweepingConfig {
using SweepingType = cppgc::Heap::SweepingType;
enum class CompactableSpaceHandling { kSweep, kIgnore };
enum class FreeMemoryHandling { kDoNotDiscard, kDiscardWherePossible };
SweepingType sweeping_type = SweepingType::kIncrementalAndConcurrent;
CompactableSpaceHandling compactable_space_handling =
CompactableSpaceHandling::kSweep;
FreeMemoryHandling free_memory_handling = FreeMemoryHandling::kDoNotDiscard;
};
} // namespace cppgc::internal
#endif // V8_HEAP_CPPGC_HEAP_CONFIG_H_
...@@ -203,9 +203,8 @@ void Heap::FinalizeGarbageCollection(Config::StackState stack_state) { ...@@ -203,9 +203,8 @@ void Heap::FinalizeGarbageCollection(Config::StackState stack_state) {
#endif // defined(CPPGC_YOUNG_GENERATION) #endif // defined(CPPGC_YOUNG_GENERATION)
subtle::NoGarbageCollectionScope no_gc(*this); subtle::NoGarbageCollectionScope no_gc(*this);
const Sweeper::SweepingConfig sweeping_config{ const SweepingConfig sweeping_config{
config_.sweeping_type, config_.sweeping_type, SweepingConfig::CompactableSpaceHandling::kSweep,
Sweeper::SweepingConfig::CompactableSpaceHandling::kSweep,
config_.free_memory_handling}; config_.free_memory_handling};
sweeper_.Start(sweeping_config); sweeper_.Start(sweeping_config);
in_atomic_pause_ = false; in_atomic_pause_ = false;
......
...@@ -54,8 +54,8 @@ namespace internal { ...@@ -54,8 +54,8 @@ namespace internal {
V(MarkVisitRememberedSets) \ V(MarkVisitRememberedSets) \
V(SweepFinishIfOutOfWork) \ V(SweepFinishIfOutOfWork) \
V(SweepInvokePreFinalizers) \ V(SweepInvokePreFinalizers) \
V(SweepIdleStep) \
V(SweepInTask) \ V(SweepInTask) \
V(SweepInTaskForStatistics) \
V(SweepOnAllocation) \ V(SweepOnAllocation) \
V(SweepFinalize) V(SweepFinalize)
......
...@@ -26,13 +26,41 @@ ...@@ -26,13 +26,41 @@
#include "src/heap/cppgc/stats-collector.h" #include "src/heap/cppgc/stats-collector.h"
#include "src/heap/cppgc/task-handle.h" #include "src/heap/cppgc/task-handle.h"
namespace cppgc { namespace cppgc::internal {
namespace internal {
namespace { namespace {
class DeadlineChecker final {
public:
explicit DeadlineChecker(v8::base::TimeTicks end) : end_(end) {}
bool Check() {
return (++count_ % kInterval == 0) && (end_ < v8::base::TimeTicks::Now());
}
private:
static constexpr size_t kInterval = 4;
const v8::base::TimeTicks end_;
size_t count_ = 0;
};
using v8::base::Optional; using v8::base::Optional;
enum class MutatorThreadSweepingMode {
kOnlyFinalizers,
kAll,
};
constexpr const char* ToString(MutatorThreadSweepingMode sweeping_mode) {
switch (sweeping_mode) {
case MutatorThreadSweepingMode::kAll:
return "all";
case MutatorThreadSweepingMode::kOnlyFinalizers:
return "only-finalizers";
}
}
enum class StickyBits : uint8_t { enum class StickyBits : uint8_t {
kDisabled, kDisabled,
kEnabled, kEnabled,
...@@ -378,7 +406,7 @@ typename FinalizationBuilder::ResultType SweepNormalPage( ...@@ -378,7 +406,7 @@ typename FinalizationBuilder::ResultType SweepNormalPage(
// - returns (unmaps) empty pages; // - returns (unmaps) empty pages;
// - merges freelists to the space's freelist. // - merges freelists to the space's freelist.
class SweepFinalizer final { class SweepFinalizer final {
using FreeMemoryHandling = Sweeper::SweepingConfig::FreeMemoryHandling; using FreeMemoryHandling = SweepingConfig::FreeMemoryHandling;
public: public:
SweepFinalizer(cppgc::Platform* platform, SweepFinalizer(cppgc::Platform* platform,
...@@ -398,20 +426,13 @@ class SweepFinalizer final { ...@@ -398,20 +426,13 @@ class SweepFinalizer final {
} }
bool FinalizeSpaceWithDeadline(SpaceState* space_state, bool FinalizeSpaceWithDeadline(SpaceState* space_state,
double deadline_in_seconds) { v8::base::TimeTicks deadline) {
DCHECK(platform_); DCHECK(platform_);
static constexpr size_t kDeadlineCheckInterval = 4; DeadlineChecker deadline_check(deadline);
size_t page_count = 1;
while (auto page_state = space_state->swept_unfinalized_pages.Pop()) { while (auto page_state = space_state->swept_unfinalized_pages.Pop()) {
FinalizePage(&*page_state); FinalizePage(&*page_state);
if (page_count % kDeadlineCheckInterval == 0 && if (deadline_check.Check()) return false;
deadline_in_seconds <= platform_->MonotonicallyIncreasingTime()) {
return false;
}
page_count++;
} }
return true; return true;
...@@ -489,7 +510,7 @@ class SweepFinalizer final { ...@@ -489,7 +510,7 @@ class SweepFinalizer final {
class MutatorThreadSweeper final : private HeapVisitor<MutatorThreadSweeper> { class MutatorThreadSweeper final : private HeapVisitor<MutatorThreadSweeper> {
friend class HeapVisitor<MutatorThreadSweeper>; friend class HeapVisitor<MutatorThreadSweeper>;
using FreeMemoryHandling = Sweeper::SweepingConfig::FreeMemoryHandling; using FreeMemoryHandling = SweepingConfig::FreeMemoryHandling;
public: public:
MutatorThreadSweeper(HeapBase* heap, SpaceStates* states, MutatorThreadSweeper(HeapBase* heap, SpaceStates* states,
...@@ -512,25 +533,23 @@ class MutatorThreadSweeper final : private HeapVisitor<MutatorThreadSweeper> { ...@@ -512,25 +533,23 @@ class MutatorThreadSweeper final : private HeapVisitor<MutatorThreadSweeper> {
void SweepPage(BasePage& page) { Traverse(page); } void SweepPage(BasePage& page) { Traverse(page); }
bool SweepWithDeadline(double deadline_in_seconds) { bool SweepWithDeadline(v8::base::TimeDelta max_duration,
MutatorThreadSweepingMode sweeping_mode) {
DCHECK(platform_); DCHECK(platform_);
static constexpr double kSlackInSeconds = 0.001;
for (SpaceState& state : *states_) { for (SpaceState& state : *states_) {
// FinalizeSpaceWithDeadline() and SweepSpaceWithDeadline() won't check const auto deadline = v8::base::TimeTicks::Now() + max_duration;
// the deadline until it sweeps 10 pages. So we give a small slack for
// safety.
const double remaining_budget = deadline_in_seconds - kSlackInSeconds -
platform_->MonotonicallyIncreasingTime();
if (remaining_budget <= 0.) return false;
// First, prioritize finalization of pages that were swept concurrently. // First, prioritize finalization of pages that were swept concurrently.
SweepFinalizer finalizer(platform_, free_memory_handling_); SweepFinalizer finalizer(platform_, free_memory_handling_);
if (!finalizer.FinalizeSpaceWithDeadline(&state, deadline_in_seconds)) { if (!finalizer.FinalizeSpaceWithDeadline(&state, deadline)) {
return false; return false;
} }
if (sweeping_mode == MutatorThreadSweepingMode::kOnlyFinalizers)
return false;
// Help out the concurrent sweeper. // Help out the concurrent sweeper.
if (!SweepSpaceWithDeadline(&state, deadline_in_seconds)) { if (!SweepSpaceWithDeadline(&state, deadline)) {
return false; return false;
} }
} }
...@@ -542,16 +561,11 @@ class MutatorThreadSweeper final : private HeapVisitor<MutatorThreadSweeper> { ...@@ -542,16 +561,11 @@ class MutatorThreadSweeper final : private HeapVisitor<MutatorThreadSweeper> {
} }
private: private:
bool SweepSpaceWithDeadline(SpaceState* state, double deadline_in_seconds) { bool SweepSpaceWithDeadline(SpaceState* state, v8::base::TimeTicks deadline) {
static constexpr size_t kDeadlineCheckInterval = 4; DeadlineChecker deadline_check(deadline);
size_t page_count = 1;
while (auto page = state->unswept_pages.Pop()) { while (auto page = state->unswept_pages.Pop()) {
Traverse(**page); Traverse(**page);
if (page_count % kDeadlineCheckInterval == 0 && if (deadline_check.Check()) return false;
deadline_in_seconds <= platform_->MonotonicallyIncreasingTime()) {
return false;
}
page_count++;
} }
return true; return true;
...@@ -604,7 +618,7 @@ class ConcurrentSweepTask final : public cppgc::JobTask, ...@@ -604,7 +618,7 @@ class ConcurrentSweepTask final : public cppgc::JobTask,
private HeapVisitor<ConcurrentSweepTask> { private HeapVisitor<ConcurrentSweepTask> {
friend class HeapVisitor<ConcurrentSweepTask>; friend class HeapVisitor<ConcurrentSweepTask>;
using FreeMemoryHandling = Sweeper::SweepingConfig::FreeMemoryHandling; using FreeMemoryHandling = SweepingConfig::FreeMemoryHandling;
public: public:
ConcurrentSweepTask(HeapBase& heap, SpaceStates* states, Platform* platform, ConcurrentSweepTask(HeapBase& heap, SpaceStates* states, Platform* platform,
...@@ -694,8 +708,7 @@ class ConcurrentSweepTask final : public cppgc::JobTask, ...@@ -694,8 +708,7 @@ class ConcurrentSweepTask final : public cppgc::JobTask,
class PrepareForSweepVisitor final class PrepareForSweepVisitor final
: protected HeapVisitor<PrepareForSweepVisitor> { : protected HeapVisitor<PrepareForSweepVisitor> {
friend class HeapVisitor<PrepareForSweepVisitor>; friend class HeapVisitor<PrepareForSweepVisitor>;
using CompactableSpaceHandling = using CompactableSpaceHandling = SweepingConfig::CompactableSpaceHandling;
Sweeper::SweepingConfig::CompactableSpaceHandling;
public: public:
PrepareForSweepVisitor(SpaceStates* states, PrepareForSweepVisitor(SpaceStates* states,
...@@ -747,7 +760,7 @@ class PrepareForSweepVisitor final ...@@ -747,7 +760,7 @@ class PrepareForSweepVisitor final
} // namespace } // namespace
class Sweeper::SweeperImpl final { class Sweeper::SweeperImpl final {
using FreeMemoryHandling = Sweeper::SweepingConfig::FreeMemoryHandling; using FreeMemoryHandling = SweepingConfig::FreeMemoryHandling;
public: public:
SweeperImpl(RawHeap& heap, StatsCollector* stats_collector) SweeperImpl(RawHeap& heap, StatsCollector* stats_collector)
...@@ -810,20 +823,7 @@ class Sweeper::SweeperImpl final { ...@@ -810,20 +823,7 @@ class Sweeper::SweeperImpl final {
StatsCollector::EnabledScope inner_scope( StatsCollector::EnabledScope inner_scope(
stats_collector_, StatsCollector::kSweepOnAllocation); stats_collector_, StatsCollector::kSweepOnAllocation);
MutatorThreadSweepingScope sweeping_in_progress(*this); MutatorThreadSweepingScope sweeping_in_progress(*this);
DeadlineChecker deadline_check(v8::base::TimeTicks::Now() + max_duration);
const auto deadline = v8::base::TimeTicks::Now() + max_duration;
size_t page_count = 0;
const auto ShouldYield = [&page_count, deadline]() {
constexpr size_t kPageInterruptInterval = 10;
if (page_count++ == kPageInterruptInterval) {
if (deadline < v8::base::TimeTicks::Now()) {
return true;
}
page_count = 0;
}
return false;
};
{ {
// First, process unfinalized pages as finalizing a page is faster than // First, process unfinalized pages as finalizing a page is faster than
// sweeping. // sweeping.
...@@ -833,7 +833,7 @@ class Sweeper::SweeperImpl final { ...@@ -833,7 +833,7 @@ class Sweeper::SweeperImpl final {
if (size <= finalizer.largest_new_free_list_entry()) { if (size <= finalizer.largest_new_free_list_entry()) {
return true; return true;
} }
if (ShouldYield()) { if (deadline_check.Check()) {
return false; return false;
} }
} }
...@@ -848,7 +848,7 @@ class Sweeper::SweeperImpl final { ...@@ -848,7 +848,7 @@ class Sweeper::SweeperImpl final {
if (size <= sweeper.largest_new_free_list_entry()) { if (size <= sweeper.largest_new_free_list_entry()) {
return true; return true;
} }
if (ShouldYield()) { if (deadline_check.Check()) {
return false; return false;
} }
} }
...@@ -880,6 +880,12 @@ class Sweeper::SweeperImpl final { ...@@ -880,6 +880,12 @@ class Sweeper::SweeperImpl final {
return true; return true;
} }
bool IsConcurrentSweepingDone() const {
return !concurrent_sweeper_handle_ ||
(concurrent_sweeper_handle_->IsValid() &&
!concurrent_sweeper_handle_->IsActive());
}
void FinishIfOutOfWork() { void FinishIfOutOfWork() {
if (is_in_progress_ && !is_sweeping_on_mutator_thread_ && if (is_in_progress_ && !is_sweeping_on_mutator_thread_ &&
concurrent_sweeper_handle_ && concurrent_sweeper_handle_->IsValid() && concurrent_sweeper_handle_ && concurrent_sweeper_handle_->IsValid() &&
...@@ -899,10 +905,8 @@ class Sweeper::SweeperImpl final { ...@@ -899,10 +905,8 @@ class Sweeper::SweeperImpl final {
// deadline to see if sweeping can be fully finished. // deadline to see if sweeping can be fully finished.
MutatorThreadSweeper sweeper(heap_.heap(), &space_states_, platform_, MutatorThreadSweeper sweeper(heap_.heap(), &space_states_, platform_,
config_.free_memory_handling); config_.free_memory_handling);
const double deadline = if (sweeper.SweepWithDeadline(v8::base::TimeDelta::FromMilliseconds(2),
platform_->MonotonicallyIncreasingTime() + MutatorThreadSweepingMode::kAll)) {
v8::base::TimeDelta::FromMilliseconds(2).InSecondsF();
if (sweeper.SweepWithDeadline(deadline)) {
FinalizeSweep(); FinalizeSweep();
} }
} }
...@@ -960,8 +964,9 @@ class Sweeper::SweeperImpl final { ...@@ -960,8 +964,9 @@ class Sweeper::SweeperImpl final {
bool IsSweepingInProgress() const { return is_in_progress_; } bool IsSweepingInProgress() const { return is_in_progress_; }
bool PerformSweepOnMutatorThread(double deadline_in_seconds, bool PerformSweepOnMutatorThread(v8::base::TimeDelta max_duration,
StatsCollector::ScopeId internal_scope_id) { StatsCollector::ScopeId internal_scope_id,
MutatorThreadSweepingMode sweeping_mode) {
if (!is_in_progress_) return true; if (!is_in_progress_) return true;
MutatorThreadSweepingScope sweeping_in_progress(*this); MutatorThreadSweepingScope sweeping_in_progress(*this);
...@@ -975,10 +980,10 @@ class Sweeper::SweeperImpl final { ...@@ -975,10 +980,10 @@ class Sweeper::SweeperImpl final {
config_.free_memory_handling); config_.free_memory_handling);
{ {
StatsCollector::EnabledScope inner_stats_scope( StatsCollector::EnabledScope inner_stats_scope(
stats_collector_, internal_scope_id, "deltaInSeconds", stats_collector_, internal_scope_id, "max_duration_ms",
deadline_in_seconds - platform_->MonotonicallyIncreasingTime()); max_duration.InMillisecondsF(), "sweeping_mode",
ToString(sweeping_mode));
sweep_complete = sweeper.SweepWithDeadline(deadline_in_seconds); sweep_complete = sweeper.SweepWithDeadline(max_duration, sweeping_mode);
} }
if (sweep_complete) { if (sweep_complete) {
FinalizeSweep(); FinalizeSweep();
...@@ -1008,33 +1013,37 @@ class Sweeper::SweeperImpl final { ...@@ -1008,33 +1013,37 @@ class Sweeper::SweeperImpl final {
SweeperImpl& sweeper_; SweeperImpl& sweeper_;
}; };
class IncrementalSweepTask : public cppgc::IdleTask { class IncrementalSweepTask final : public cppgc::Task {
public: public:
using Handle = SingleThreadedHandle; using Handle = SingleThreadedHandle;
explicit IncrementalSweepTask(SweeperImpl* sweeper) explicit IncrementalSweepTask(SweeperImpl& sweeper)
: sweeper_(sweeper), handle_(Handle::NonEmptyTag{}) {} : sweeper_(sweeper), handle_(Handle::NonEmptyTag{}) {}
static Handle Post(SweeperImpl* sweeper, cppgc::TaskRunner* runner) { static Handle Post(SweeperImpl& sweeper, cppgc::TaskRunner* runner) {
auto task = std::make_unique<IncrementalSweepTask>(sweeper); auto task = std::make_unique<IncrementalSweepTask>(sweeper);
auto handle = task->GetHandle(); auto handle = task->GetHandle();
runner->PostIdleTask(std::move(task)); runner->PostTask(std::move(task));
return handle; return handle;
} }
private: private:
void Run(double deadline_in_seconds) override { void Run() override {
if (handle_.IsCanceled()) return; if (handle_.IsCanceled()) return;
if (!sweeper_->PerformSweepOnMutatorThread( if (!sweeper_.PerformSweepOnMutatorThread(
deadline_in_seconds, StatsCollector::kSweepIdleStep)) { v8::base::TimeDelta::FromMilliseconds(5),
sweeper_->ScheduleIncrementalSweeping(); StatsCollector::kSweepInTask,
sweeper_.IsConcurrentSweepingDone()
? MutatorThreadSweepingMode::kAll
: MutatorThreadSweepingMode::kOnlyFinalizers)) {
sweeper_.ScheduleIncrementalSweeping();
} }
} }
Handle GetHandle() const { return handle_; } Handle GetHandle() const { return handle_; }
SweeperImpl* sweeper_; SweeperImpl& sweeper_;
// TODO(chromium:1056170): Change to CancelableTask. // TODO(chromium:1056170): Change to CancelableTask.
Handle handle_; Handle handle_;
}; };
...@@ -1042,10 +1051,10 @@ class Sweeper::SweeperImpl final { ...@@ -1042,10 +1051,10 @@ class Sweeper::SweeperImpl final {
void ScheduleIncrementalSweeping() { void ScheduleIncrementalSweeping() {
DCHECK(platform_); DCHECK(platform_);
auto runner = platform_->GetForegroundTaskRunner(); auto runner = platform_->GetForegroundTaskRunner();
if (!runner || !runner->IdleTasksEnabled()) return; if (!runner) return;
incremental_sweeper_handle_ = incremental_sweeper_handle_ =
IncrementalSweepTask::Post(this, runner.get()); IncrementalSweepTask::Post(*this, runner.get());
} }
void ScheduleConcurrentSweeping() { void ScheduleConcurrentSweeping() {
...@@ -1119,10 +1128,10 @@ bool Sweeper::IsSweepingInProgress() const { ...@@ -1119,10 +1128,10 @@ bool Sweeper::IsSweepingInProgress() const {
return impl_->IsSweepingInProgress(); return impl_->IsSweepingInProgress();
} }
bool Sweeper::PerformSweepOnMutatorThread(double deadline_in_seconds) { bool Sweeper::PerformSweepOnMutatorThread(v8::base::TimeDelta max_duration,
return impl_->PerformSweepOnMutatorThread(deadline_in_seconds, StatsCollector::ScopeId scope_id) {
StatsCollector::kSweepInTask); return impl_->PerformSweepOnMutatorThread(max_duration, scope_id,
MutatorThreadSweepingMode::kAll);
} }
} // namespace internal } // namespace cppgc::internal
} // namespace cppgc
...@@ -7,16 +7,13 @@ ...@@ -7,16 +7,13 @@
#include <memory> #include <memory>
#include "include/cppgc/heap.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/heap/cppgc/heap-config.h"
#include "src/heap/cppgc/memory.h" #include "src/heap/cppgc/memory.h"
#include "src/heap/cppgc/stats-collector.h"
namespace cppgc { namespace cppgc::internal {
class Platform;
namespace internal {
class HeapBase; class HeapBase;
class ConcurrentSweeperTest; class ConcurrentSweeperTest;
...@@ -24,17 +21,6 @@ class NormalPageSpace; ...@@ -24,17 +21,6 @@ class NormalPageSpace;
class V8_EXPORT_PRIVATE Sweeper final { class V8_EXPORT_PRIVATE Sweeper final {
public: public:
struct SweepingConfig {
using SweepingType = cppgc::Heap::SweepingType;
enum class CompactableSpaceHandling { kSweep, kIgnore };
enum class FreeMemoryHandling { kDoNotDiscard, kDiscardWherePossible };
SweepingType sweeping_type = SweepingType::kIncrementalAndConcurrent;
CompactableSpaceHandling compactable_space_handling =
CompactableSpaceHandling::kSweep;
FreeMemoryHandling free_memory_handling = FreeMemoryHandling::kDoNotDiscard;
};
static constexpr bool CanDiscardMemory() { static constexpr bool CanDiscardMemory() {
return CheckMemoryIsInaccessibleIsNoop(); return CheckMemoryIsInaccessibleIsNoop();
} }
...@@ -63,7 +49,8 @@ class V8_EXPORT_PRIVATE Sweeper final { ...@@ -63,7 +49,8 @@ class V8_EXPORT_PRIVATE Sweeper final {
bool IsSweepingInProgress() const; bool IsSweepingInProgress() const;
// Assist with sweeping. Returns true if sweeping is done. // Assist with sweeping. Returns true if sweeping is done.
bool PerformSweepOnMutatorThread(double deadline_in_seconds); bool PerformSweepOnMutatorThread(v8::base::TimeDelta max_duration,
StatsCollector::ScopeId);
private: private:
void WaitForConcurrentSweepingForTesting(); void WaitForConcurrentSweepingForTesting();
...@@ -76,7 +63,6 @@ class V8_EXPORT_PRIVATE Sweeper final { ...@@ -76,7 +63,6 @@ class V8_EXPORT_PRIVATE Sweeper final {
friend class ConcurrentSweeperTest; friend class ConcurrentSweeperTest;
}; };
} // namespace internal } // namespace cppgc::internal
} // namespace cppgc
#endif // V8_HEAP_CPPGC_SWEEPER_H_ #endif // V8_HEAP_CPPGC_SWEEPER_H_
...@@ -95,9 +95,9 @@ class CompactorTest : public testing::TestWithPlatform { ...@@ -95,9 +95,9 @@ class CompactorTest : public testing::TestWithPlatform {
heap()->GetMarkerRefForTesting().reset(); heap()->GetMarkerRefForTesting().reset();
FinishCompaction(); FinishCompaction();
// Sweeping also verifies the object start bitmap. // Sweeping also verifies the object start bitmap.
const Sweeper::SweepingConfig sweeping_config{ const SweepingConfig sweeping_config{
Sweeper::SweepingConfig::SweepingType::kAtomic, SweepingConfig::SweepingType::kAtomic,
Sweeper::SweepingConfig::CompactableSpaceHandling::kIgnore}; SweepingConfig::CompactableSpaceHandling::kIgnore};
heap()->sweeper().Start(sweeping_config); heap()->sweeper().Start(sweeping_config);
} }
......
...@@ -78,9 +78,9 @@ class ConcurrentSweeperTest : public testing::TestWithHeap { ...@@ -78,9 +78,9 @@ class ConcurrentSweeperTest : public testing::TestWithHeap {
GarbageCollector::Config::IsForcedGC::kNotForced); GarbageCollector::Config::IsForcedGC::kNotForced);
heap->stats_collector()->NotifyMarkingCompleted(0); heap->stats_collector()->NotifyMarkingCompleted(0);
Sweeper& sweeper = heap->sweeper(); Sweeper& sweeper = heap->sweeper();
const Sweeper::SweepingConfig sweeping_config{ const SweepingConfig sweeping_config{
Sweeper::SweepingConfig::SweepingType::kIncrementalAndConcurrent, SweepingConfig::SweepingType::kIncrementalAndConcurrent,
Sweeper::SweepingConfig::CompactableSpaceHandling::kSweep}; SweepingConfig::CompactableSpaceHandling::kSweep};
sweeper.Start(sweeping_config); sweeper.Start(sweeping_config);
} }
......
...@@ -52,9 +52,9 @@ class SweeperTest : public testing::TestWithHeap { ...@@ -52,9 +52,9 @@ class SweeperTest : public testing::TestWithHeap {
GarbageCollector::Config::MarkingType::kAtomic, GarbageCollector::Config::MarkingType::kAtomic,
GarbageCollector::Config::IsForcedGC::kNotForced); GarbageCollector::Config::IsForcedGC::kNotForced);
heap->stats_collector()->NotifyMarkingCompleted(0); heap->stats_collector()->NotifyMarkingCompleted(0);
const Sweeper::SweepingConfig sweeping_config{ const SweepingConfig sweeping_config{
Sweeper::SweepingConfig::SweepingType::kAtomic, SweepingConfig::SweepingType::kAtomic,
Sweeper::SweepingConfig::CompactableSpaceHandling::kSweep}; SweepingConfig::CompactableSpaceHandling::kSweep};
sweeper.Start(sweeping_config); sweeper.Start(sweeping_config);
sweeper.FinishIfRunning(); sweeper.FinishIfRunning();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment