#include "src/heap/sweeper.h"
#include <algorithm>
#include <atomic>
#include <memory>
#include <optional>
#include <vector>
#include "src/base/atomic-utils.h"
#include "src/base/logging.h"
#include "src/common/globals.h"
#include "src/execution/vm-state-inl.h"
#include "src/flags/flags.h"
#include "src/heap/base/active-system-pages.h"
#include "src/heap/ephemeron-remembered-set.h"
#include "src/heap/free-list-inl.h"
#include "src/heap/gc-tracer-inl.h"
#include "src/heap/gc-tracer.h"
#include "src/heap/heap.h"
#include "src/heap/mark-compact-inl.h"
#include "src/heap/mark-compact.h"
#include "src/heap/marking-inl.h"
#include "src/heap/marking-state.h"
#include "src/heap/memory-allocator.h"
#include "src/heap/memory-chunk-layout.h"
#include "src/heap/mutable-page-metadata.h"
#include "src/heap/new-spaces.h"
#include "src/heap/page-metadata-inl.h"
#include "src/heap/paged-spaces.h"
#include "src/heap/pretenuring-handler-inl.h"
#include "src/heap/pretenuring-handler.h"
#include "src/heap/remembered-set.h"
#include "src/heap/slot-set.h"
#include "src/heap/zapping.h"
#include "src/objects/hash-table.h"
#include "src/objects/instance-type.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/map.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
class Sweeper::ConcurrentMajorSweeper final { … };
static constexpr auto kNewSpace = …;
class Sweeper::ConcurrentMinorSweeper final { … };
class Sweeper::MajorSweeperJob final : public JobTask { … };
class Sweeper::MinorSweeperJob final : public JobTask { … };
template <Sweeper::SweepingScope scope>
Sweeper::SweepingState<scope>::SweepingState(Sweeper* sweeper)
: … { … }
template <Sweeper::SweepingScope scope>
Sweeper::SweepingState<scope>::~SweepingState() { … }
template <Sweeper::SweepingScope scope>
bool Sweeper::SweepingState<scope>::HasValidJob() const { … }
template <Sweeper::SweepingScope scope>
bool Sweeper::SweepingState<scope>::HasActiveJob() const { … }
template <Sweeper::SweepingScope scope>
void Sweeper::SweepingState<scope>::StopConcurrentSweeping() { … }
template <Sweeper::SweepingScope scope>
void Sweeper::SweepingState<scope>::InitializeSweeping() { … }
template <Sweeper::SweepingScope scope>
void Sweeper::SweepingState<scope>::StartSweeping() { … }
template <Sweeper::SweepingScope scope>
void Sweeper::SweepingState<scope>::StartConcurrentSweeping() { … }
template <Sweeper::SweepingScope scope>
void Sweeper::SweepingState<scope>::JoinSweeping() { … }
template <Sweeper::SweepingScope scope>
void Sweeper::SweepingState<scope>::FinishSweeping() { … }
template <Sweeper::SweepingScope scope>
void Sweeper::SweepingState<scope>::Pause() { … }
template <Sweeper::SweepingScope scope>
void Sweeper::SweepingState<scope>::Resume() { … }
bool Sweeper::LocalSweeper::ParallelSweepSpace(AllocationSpace identity,
SweepingMode sweeping_mode,
uint32_t max_pages) { … }
void Sweeper::LocalSweeper::ParallelSweepPage(PageMetadata* page,
AllocationSpace identity,
SweepingMode sweeping_mode) { … }
bool Sweeper::LocalSweeper::ContributeAndWaitForPromotedPagesIteration(
JobDelegate* delegate) { … }
bool Sweeper::LocalSweeper::ContributeAndWaitForPromotedPagesIteration() { … }
bool Sweeper::LocalSweeper::ParallelIteratePromotedPages(
JobDelegate* delegate) { … }
bool Sweeper::LocalSweeper::ParallelIteratePromotedPages() { … }
namespace {
class PromotedPageRecordMigratedSlotVisitor final
: public NewSpaceVisitor<PromotedPageRecordMigratedSlotVisitor> { … };
V8_INLINE void AtomicZapBlock(Address addr, size_t size_in_bytes) { … }
void ZapDeadObjectsInRange(Heap* heap, Address dead_start, Address dead_end) { … }
void ZapDeadObjectsOnPage(Heap* heap, PageMetadata* p) { … }
}
void Sweeper::LocalSweeper::ParallelIteratePromotedPage(
MutablePageMetadata* page) { … }
Sweeper::Sweeper(Heap* heap)
: … { … }
Sweeper::~Sweeper() = default;
void Sweeper::TearDown() { … }
void Sweeper::InitializeMajorSweeping() { … }
void Sweeper::InitializeMinorSweeping() { … }
namespace {
V8_INLINE bool ComparePagesForSweepingOrder(const PageMetadata* a,
const PageMetadata* b) { … }
}
void Sweeper::StartMajorSweeping() { … }
void Sweeper::StartMinorSweeping() { … }
namespace {
bool ShouldUpdateRememberedSets(Heap* heap) { … }
}
void Sweeper::StartMajorSweeperTasks() { … }
namespace {
void ClearPromotedPages(Heap* heap, std::vector<MutablePageMetadata*> pages) { … }
}
void Sweeper::StartMinorSweeperTasks() { … }
PageMetadata* Sweeper::GetSweptPageSafe(PagedSpaceBase* space) { … }
Sweeper::SweptList Sweeper::GetAllSweptPagesSafe(PagedSpaceBase* space) { … }
void Sweeper::FinishMajorJobs() { … }
void Sweeper::EnsureMajorCompleted() { … }
void Sweeper::FinishMinorJobs() { … }
void Sweeper::EnsureMinorCompleted() { … }
bool Sweeper::AreMinorSweeperTasksRunning() const { … }
bool Sweeper::AreMajorSweeperTasksRunning() const { … }
bool Sweeper::UsingMajorSweeperTasks() const { … }
V8_INLINE size_t Sweeper::FreeAndProcessFreedMemory(
Address free_start, Address free_end, PageMetadata* page, Space* space,
FreeSpaceTreatmentMode free_space_treatment_mode,
bool should_reduce_memory) { … }
V8_INLINE void Sweeper::CleanupRememberedSetEntriesForFreedMemory(
Address free_start, Address free_end, PageMetadata* page,
bool record_free_ranges, TypedSlotSet::FreeRangesMap* free_ranges_map,
SweepingMode sweeping_mode) { … }
void Sweeper::CleanupTypedSlotsInFreeMemory(
PageMetadata* page, const TypedSlotSet::FreeRangesMap& free_ranges_map,
SweepingMode sweeping_mode) { … }
void Sweeper::ClearMarkBitsAndHandleLivenessStatistics(PageMetadata* page,
size_t live_bytes) { … }
void Sweeper::RawSweep(PageMetadata* p,
FreeSpaceTreatmentMode free_space_treatment_mode,
SweepingMode sweeping_mode, bool should_reduce_memory) { … }
bool Sweeper::IsIteratingPromotedPages() const { … }
void Sweeper::ContributeAndWaitForPromotedPagesIteration() { … }
void Sweeper::NotifyPromotedPageIterationFinished(MutablePageMetadata* chunk) { … }
void Sweeper::NotifyPromotedPagesIterationFinished() { … }
size_t Sweeper::ConcurrentMinorSweepingPageCount() { … }
size_t Sweeper::ConcurrentMajorSweepingPageCount() { … }
bool Sweeper::ParallelSweepSpace(AllocationSpace identity,
SweepingMode sweeping_mode,
uint32_t max_pages) { … }
void Sweeper::EnsurePageIsSwept(PageMetadata* page) { … }
void Sweeper::WaitForPageToBeSwept(PageMetadata* page) { … }
bool Sweeper::TryRemoveSweepingPageSafe(AllocationSpace space,
PageMetadata* page) { … }
bool Sweeper::TryRemovePromotedPageSafe(MutablePageMetadata* chunk) { … }
void Sweeper::AddPage(AllocationSpace space, PageMetadata* page) { … }
void Sweeper::AddNewSpacePage(PageMetadata* page) { … }
void Sweeper::AddPageImpl(AllocationSpace space, PageMetadata* page) { … }
void Sweeper::AddPromotedPage(MutablePageMetadata* chunk) { … }
namespace {
void VerifyPreparedPage(PageMetadata* page) { … }
}
void Sweeper::PrepareToBeSweptPage(AllocationSpace space, PageMetadata* page) { … }
void Sweeper::PrepareToBeIteratedPromotedPage(PageMetadata* page) { … }
PageMetadata* Sweeper::GetSweepingPageSafe(AllocationSpace space) { … }
MutablePageMetadata* Sweeper::GetPromotedPageSafe() { … }
GCTracer::Scope::ScopeId Sweeper::GetTracingScope(AllocationSpace space,
bool is_joining_thread) { … }
bool Sweeper::IsSweepingDoneForSpace(AllocationSpace space) const { … }
void Sweeper::AddSweptPage(PageMetadata* page, AllocationSpace identity) { … }
bool Sweeper::ShouldRefillFreelistForSpace(AllocationSpace space) const { … }
void Sweeper::SweepEmptyNewSpacePage(PageMetadata* page) { … }
Sweeper::PauseMajorSweepingScope::PauseMajorSweepingScope(Sweeper* sweeper)
: … { … }
Sweeper::PauseMajorSweepingScope::~PauseMajorSweepingScope() { … }
uint64_t Sweeper::GetTraceIdForFlowEvent(
GCTracer::Scope::ScopeId scope_id) const { … }
#if DEBUG
bool Sweeper::HasUnsweptPagesForMajorSweeping() const { … }
#endif
}
}