48 page_range_(space->first_page(), nullptr),
50 heap->MakeHeapIterable();
70 std::unique_ptr<FreeList> free_list,
73 executable_(executable),
74 compaction_space_kind_(compaction_space_kind) {
87 page->ResetAllocationStatistics();
88 page->AllocateFreeListCategories();
89 page->InitializeFreeListCategories();
90 page->list_node().Initialize();
96 const bool is_marking =
heap_->isolate()->isolate_data()->is_marking();
97 while (!memory_chunk_list_.Empty()) {
99 memory_chunk_list_.Remove(chunk);
107 heap()->memory_allocator()->Free(mode, chunk);
119 for (
auto it = other->begin(); it != other->end();) {
127 other->RemovePage(p);
140 const bool is_from_client_heap =
141 (other->destination_heap() ==
144 for (
auto p : other->GetNewPages()) {
145 heap()->NotifyOldGenerationExpansion(
146 heap()->main_thread_local_heap(), identity(), p,
148 ? Heap::OldGenerationExpansionNotificationOrigin::kFromClientHeap
149 : Heap::OldGenerationExpansionNotificationOrigin::kFromSameHeap);
159 return CommittedMemory();
167 increment_value, std::memory_order_relaxed);
169 DCHECK_LT(old_value, old_value + increment_value);
175 decrement_value, std::memory_order_relaxed);
177 DCHECK_GT(old_value, old_value - decrement_value);
181void PagedSpaceBase::VerifyCommittedPhysicalMemory()
const {
182 heap()->safepoint()->AssertActive();
185 DCHECK(page->SweepingDone());
186 size += page->CommittedPhysicalMemory();
196 if (page->Chunk() == chunk)
return true;
202 CHECK(page->SweepingDone());
206 size_t old_counter = page->live_bytes();
207 size_t new_counter = page->allocated_bytes();
209 if (old_counter > new_counter) {
210 size_t counter_diff = old_counter - new_counter;
218 page->SetLiveBytes(0);
224 PageMetadata* page = free_list()->GetPageForSize(size_in_bytes);
225 if (!page)
return nullptr;
232 CHECK(page->SweepingDone());
233 page->set_owner(
this);
238 memory_chunk_list_.PushBack(page);
239 AccountCommitted(page->size());
244 IncrementExternalBackingStoreBytes(
245 type, page->ExternalBackingStoreBytes(type));
256 CHECK(page->SweepingDone());
259 memory_chunk_list_.Remove(page);
265 heap()->gc_state() != Heap::NOT_IN_GC);
267 page->ReleaseFreeListCategories();
270 free_list()->decrease_wasted_bytes(page->wasted_memory());
273 AccountUncommitted(page->size());
276 DecrementExternalBackingStoreBytes(
277 type, page->ExternalBackingStoreBytes(type));
292 const size_t accounted_size =
296 if (!
heap()->IsOldGenerationExpansionAllowed(accounted_size,
307 if (page ==
nullptr)
return false;
308 DCHECK_EQ(page->area_size(), accounted_size);
312 heap()->NotifyOldGenerationExpansion(local_heap, identity(), page);
314 Free(page->area_start(), page->area_size());
320 return base::checked_cast<int>(std::distance(
begin(),
end()));
338 DCHECK(page->SweepingDone());
345 memory_chunk_list_.Remove(page);
350 heap()->isolate()->RemoveCodeMemoryChunk(page);
353 AccountUncommitted(page->size());
356 heap()->memory_allocator()->Free(free_mode, page);
360 return std::unique_ptr<ObjectIterator>(
365void PagedSpaceBase::Print() {}
369void PagedSpaceBase::Verify(
Isolate* isolate,
370 SpaceVerificationVisitor* visitor)
const {
373 size_t external_space_bytes[
static_cast<int>(
375 PtrComprCageBase cage_base(isolate);
376 for (
const PageMetadata* page : *
this) {
377 size_t external_page_bytes[
static_cast<int>(
382 visitor->VerifyPage(page);
384 CHECK(page->SweepingDone());
385 Address end_of_previous_object = page->area_start();
386 Address top = page->area_end();
389 CHECK(end_of_previous_object <=
object.address());
392 visitor->VerifyObject(
object);
395 int size =
object->Size(cage_base);
396 CHECK(
object.address() + size <= top);
397 end_of_previous_object =
object.address() +
size;
401 size_t payload_size = external_string->ExternalPayloadSize();
402 external_page_bytes[
static_cast<int>(
407 [page, external_page_bytes, &external_space_bytes](
409 CHECK_EQ(external_page_bytes[index],
410 page->ExternalBackingStoreBytes(type));
411 external_space_bytes[
index] += external_page_bytes[
index];
414 visitor->VerifyPageDone(page);
421 CHECK_EQ(external_space_bytes[index], ExternalBackingStoreBytes(type));
424 if (!
v8_flags.concurrent_array_buffer_sweeping) {
426 size_t bytes =
heap()->array_buffer_sweeper()->old().BytesSlow();
427 CHECK_EQ(bytes, ExternalBackingStoreBytes(
431 size_t bytes =
heap()->array_buffer_sweeper()->young().BytesSlow();
432 CHECK_EQ(bytes, ExternalBackingStoreBytes(
438 VerifyCountersAfterSweeping(isolate->heap());
442void PagedSpaceBase::VerifyLiveBytes()
const {
443 MarkingState* marking_state =
heap()->marking_state();
445 for (
const PageMetadata* page : *
this) {
446 CHECK(page->SweepingDone());
450 if (marking_state->IsMarked(
object)) {
451 black_size +=
object->Size(cage_base);
454 CHECK_LE(black_size, page->live_bytes());
460void PagedSpaceBase::VerifyCountersAfterSweeping(Heap*
heap)
const {
461 size_t total_capacity = 0;
462 size_t total_allocated = 0;
463 PtrComprCageBase cage_base(
heap->isolate());
464 for (
const PageMetadata* page : *
this) {
465 DCHECK(page->SweepingDone());
466 total_capacity += page->area_size();
467 size_t real_allocated = 0;
474 total_allocated += page->allocated_bytes();
484void PagedSpaceBase::VerifyCountersBeforeConcurrentSweeping()
const {
485 size_t total_capacity = 0;
486 size_t total_allocated = 0;
487 for (
const PageMetadata* page : *
this) {
488 size_t page_allocated =
489 page->SweepingDone() ? page->allocated_bytes() : page->live_bytes();
490 total_capacity += page->area_size();
491 total_allocated += page_allocated;
506 const size_t added_pages = page->active_system_pages()->Add(
516 const size_t reduced_pages =
517 page->active_system_pages()->Reduce(active_system_pages);
525 free_list()->RemoveCategory(category);
534 category->
Relink(free_list());
536 free_list()->increase_wasted_bytes(page->wasted_memory());
539 page->AvailableInFreeList() ==
540 page->AvailableInFreeListFromAllocatedBytes());
595 free_list()->EvictFreeListItems(p);
614 compaction_space_kind,
617 compaction_space_kind,
620 compaction_space_kind,
622 if (
heap->isolate()->has_shared_space()) {
623 const CompactionSpace::DestinationHeap dest_heap =
624 heap->isolate()->is_shared_space_isolate()
625 ? CompactionSpace::DestinationHeap::kSameHeap
626 : CompactionSpace::DestinationHeap::kSharedSpaceHeap;
627 shared_space_.emplace(heap->isolate()->shared_space_isolate()->heap(),
628 SHARED_SPACE, Executability::NOT_EXECUTABLE,
629 compaction_space_kind, dest_heap);
637 DCHECK_EQ(page->area_size(), page->allocated_bytes());
641 page->DecreaseAllocatedBytes(page->area_size());
654 size_t filler_size_on_page) {
657 DCHECK(page->SweepingDone());
static bool HasLazyCommits()
void DecreaseCapacity(size_t bytes)
CompactionSpaceCollection(Heap *heap, CompactionSpaceKind compaction_space_kind)
void RefillFreeList() final
std::vector< PageMetadata * > new_pages_
void NotifyNewPage(PageMetadata *page) final
DestinationHeap destination_heap() const
void Relink(FreeList *owner)
uint32_t available() const
static V8_INLINE intptr_t GetCommitPageSizeBits()
static V8_INLINE intptr_t GetCommitPageSize()
static constexpr size_t AllocatableMemoryInMemoryChunk(AllocationSpace space)
void InitializationMemoryFence()
V8_INLINE bool IsFlagSet(Flag flag) const
V8_INLINE Address address() const
static V8_INLINE MemoryChunk * FromAddress(Address addr)
size_t Offset(Address addr) const
static const int kPageSize
void AddPromotedPage(PageMetadata *page, FreeMode free_mode)
void ReleasePage(PageMetadata *page) override
void RelinkQuarantinedPageFreeList(PageMetadata *page, size_t filler_size_on_page)
V8_EXPORT_PRIVATE size_t AvailableInFreeList()
size_t AvailableInFreeListFromAllocatedBytes()
static PageMetadata * cast(MemoryChunkMetadata *metadata)
virtual void NotifyNewPage(PageMetadata *page)
V8_INLINE size_t Free(Address start, size_t size_in_bytes)
void DecreaseAllocatedBytes(size_t bytes, PageMetadata *page)
size_t RelinkFreeListCategories(PageMetadata *page)
int CountTotalPages() const
void AddPageImpl(PageMetadata *page)
virtual void ReleasePage(PageMetadata *page)
virtual void RemovePage(PageMetadata *page)
void DecreaseCapacity(size_t bytes)
virtual size_t AddPage(PageMetadata *page)
bool TryExpand(LocalHeap *local_heap, AllocationOrigin origin)
void ReleasePageImpl(PageMetadata *page, MemoryAllocator::FreeMode free_mode)
void IncreaseAllocatedBytes(size_t bytes, PageMetadata *page)
std::unique_ptr< ObjectIterator > GetObjectIterator(Heap *heap) override
void MergeCompactionSpace(CompactionSpace *other)
void DecrementCommittedPhysicalMemory(size_t decrement_value)
static const size_t kCompactionMemoryWanted
size_t CommittedPhysicalMemory() const override
std::atomic< size_t > committed_physical_memory_
AllocationStats accounting_stats_
friend class PagedSpaceAllocatorPolicy
size_t committed_physical_memory() const
bool is_compaction_space() const
size_t Available() const override
bool ContainsSlow(Address addr) const
PagedSpaceBase(Heap *heap, AllocationSpace id, Executability executable, std::unique_ptr< FreeList > free_list, CompactionSpaceKind compaction_space_kind)
void AddRangeToActiveSystemPages(PageMetadata *page, Address start, Address end)
PageMetadata * RemovePageSafe(int size_in_bytes)
void IncrementCommittedPhysicalMemory(size_t increment_value)
void UnlinkFreeListCategories(PageMetadata *page)
Executability executable() const
void ReduceActiveSystemPages(PageMetadata *page, ActiveSystemPages active_system_pages)
virtual void RefillFreeList()
void IncreaseCapacity(size_t bytes)
virtual void AdjustDifferenceInAllocatedBytes(size_t diff)
PageMetadata * InitializePage(MutablePageMetadata *chunk) override
void RefineAllocatedBytesAfterSweeping(PageMetadata *page)
ConstPageRange::iterator current_page_
PagedSpaceObjectIterator(Heap *heap, const PagedSpaceBase *space)
HeapObjectRange::iterator end_
const PagedSpaceBase *const space_
ConstPageRange page_range_
HeapObjectRange::iterator cur_
AllocatorPolicy * CreateAllocatorPolicy(MainAllocator *allocator) final
void ReleasePage(PageMetadata *page) override
void AdjustDifferenceInAllocatedBytes(size_t) override
size_t allocated_old_size_
PageMetadata * GetSweptPageSafe(PagedSpaceBase *space)
#define ALIGN_TO_ALLOCATION_ALIGNMENT(value)
NormalPage * current_page_
#define V8_ENABLE_STICKY_MARK_BITS_BOOL
V8_INLINE constexpr bool IsExternalString(InstanceType instance_type)
V8_INLINE constexpr bool IsFreeSpaceOrFiller(InstanceType instance_type)
Tagged(T object) -> Tagged< T >
kInterpreterTrampolineOffset Tagged< HeapObject >
void ForAll(Callback callback)
V8_EXPORT_PRIVATE FlagValues v8_flags
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define DCHECK_LE(v1, v2)
#define CHECK_IMPLIES(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)