Commit 03217624 authored by Darius Mercadier's avatar Darius Mercadier Committed by Commit Bot

[heap] Use generic FreeLists

Bug: v8:9329
Change-Id: I28619fef8f206fcb749b8974bb3e7547d6da402e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1687423
Commit-Queue: Darius Mercadier <dmercadier@google.com>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62635}
parent c28f7e14
...@@ -515,8 +515,10 @@ void Heap::PrintFreeListsStats() { ...@@ -515,8 +515,10 @@ void Heap::PrintFreeListsStats() {
"[category: length || total free bytes]\n"); "[category: length || total free bytes]\n");
} }
int categories_lengths[kNumberOfCategories] = {0}; std::vector<int> categories_lengths(
size_t categories_sums[kNumberOfCategories] = {0}; old_space()->free_list()->number_of_categories(), 0);
std::vector<size_t> categories_sums(
old_space()->free_list()->number_of_categories(), 0);
unsigned int pageCnt = 0; unsigned int pageCnt = 0;
// This loops computes freelists lengths and sum. // This loops computes freelists lengths and sum.
...@@ -529,7 +531,8 @@ void Heap::PrintFreeListsStats() { ...@@ -529,7 +531,8 @@ void Heap::PrintFreeListsStats() {
out_str << "Page " << std::setw(4) << pageCnt; out_str << "Page " << std::setw(4) << pageCnt;
} }
for (int cat = kFirstCategory; cat <= kLastCategory; cat++) { for (int cat = kFirstCategory;
cat <= old_space()->free_list()->last_category(); cat++) {
FreeListCategory* free_list = FreeListCategory* free_list =
page->free_list_category(static_cast<FreeListCategoryType>(cat)); page->free_list_category(static_cast<FreeListCategoryType>(cat));
int length = free_list->FreeListLength(); int length = free_list->FreeListLength();
...@@ -538,7 +541,8 @@ void Heap::PrintFreeListsStats() { ...@@ -538,7 +541,8 @@ void Heap::PrintFreeListsStats() {
if (FLAG_trace_gc_freelists_verbose) { if (FLAG_trace_gc_freelists_verbose) {
out_str << "[" << cat << ": " << std::setw(4) << length << " || " out_str << "[" << cat << ": " << std::setw(4) << length << " || "
<< std::setw(6) << sum << " ]" << std::setw(6) << sum << " ]"
<< (cat == kLastCategory ? "\n" : ", "); << (cat == old_space()->free_list()->last_category() ? "\n"
: ", ");
} }
categories_lengths[cat] += length; categories_lengths[cat] += length;
categories_sums[cat] += sum; categories_sums[cat] += sum;
...@@ -567,11 +571,12 @@ void Heap::PrintFreeListsStats() { ...@@ -567,11 +571,12 @@ void Heap::PrintFreeListsStats() {
"FreeLists global statistics: " "FreeLists global statistics: "
"[category: length || total free KB]\n"); "[category: length || total free KB]\n");
std::ostringstream out_str; std::ostringstream out_str;
for (int cat = 0; cat <= kLastCategory; cat++) { for (int cat = kFirstCategory;
cat <= old_space()->free_list()->last_category(); cat++) {
out_str << "[" << cat << ": " << categories_lengths[cat] << " || " out_str << "[" << cat << ": " << categories_lengths[cat] << " || "
<< std::fixed << std::setprecision(2) << std::fixed << std::setprecision(2)
<< static_cast<double>(categories_sums[cat]) / KB << " KB]" << static_cast<double>(categories_sums[cat]) / KB << " KB]"
<< (cat == kLastCategory ? "\n" : ", "); << (cat == old_space()->free_list()->last_category() ? "\n" : ", ");
} }
PrintIsolate(isolate_, "%s", out_str.str().c_str()); PrintIsolate(isolate_, "%s", out_str.str().c_str());
} }
......
...@@ -182,7 +182,7 @@ size_t PagedSpace::RelinkFreeListCategories(Page* page) { ...@@ -182,7 +182,7 @@ size_t PagedSpace::RelinkFreeListCategories(Page* page) {
DCHECK_EQ(this, page->owner()); DCHECK_EQ(this, page->owner());
size_t added = 0; size_t added = 0;
page->ForAllFreeListCategories([this, &added](FreeListCategory* category) { page->ForAllFreeListCategories([this, &added](FreeListCategory* category) {
category->set_free_list(&free_list_); category->set_free_list(free_list());
added += category->available(); added += category->available();
category->Relink(); category->Relink();
}); });
...@@ -322,10 +322,6 @@ MemoryChunk* OldGenerationMemoryChunkIterator::next() { ...@@ -322,10 +322,6 @@ MemoryChunk* OldGenerationMemoryChunkIterator::next() {
UNREACHABLE(); UNREACHABLE();
} }
Page* FreeList::GetPageForCategoryType(FreeListCategoryType type) {
return top(type) ? top(type)->page() : nullptr;
}
FreeList* FreeListCategory::owner() { return free_list_; } FreeList* FreeListCategory::owner() { return free_list_; }
bool FreeListCategory::is_linked() { bool FreeListCategory::is_linked() {
......
...@@ -726,9 +726,7 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size, ...@@ -726,9 +726,7 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size,
chunk->external_backing_store_bytes_ chunk->external_backing_store_bytes_
[ExternalBackingStoreType::kExternalString] = 0; [ExternalBackingStoreType::kExternalString] = 0;
for (int i = kFirstCategory; i < kNumberOfCategories; i++) { chunk->categories_ = nullptr;
chunk->categories_[i] = nullptr;
}
chunk->AllocateMarkingBitmap(); chunk->AllocateMarkingBitmap();
if (owner->identity() == RO_SPACE) { if (owner->identity() == RO_SPACE) {
...@@ -830,25 +828,32 @@ LargePage* LargePage::Initialize(Heap* heap, MemoryChunk* chunk, ...@@ -830,25 +828,32 @@ LargePage* LargePage::Initialize(Heap* heap, MemoryChunk* chunk,
} }
void Page::AllocateFreeListCategories() { void Page::AllocateFreeListCategories() {
for (int i = kFirstCategory; i < kNumberOfCategories; i++) { DCHECK_NULL(categories_);
categories_ = new FreeListCategory*[free_list()->number_of_categories()]();
for (int i = kFirstCategory; i <= free_list()->last_category(); i++) {
DCHECK_NULL(categories_[i]);
categories_[i] = new FreeListCategory( categories_[i] = new FreeListCategory(
reinterpret_cast<PagedSpace*>(owner())->free_list(), this); reinterpret_cast<PagedSpace*>(owner())->free_list(), this);
} }
} }
void Page::InitializeFreeListCategories() { void Page::InitializeFreeListCategories() {
for (int i = kFirstCategory; i < kNumberOfCategories; i++) { for (int i = kFirstCategory; i <= free_list()->last_category(); i++) {
categories_[i]->Initialize(static_cast<FreeListCategoryType>(i)); categories_[i]->Initialize(static_cast<FreeListCategoryType>(i));
} }
} }
void Page::ReleaseFreeListCategories() { void Page::ReleaseFreeListCategories() {
for (int i = kFirstCategory; i < kNumberOfCategories; i++) { if (categories_ != nullptr) {
for (int i = kFirstCategory; i <= free_list()->last_category(); i++) {
if (categories_[i] != nullptr) { if (categories_[i] != nullptr) {
delete categories_[i]; delete categories_[i];
categories_[i] = nullptr; categories_[i] = nullptr;
} }
} }
delete[] categories_;
categories_ = nullptr;
}
} }
Page* Page::ConvertNewToOld(Page* old_page) { Page* Page::ConvertNewToOld(Page* old_page) {
...@@ -1392,12 +1397,13 @@ void MemoryChunk::ReleaseAllocatedMemoryNeededForWritableChunk() { ...@@ -1392,12 +1397,13 @@ void MemoryChunk::ReleaseAllocatedMemoryNeededForWritableChunk() {
} }
void MemoryChunk::ReleaseAllAllocatedMemory() { void MemoryChunk::ReleaseAllAllocatedMemory() {
ReleaseAllocatedMemoryNeededForWritableChunk();
if (marking_bitmap_ != nullptr) ReleaseMarkingBitmap();
if (!IsLargePage()) { if (!IsLargePage()) {
Page* page = static_cast<Page*>(this); Page* page = static_cast<Page*>(this);
page->ReleaseFreeListCategories(); page->ReleaseFreeListCategories();
} }
ReleaseAllocatedMemoryNeededForWritableChunk();
if (marking_bitmap_ != nullptr) ReleaseMarkingBitmap();
} }
static SlotSet* AllocateAndInitializeSlotSet(size_t size, Address page_start) { static SlotSet* AllocateAndInitializeSlotSet(size_t size, Address page_start) {
...@@ -1597,8 +1603,8 @@ intptr_t Space::GetNextInlineAllocationStepSize() { ...@@ -1597,8 +1603,8 @@ intptr_t Space::GetNextInlineAllocationStepSize() {
} }
PagedSpace::PagedSpace(Heap* heap, AllocationSpace space, PagedSpace::PagedSpace(Heap* heap, AllocationSpace space,
Executability executable) Executability executable, FreeList* free_list)
: SpaceWithLinearArea(heap, space), executable_(executable) { : SpaceWithLinearArea(heap, space, free_list), executable_(executable) {
area_size_ = MemoryChunkLayout::AllocatableMemoryInMemoryChunk(space); area_size_ = MemoryChunkLayout::AllocatableMemoryInMemoryChunk(space);
accounting_stats_.Clear(); accounting_stats_.Clear();
} }
...@@ -1719,21 +1725,7 @@ void PagedSpace::RefineAllocatedBytesAfterSweeping(Page* page) { ...@@ -1719,21 +1725,7 @@ void PagedSpace::RefineAllocatedBytesAfterSweeping(Page* page) {
Page* PagedSpace::RemovePageSafe(int size_in_bytes) { Page* PagedSpace::RemovePageSafe(int size_in_bytes) {
base::MutexGuard guard(mutex()); base::MutexGuard guard(mutex());
// Check for pages that still contain free list entries. Bail out for smaller Page* page = free_list()->GetPageForSize(size_in_bytes);
// categories.
const int minimum_category =
static_cast<int>(FreeList::SelectFreeListCategoryType(size_in_bytes));
Page* page = free_list()->GetPageForCategoryType(kHuge);
if (!page && static_cast<int>(kLarge) >= minimum_category)
page = free_list()->GetPageForCategoryType(kLarge);
if (!page && static_cast<int>(kMedium) >= minimum_category)
page = free_list()->GetPageForCategoryType(kMedium);
if (!page && static_cast<int>(kSmall) >= minimum_category)
page = free_list()->GetPageForCategoryType(kSmall);
if (!page && static_cast<int>(kTiny) >= minimum_category)
page = free_list()->GetPageForCategoryType(kTiny);
if (!page && static_cast<int>(kTiniest) >= minimum_category)
page = free_list()->GetPageForCategoryType(kTiniest);
if (!page) return nullptr; if (!page) return nullptr;
RemovePage(page); RemovePage(page);
return page; return page;
...@@ -1775,9 +1767,9 @@ size_t PagedSpace::ShrinkPageToHighWaterMark(Page* page) { ...@@ -1775,9 +1767,9 @@ size_t PagedSpace::ShrinkPageToHighWaterMark(Page* page) {
void PagedSpace::ResetFreeList() { void PagedSpace::ResetFreeList() {
for (Page* page : *this) { for (Page* page : *this) {
free_list_.EvictFreeListItems(page); free_list_->EvictFreeListItems(page);
} }
DCHECK(free_list_.IsEmpty()); DCHECK(free_list_->IsEmpty());
} }
void PagedSpace::ShrinkImmortalImmovablePages() { void PagedSpace::ShrinkImmortalImmovablePages() {
...@@ -1940,8 +1932,8 @@ void PagedSpace::ReleasePage(Page* page) { ...@@ -1940,8 +1932,8 @@ void PagedSpace::ReleasePage(Page* page) {
page)); page));
DCHECK_EQ(page->owner(), this); DCHECK_EQ(page->owner(), this);
free_list_.EvictFreeListItems(page); free_list_->EvictFreeListItems(page);
DCHECK(!free_list_.ContainsPageFreeListItems(page)); DCHECK(!free_list_->ContainsPageFreeListItems(page));
if (Page::FromAllocationAreaAddress(allocation_info_.top()) == page) { if (Page::FromAllocationAreaAddress(allocation_info_.top()) == page) {
DCHECK(!top_on_previous_step_); DCHECK(!top_on_previous_step_);
...@@ -2004,7 +1996,7 @@ bool PagedSpace::RefillLinearAllocationAreaFromFreeList(size_t size_in_bytes) { ...@@ -2004,7 +1996,7 @@ bool PagedSpace::RefillLinearAllocationAreaFromFreeList(size_t size_in_bytes) {
} }
size_t new_node_size = 0; size_t new_node_size = 0;
FreeSpace new_node = free_list_.Allocate(size_in_bytes, &new_node_size); FreeSpace new_node = free_list_->Allocate(size_in_bytes, &new_node_size);
if (new_node.is_null()) return false; if (new_node.is_null()) return false;
DCHECK_GE(new_node_size, size_in_bytes); DCHECK_GE(new_node_size, size_in_bytes);
...@@ -2191,7 +2183,7 @@ void PagedSpace::VerifyCountersBeforeConcurrentSweeping() { ...@@ -2191,7 +2183,7 @@ void PagedSpace::VerifyCountersBeforeConcurrentSweeping() {
NewSpace::NewSpace(Heap* heap, v8::PageAllocator* page_allocator, NewSpace::NewSpace(Heap* heap, v8::PageAllocator* page_allocator,
size_t initial_semispace_capacity, size_t initial_semispace_capacity,
size_t max_semispace_capacity) size_t max_semispace_capacity)
: SpaceWithLinearArea(heap, NEW_SPACE), : SpaceWithLinearArea(heap, NEW_SPACE, new NoFreeList()),
to_space_(heap, kToSpace), to_space_(heap, kToSpace),
from_space_(heap, kFromSpace) { from_space_(heap, kFromSpace) {
DCHECK(initial_semispace_capacity <= max_semispace_capacity); DCHECK(initial_semispace_capacity <= max_semispace_capacity);
...@@ -2638,6 +2630,9 @@ bool SemiSpace::Commit() { ...@@ -2638,6 +2630,9 @@ bool SemiSpace::Commit() {
DCHECK(!is_committed()); DCHECK(!is_committed());
const int num_pages = static_cast<int>(current_capacity_ / Page::kPageSize); const int num_pages = static_cast<int>(current_capacity_ / Page::kPageSize);
for (int pages_added = 0; pages_added < num_pages; pages_added++) { for (int pages_added = 0; pages_added < num_pages; pages_added++) {
// Pages in the new spaces can be moved to the old space by the full
// collector. Therefore, they must be initialized with the same FreeList as
// old pages.
Page* new_page = Page* new_page =
heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>(
MemoryChunkLayout::AllocatableMemoryInDataPage(), this, MemoryChunkLayout::AllocatableMemoryInDataPage(), this,
...@@ -3010,24 +3005,30 @@ void FreeListCategory::Relink() { ...@@ -3010,24 +3005,30 @@ void FreeListCategory::Relink() {
owner()->AddCategory(this); owner()->AddCategory(this);
} }
FreeList::FreeList() : wasted_bytes_(0) { FreeList* FreeList::CreateFreeList() { return new FreeListLegacy(); }
for (int i = kFirstCategory; i < kNumberOfCategories; i++) {
categories_[i] = nullptr; FreeListLegacy::FreeListLegacy() {
} wasted_bytes_ = 0;
number_of_categories_ = kHuge + 1;
last_category_ = kHuge;
categories_ = new FreeListCategory*[number_of_categories_]();
Reset(); Reset();
} }
FreeListLegacy::~FreeListLegacy() { delete[] categories_; }
void FreeList::Reset() { void FreeList::Reset() {
ForAllFreeListCategories( ForAllFreeListCategories(
[](FreeListCategory* category) { category->Reset(); }); [](FreeListCategory* category) { category->Reset(); });
for (int i = kFirstCategory; i < kNumberOfCategories; i++) { for (int i = kFirstCategory; i < number_of_categories_; i++) {
categories_[i] = nullptr; categories_[i] = nullptr;
} }
wasted_bytes_ = 0; wasted_bytes_ = 0;
} }
size_t FreeList::Free(Address start, size_t size_in_bytes, FreeMode mode) { size_t FreeListLegacy::Free(Address start, size_t size_in_bytes,
FreeMode mode) {
Page* page = Page::FromAddress(start); Page* page = Page::FromAddress(start);
page->DecreaseAllocatedBytes(size_in_bytes); page->DecreaseAllocatedBytes(size_in_bytes);
...@@ -3047,9 +3048,9 @@ size_t FreeList::Free(Address start, size_t size_in_bytes, FreeMode mode) { ...@@ -3047,9 +3048,9 @@ size_t FreeList::Free(Address start, size_t size_in_bytes, FreeMode mode) {
return 0; return 0;
} }
FreeSpace FreeListLegacy::TryFindNodeIn(FreeListCategoryType type,
FreeSpace FreeList::TryFindNodeIn(FreeListCategoryType type, size_t minimum_size,
size_t minimum_size, size_t* node_size) { size_t* node_size) {
FreeListCategory* category = categories_[type]; FreeListCategory* category = categories_[type];
if (category == nullptr) return FreeSpace(); if (category == nullptr) return FreeSpace();
FreeSpace node = category->PickNodeFromList(minimum_size, node_size); FreeSpace node = category->PickNodeFromList(minimum_size, node_size);
...@@ -3062,7 +3063,7 @@ FreeSpace FreeList::TryFindNodeIn(FreeListCategoryType type, ...@@ -3062,7 +3063,7 @@ FreeSpace FreeList::TryFindNodeIn(FreeListCategoryType type,
return node; return node;
} }
FreeSpace FreeList::SearchForNodeInList(FreeListCategoryType type, FreeSpace FreeListLegacy::SearchForNodeInList(FreeListCategoryType type,
size_t* node_size, size_t* node_size,
size_t minimum_size) { size_t minimum_size) {
FreeListCategoryIterator it(this, type); FreeListCategoryIterator it(this, type);
...@@ -3081,7 +3082,7 @@ FreeSpace FreeList::SearchForNodeInList(FreeListCategoryType type, ...@@ -3081,7 +3082,7 @@ FreeSpace FreeList::SearchForNodeInList(FreeListCategoryType type,
return node; return node;
} }
FreeSpace FreeList::Allocate(size_t size_in_bytes, size_t* node_size) { FreeSpace FreeListLegacy::Allocate(size_t size_in_bytes, size_t* node_size) {
DCHECK_GE(kMaxBlockSize, size_in_bytes); DCHECK_GE(kMaxBlockSize, size_in_bytes);
FreeSpace node; FreeSpace node;
// First try the allocation fast path: try to allocate the minimum element // First try the allocation fast path: try to allocate the minimum element
...@@ -3153,7 +3154,7 @@ void FreeList::RepairLists(Heap* heap) { ...@@ -3153,7 +3154,7 @@ void FreeList::RepairLists(Heap* heap) {
bool FreeList::AddCategory(FreeListCategory* category) { bool FreeList::AddCategory(FreeListCategory* category) {
FreeListCategoryType type = category->type_; FreeListCategoryType type = category->type_;
DCHECK_LT(type, kNumberOfCategories); DCHECK_LT(type, number_of_categories_);
FreeListCategory* top = categories_[type]; FreeListCategory* top = categories_[type];
if (category->is_empty()) return false; if (category->is_empty()) return false;
...@@ -3170,7 +3171,7 @@ bool FreeList::AddCategory(FreeListCategory* category) { ...@@ -3170,7 +3171,7 @@ bool FreeList::AddCategory(FreeListCategory* category) {
void FreeList::RemoveCategory(FreeListCategory* category) { void FreeList::RemoveCategory(FreeListCategory* category) {
FreeListCategoryType type = category->type_; FreeListCategoryType type = category->type_;
DCHECK_LT(type, kNumberOfCategories); DCHECK_LT(type, number_of_categories_);
FreeListCategory* top = categories_[type]; FreeListCategory* top = categories_[type];
// Common double-linked list removal. // Common double-linked list removal.
...@@ -3200,7 +3201,7 @@ void FreeList::PrintCategories(FreeListCategoryType type) { ...@@ -3200,7 +3201,7 @@ void FreeList::PrintCategories(FreeListCategoryType type) {
int MemoryChunk::FreeListsLength() { int MemoryChunk::FreeListsLength() {
int length = 0; int length = 0;
for (int cat = kFirstCategory; cat <= kLastCategory; cat++) { for (int cat = kFirstCategory; cat <= free_list()->last_category(); cat++) {
if (categories_[cat] != nullptr) { if (categories_[cat] != nullptr) {
length += categories_[cat]->FreeListLength(); length += categories_[cat]->FreeListLength();
} }
...@@ -3225,7 +3226,7 @@ size_t FreeListCategory::SumFreeList() { ...@@ -3225,7 +3226,7 @@ size_t FreeListCategory::SumFreeList() {
#ifdef DEBUG #ifdef DEBUG
bool FreeList::IsVeryLong() { bool FreeList::IsVeryLong() {
int len = 0; int len = 0;
for (int i = kFirstCategory; i < kNumberOfCategories; i++) { for (int i = kFirstCategory; i < number_of_categories_; i++) {
FreeListCategoryIterator it(this, static_cast<FreeListCategoryType>(i)); FreeListCategoryIterator it(this, static_cast<FreeListCategoryType>(i));
while (it.HasNext()) { while (it.HasNext()) {
len += it.Next()->FreeListLength(); len += it.Next()->FreeListLength();
...@@ -3257,7 +3258,7 @@ void PagedSpace::PrepareForMarkCompact() { ...@@ -3257,7 +3258,7 @@ void PagedSpace::PrepareForMarkCompact() {
FreeLinearAllocationArea(); FreeLinearAllocationArea();
// Clear the free list before a full GC---it will be rebuilt afterward. // Clear the free list before a full GC---it will be rebuilt afterward.
free_list_.Reset(); free_list_->Reset();
} }
size_t PagedSpace::SizeOfObjects() { size_t PagedSpace::SizeOfObjects() {
...@@ -3350,7 +3351,7 @@ bool PagedSpace::RawSlowRefillLinearAllocationArea(int size_in_bytes) { ...@@ -3350,7 +3351,7 @@ bool PagedSpace::RawSlowRefillLinearAllocationArea(int size_in_bytes) {
if (heap()->ShouldExpandOldGenerationOnSlowAllocation() && Expand()) { if (heap()->ShouldExpandOldGenerationOnSlowAllocation() && Expand()) {
DCHECK((CountTotalPages() > 1) || DCHECK((CountTotalPages() > 1) ||
(static_cast<size_t>(size_in_bytes) <= free_list_.Available())); (static_cast<size_t>(size_in_bytes) <= free_list_->Available()));
return RefillLinearAllocationAreaFromFreeList( return RefillLinearAllocationAreaFromFreeList(
static_cast<size_t>(size_in_bytes)); static_cast<size_t>(size_in_bytes));
} }
...@@ -3369,7 +3370,7 @@ void MapSpace::VerifyObject(HeapObject object) { CHECK(object.IsMap()); } ...@@ -3369,7 +3370,7 @@ void MapSpace::VerifyObject(HeapObject object) { CHECK(object.IsMap()); }
#endif #endif
ReadOnlySpace::ReadOnlySpace(Heap* heap) ReadOnlySpace::ReadOnlySpace(Heap* heap)
: PagedSpace(heap, RO_SPACE, NOT_EXECUTABLE), : PagedSpace(heap, RO_SPACE, NOT_EXECUTABLE, FreeList::CreateFreeList()),
is_string_padding_cleared_(heap->isolate()->initialized_from_snapshot()) { is_string_padding_cleared_(heap->isolate()->initialized_from_snapshot()) {
} }
...@@ -3377,10 +3378,11 @@ void ReadOnlyPage::MakeHeaderRelocatable() { ...@@ -3377,10 +3378,11 @@ void ReadOnlyPage::MakeHeaderRelocatable() {
ReleaseAllocatedMemoryNeededForWritableChunk(); ReleaseAllocatedMemoryNeededForWritableChunk();
// Detached read-only space needs to have a valid marking bitmap and free list // Detached read-only space needs to have a valid marking bitmap and free list
// categories. Instruct Lsan to ignore them if required. // categories. Instruct Lsan to ignore them if required.
LSAN_IGNORE_OBJECT(marking_bitmap_); LSAN_IGNORE_OBJECT(categories_);
for (int i = kFirstCategory; i < kNumberOfCategories; i++) { for (int i = kFirstCategory; i < free_list()->number_of_categories(); i++) {
LSAN_IGNORE_OBJECT(categories_[i]); LSAN_IGNORE_OBJECT(categories_[i]);
} }
LSAN_IGNORE_OBJECT(marking_bitmap_);
heap_ = nullptr; heap_ = nullptr;
owner_ = nullptr; owner_ = nullptr;
} }
...@@ -3401,7 +3403,7 @@ void ReadOnlySpace::SetPermissionsForPages(MemoryAllocator* memory_allocator, ...@@ -3401,7 +3403,7 @@ void ReadOnlySpace::SetPermissionsForPages(MemoryAllocator* memory_allocator,
// were created with the wrong FreeSpaceMap (normally nullptr), so we need to // were created with the wrong FreeSpaceMap (normally nullptr), so we need to
// fix them. // fix them.
void ReadOnlySpace::RepairFreeListsAfterDeserialization() { void ReadOnlySpace::RepairFreeListsAfterDeserialization() {
free_list_.RepairLists(heap()); free_list_->RepairLists(heap());
// Each page may have a small free space that is not tracked by a free list. // Each page may have a small free space that is not tracked by a free list.
// Those free spaces still contain null as their map pointer. // Those free spaces still contain null as their map pointer.
// Overwrite them with new fillers. // Overwrite them with new fillers.
...@@ -3507,7 +3509,10 @@ LargeObjectSpace::LargeObjectSpace(Heap* heap) ...@@ -3507,7 +3509,10 @@ LargeObjectSpace::LargeObjectSpace(Heap* heap)
: LargeObjectSpace(heap, LO_SPACE) {} : LargeObjectSpace(heap, LO_SPACE) {}
LargeObjectSpace::LargeObjectSpace(Heap* heap, AllocationSpace id) LargeObjectSpace::LargeObjectSpace(Heap* heap, AllocationSpace id)
: Space(heap, id), size_(0), page_count_(0), objects_size_(0) {} : Space(heap, id, new NoFreeList()),
size_(0),
page_count_(0),
objects_size_(0) {}
void LargeObjectSpace::TearDown() { void LargeObjectSpace::TearDown() {
while (!memory_chunk_list_.Empty()) { while (!memory_chunk_list_.Empty()) {
......
...@@ -119,19 +119,10 @@ class Space; ...@@ -119,19 +119,10 @@ class Space;
#define DCHECK_CODEOBJECT_SIZE(size, code_space) \ #define DCHECK_CODEOBJECT_SIZE(size, code_space) \
DCHECK((0 < size) && (size <= code_space->AreaSize())) DCHECK((0 < size) && (size <= code_space->AreaSize()))
enum FreeListCategoryType { using FreeListCategoryType = int;
kTiniest,
kTiny, static const FreeListCategoryType kFirstCategory = 0;
kSmall, static const FreeListCategoryType kInvalidCategory = -1;
kMedium,
kLarge,
kHuge,
kFirstCategory = kTiniest,
kLastCategory = kHuge,
kNumberOfCategories = kLastCategory + 1,
kInvalidCategory
};
enum FreeMode { kLinkCategory, kDoNotLinkCategory }; enum FreeMode { kLinkCategory, kDoNotLinkCategory };
...@@ -233,6 +224,288 @@ class FreeListCategory { ...@@ -233,6 +224,288 @@ class FreeListCategory {
DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListCategory); DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListCategory);
}; };
// A free list maintains free blocks of memory. The free list is organized in
// a way to encourage objects allocated around the same time to be near each
// other. The normal way to allocate is intended to be by bumping a 'top'
// pointer until it hits a 'limit' pointer. When the limit is hit we need to
// find a new space to allocate from. This is done with the free list, which is
// divided up into rough categories to cut down on waste. Having finer
// categories would scatter allocation more.
class FreeList {
public:
// Creates a Freelist of the default class (FreeListLegacy for now).
V8_EXPORT_PRIVATE static FreeList* CreateFreeList();
virtual ~FreeList() = default;
virtual size_t GuaranteedAllocatable(size_t maximum_freed) = 0;
virtual size_t Free(Address start, size_t size_in_bytes, FreeMode mode) = 0;
virtual V8_WARN_UNUSED_RESULT FreeSpace Allocate(size_t size_in_bytes,
size_t* node_size) = 0;
// Returns a page containing an entry for a given type, or nullptr otherwise.
V8_EXPORT_PRIVATE virtual Page* GetPageForSize(size_t size_in_bytes) = 0;
void Reset();
// Return the number of bytes available on the free list.
size_t Available() {
size_t available = 0;
ForAllFreeListCategories([&available](FreeListCategory* category) {
available += category->available();
});
return available;
}
bool IsEmpty() {
bool empty = true;
ForAllFreeListCategories([&empty](FreeListCategory* category) {
if (!category->is_empty()) empty = false;
});
return empty;
}
// Used after booting the VM.
void RepairLists(Heap* heap);
V8_EXPORT_PRIVATE size_t EvictFreeListItems(Page* page);
bool ContainsPageFreeListItems(Page* page);
int number_of_categories() { return number_of_categories_; }
FreeListCategoryType last_category() { return last_category_; }
size_t wasted_bytes() { return wasted_bytes_; }
template <typename Callback>
void ForAllFreeListCategories(FreeListCategoryType type, Callback callback) {
FreeListCategory* current = categories_[type];
while (current != nullptr) {
FreeListCategory* next = current->next();
callback(current);
current = next;
}
}
template <typename Callback>
void ForAllFreeListCategories(Callback callback) {
for (int i = kFirstCategory; i < number_of_categories(); i++) {
ForAllFreeListCategories(static_cast<FreeListCategoryType>(i), callback);
}
}
bool AddCategory(FreeListCategory* category);
V8_EXPORT_PRIVATE void RemoveCategory(FreeListCategory* category);
void PrintCategories(FreeListCategoryType type);
#ifdef DEBUG
size_t SumFreeLists();
bool IsVeryLong();
#endif
protected:
class FreeListCategoryIterator final {
public:
FreeListCategoryIterator(FreeList* free_list, FreeListCategoryType type)
: current_(free_list->categories_[type]) {}
bool HasNext() const { return current_ != nullptr; }
FreeListCategory* Next() {
DCHECK(HasNext());
FreeListCategory* tmp = current_;
current_ = current_->next();
return tmp;
}
private:
FreeListCategory* current_;
};
FreeListCategory* top(FreeListCategoryType type) const {
return categories_[type];
}
int number_of_categories_;
FreeListCategoryType last_category_;
std::atomic<size_t> wasted_bytes_;
FreeListCategory** categories_;
friend class FreeListCategory;
friend class Page;
friend class MemoryChunk;
friend class ReadOnlyPage;
};
// FreeList used for spaces that don't have freelists
// (only the LargeObject space for now).
class NoFreeList final : public FreeList {
public:
size_t GuaranteedAllocatable(size_t maximum_freed) final {
FATAL("NoFreeList can't be used as a standard FreeList. ");
}
size_t Free(Address start, size_t size_in_bytes, FreeMode mode) final {
FATAL("NoFreeList can't be used as a standard FreeList.");
}
V8_WARN_UNUSED_RESULT FreeSpace Allocate(size_t size_in_bytes,
size_t* node_size) final {
FATAL("NoFreeList can't be used as a standard FreeList.");
}
Page* GetPageForSize(size_t size_in_bytes) final {
FATAL("NoFreeList can't be used as a standard FreeList.");
}
};
// ----------------------------------------------------------------------------
// Space is the abstract superclass for all allocation spaces.
class V8_EXPORT_PRIVATE Space : public Malloced {
public:
Space(Heap* heap, AllocationSpace id, FreeList* free_list)
: allocation_observers_paused_(false),
heap_(heap),
id_(id),
committed_(0),
max_committed_(0),
free_list_(std::unique_ptr<FreeList>(free_list)) {
external_backing_store_bytes_ =
new std::atomic<size_t>[ExternalBackingStoreType::kNumTypes];
external_backing_store_bytes_[ExternalBackingStoreType::kArrayBuffer] = 0;
external_backing_store_bytes_[ExternalBackingStoreType::kExternalString] =
0;
CheckOffsetsAreConsistent();
}
void CheckOffsetsAreConsistent() const;
static inline void MoveExternalBackingStoreBytes(
ExternalBackingStoreType type, Space* from, Space* to, size_t amount);
virtual ~Space() {
delete[] external_backing_store_bytes_;
external_backing_store_bytes_ = nullptr;
}
Heap* heap() const {
DCHECK_NOT_NULL(heap_);
return heap_;
}
bool IsDetached() const { return heap_ == nullptr; }
AllocationSpace identity() { return id_; }
const char* name() { return Heap::GetSpaceName(id_); }
virtual void AddAllocationObserver(AllocationObserver* observer);
virtual void RemoveAllocationObserver(AllocationObserver* observer);
virtual void PauseAllocationObservers();
virtual void ResumeAllocationObservers();
virtual void StartNextInlineAllocationStep() {}
void AllocationStep(int bytes_since_last, Address soon_object, int size);
// Return the total amount committed memory for this space, i.e., allocatable
// memory and page headers.
virtual size_t CommittedMemory() { return committed_; }
virtual size_t MaximumCommittedMemory() { return max_committed_; }
// Returns allocated size.
virtual size_t Size() = 0;
// Returns size of objects. Can differ from the allocated size
// (e.g. see LargeObjectSpace).
virtual size_t SizeOfObjects() { return Size(); }
// Approximate amount of physical memory committed for this space.
virtual size_t CommittedPhysicalMemory() = 0;
// Return the available bytes without growing.
virtual size_t Available() = 0;
virtual int RoundSizeDownToObjectAlignment(int size) {
if (id_ == CODE_SPACE) {
return RoundDown(size, kCodeAlignment);
} else {
return RoundDown(size, kTaggedSize);
}
}
virtual std::unique_ptr<ObjectIterator> GetObjectIterator() = 0;
void AccountCommitted(size_t bytes) {
DCHECK_GE(committed_ + bytes, committed_);
committed_ += bytes;
if (committed_ > max_committed_) {
max_committed_ = committed_;
}
}
void AccountUncommitted(size_t bytes) {
DCHECK_GE(committed_, committed_ - bytes);
committed_ -= bytes;
}
inline void IncrementExternalBackingStoreBytes(ExternalBackingStoreType type,
size_t amount);
inline void DecrementExternalBackingStoreBytes(ExternalBackingStoreType type,
size_t amount);
// Returns amount of off-heap memory in-use by objects in this Space.
virtual size_t ExternalBackingStoreBytes(
ExternalBackingStoreType type) const {
return external_backing_store_bytes_[type];
}
void* GetRandomMmapAddr();
MemoryChunk* first_page() { return memory_chunk_list_.front(); }
MemoryChunk* last_page() { return memory_chunk_list_.back(); }
base::List<MemoryChunk>& memory_chunk_list() { return memory_chunk_list_; }
FreeList* free_list() { return free_list_.get(); }
#ifdef DEBUG
virtual void Print() = 0;
#endif
protected:
intptr_t GetNextInlineAllocationStepSize();
bool AllocationObserversActive() {
return !allocation_observers_paused_ && !allocation_observers_.empty();
}
void DetachFromHeap() { heap_ = nullptr; }
std::vector<AllocationObserver*> allocation_observers_;
// The List manages the pages that belong to the given space.
base::List<MemoryChunk> memory_chunk_list_;
// Tracks off-heap memory used by this space.
std::atomic<size_t>* external_backing_store_bytes_;
static const intptr_t kIdOffset = 9 * kSystemPointerSize;
bool allocation_observers_paused_;
Heap* heap_;
AllocationSpace id_;
// Keeps track of committed memory in a space.
size_t committed_;
size_t max_committed_;
std::unique_ptr<FreeList> free_list_;
DISALLOW_COPY_AND_ASSIGN(Space);
};
// The CodeObjectRegistry holds all start addresses of code objects of a given // The CodeObjectRegistry holds all start addresses of code objects of a given
// MemoryChunk. Each MemoryChunk owns a separate CodeObjectRegistry. The // MemoryChunk. Each MemoryChunk owns a separate CodeObjectRegistry. The
// CodeObjectRegistry allows fast lookup from an inner pointer of a code object // CodeObjectRegistry allows fast lookup from an inner pointer of a code object
...@@ -421,8 +694,7 @@ class MemoryChunk { ...@@ -421,8 +694,7 @@ class MemoryChunk {
+ kSizetSize // size_t allocated_bytes_ + kSizetSize // size_t allocated_bytes_
+ kSizetSize // size_t wasted_memory_ + kSizetSize // size_t wasted_memory_
+ kSystemPointerSize * 2 // base::ListNode + kSystemPointerSize * 2 // base::ListNode
+ kSystemPointerSize * kNumberOfCategories + kSystemPointerSize // FreeListCategory** categories__
// FreeListCategory categories_[kNumberOfCategories]
+ kSystemPointerSize // LocalArrayBufferTracker* local_tracker_ + kSystemPointerSize // LocalArrayBufferTracker* local_tracker_
+ kIntptrSize // std::atomic<intptr_t> young_generation_live_byte_count_ + kIntptrSize // std::atomic<intptr_t> young_generation_live_byte_count_
+ kSystemPointerSize // Bitmap* young_generation_bitmap_ + kSystemPointerSize // Bitmap* young_generation_bitmap_
...@@ -720,6 +992,8 @@ class MemoryChunk { ...@@ -720,6 +992,8 @@ class MemoryChunk {
CodeObjectRegistry* GetCodeObjectRegistry() { return code_object_registry_; } CodeObjectRegistry* GetCodeObjectRegistry() { return code_object_registry_; }
FreeList* free_list() { return owner()->free_list(); }
protected: protected:
static MemoryChunk* Initialize(Heap* heap, Address base, size_t size, static MemoryChunk* Initialize(Heap* heap, Address base, size_t size,
Address area_start, Address area_end, Address area_start, Address area_end,
...@@ -823,7 +1097,7 @@ class MemoryChunk { ...@@ -823,7 +1097,7 @@ class MemoryChunk {
base::ListNode<MemoryChunk> list_node_; base::ListNode<MemoryChunk> list_node_;
FreeListCategory* categories_[kNumberOfCategories]; FreeListCategory** categories_;
LocalArrayBufferTracker* local_tracker_; LocalArrayBufferTracker* local_tracker_;
...@@ -850,7 +1124,7 @@ class MemoryChunk { ...@@ -850,7 +1124,7 @@ class MemoryChunk {
STATIC_ASSERT(sizeof(std::atomic<intptr_t>) == kSystemPointerSize); STATIC_ASSERT(sizeof(std::atomic<intptr_t>) == kSystemPointerSize);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// A page is a memory chunk of a size 512K. Large object pages may be larger. // A page is a memory chunk of a size 256K. Large object pages may be larger.
// //
// The only way to get a page pointer is by calling factory methods: // The only way to get a page pointer is by calling factory methods:
// Page* p = Page::FromAddress(addr); or // Page* p = Page::FromAddress(addr); or
...@@ -904,7 +1178,7 @@ class Page : public MemoryChunk { ...@@ -904,7 +1178,7 @@ class Page : public MemoryChunk {
template <typename Callback> template <typename Callback>
inline void ForAllFreeListCategories(Callback callback) { inline void ForAllFreeListCategories(Callback callback) {
for (int i = kFirstCategory; i < kNumberOfCategories; i++) { for (int i = kFirstCategory; i < free_list()->number_of_categories(); i++) {
callback(categories_[i]); callback(categories_[i]);
} }
} }
...@@ -1017,153 +1291,6 @@ class LargePage : public MemoryChunk { ...@@ -1017,153 +1291,6 @@ class LargePage : public MemoryChunk {
friend class MemoryAllocator; friend class MemoryAllocator;
}; };
// ----------------------------------------------------------------------------
// Space is the abstract superclass for all allocation spaces.
class V8_EXPORT_PRIVATE Space : public Malloced {
public:
Space(Heap* heap, AllocationSpace id)
: allocation_observers_paused_(false),
heap_(heap),
id_(id),
committed_(0),
max_committed_(0) {
external_backing_store_bytes_ =
new std::atomic<size_t>[ExternalBackingStoreType::kNumTypes];
external_backing_store_bytes_[ExternalBackingStoreType::kArrayBuffer] = 0;
external_backing_store_bytes_[ExternalBackingStoreType::kExternalString] =
0;
CheckOffsetsAreConsistent();
}
void CheckOffsetsAreConsistent() const;
static inline void MoveExternalBackingStoreBytes(
ExternalBackingStoreType type, Space* from, Space* to, size_t amount);
virtual ~Space() {
delete[] external_backing_store_bytes_;
external_backing_store_bytes_ = nullptr;
}
Heap* heap() const {
DCHECK_NOT_NULL(heap_);
return heap_;
}
bool IsDetached() const { return heap_ == nullptr; }
AllocationSpace identity() { return id_; }
const char* name() { return Heap::GetSpaceName(id_); }
virtual void AddAllocationObserver(AllocationObserver* observer);
virtual void RemoveAllocationObserver(AllocationObserver* observer);
virtual void PauseAllocationObservers();
virtual void ResumeAllocationObservers();
virtual void StartNextInlineAllocationStep() {}
void AllocationStep(int bytes_since_last, Address soon_object, int size);
// Return the total amount committed memory for this space, i.e., allocatable
// memory and page headers.
virtual size_t CommittedMemory() { return committed_; }
virtual size_t MaximumCommittedMemory() { return max_committed_; }
// Returns allocated size.
virtual size_t Size() = 0;
// Returns size of objects. Can differ from the allocated size
// (e.g. see LargeObjectSpace).
virtual size_t SizeOfObjects() { return Size(); }
// Approximate amount of physical memory committed for this space.
virtual size_t CommittedPhysicalMemory() = 0;
// Return the available bytes without growing.
virtual size_t Available() = 0;
virtual int RoundSizeDownToObjectAlignment(int size) {
if (id_ == CODE_SPACE) {
return RoundDown(size, kCodeAlignment);
} else {
return RoundDown(size, kTaggedSize);
}
}
virtual std::unique_ptr<ObjectIterator> GetObjectIterator() = 0;
void AccountCommitted(size_t bytes) {
DCHECK_GE(committed_ + bytes, committed_);
committed_ += bytes;
if (committed_ > max_committed_) {
max_committed_ = committed_;
}
}
void AccountUncommitted(size_t bytes) {
DCHECK_GE(committed_, committed_ - bytes);
committed_ -= bytes;
}
inline void IncrementExternalBackingStoreBytes(ExternalBackingStoreType type,
size_t amount);
inline void DecrementExternalBackingStoreBytes(ExternalBackingStoreType type,
size_t amount);
// Returns amount of off-heap memory in-use by objects in this Space.
virtual size_t ExternalBackingStoreBytes(
ExternalBackingStoreType type) const {
return external_backing_store_bytes_[type];
}
void* GetRandomMmapAddr();
MemoryChunk* first_page() { return memory_chunk_list_.front(); }
MemoryChunk* last_page() { return memory_chunk_list_.back(); }
base::List<MemoryChunk>& memory_chunk_list() { return memory_chunk_list_; }
#ifdef DEBUG
virtual void Print() = 0;
#endif
protected:
intptr_t GetNextInlineAllocationStepSize();
bool AllocationObserversActive() {
return !allocation_observers_paused_ && !allocation_observers_.empty();
}
void DetachFromHeap() { heap_ = nullptr; }
std::vector<AllocationObserver*> allocation_observers_;
// The List manages the pages that belong to the given space.
base::List<MemoryChunk> memory_chunk_list_;
// Tracks off-heap memory used by this space.
std::atomic<size_t>* external_backing_store_bytes_;
private:
static const intptr_t kIdOffset = 9 * kSystemPointerSize;
bool allocation_observers_paused_;
Heap* heap_;
AllocationSpace id_;
// Keeps track of committed memory in a space.
size_t committed_;
size_t max_committed_;
DISALLOW_COPY_AND_ASSIGN(Space);
};
class MemoryChunkValidator { class MemoryChunkValidator {
// Computed offsets should match the compiler generated ones. // Computed offsets should match the compiler generated ones.
STATIC_ASSERT(MemoryChunk::kSizeOffset == offsetof(MemoryChunk, size_)); STATIC_ASSERT(MemoryChunk::kSizeOffset == offsetof(MemoryChunk, size_));
...@@ -1792,13 +1919,6 @@ class AllocationStats { ...@@ -1792,13 +1919,6 @@ class AllocationStats {
#endif #endif
}; };
// A free list maintaining free blocks of memory. The free list is organized in
// a way to encourage objects allocated around the same time to be near each
// other. The normal way to allocate is intended to be by bumping a 'top'
// pointer until it hits a 'limit' pointer. When the limit is hit we need to
// find a new space to allocate from. This is done with the free list, which is
// divided up into rough categories to cut down on waste. Having finer
// categories would scatter allocation more.
// The free list is organized in categories as follows: // The free list is organized in categories as follows:
// kMinBlockSize-10 words (tiniest): The tiniest blocks are only used for // kMinBlockSize-10 words (tiniest): The tiniest blocks are only used for
...@@ -1813,11 +1933,11 @@ class AllocationStats { ...@@ -1813,11 +1933,11 @@ class AllocationStats {
// words in size. // words in size.
// At least 16384 words (huge): This list is for objects of 2048 words or // At least 16384 words (huge): This list is for objects of 2048 words or
// larger. Empty pages are also added to this list. // larger. Empty pages are also added to this list.
class FreeList { class V8_EXPORT_PRIVATE FreeListLegacy : public FreeList {
public: public:
// This method returns how much memory can be allocated after freeing // This method returns how much memory can be allocated after freeing
// maximum_freed memory. // maximum_freed memory.
static inline size_t GuaranteedAllocatable(size_t maximum_freed) { size_t GuaranteedAllocatable(size_t maximum_freed) override {
if (maximum_freed <= kTiniestListMax) { if (maximum_freed <= kTiniestListMax) {
// Since we are not iterating over all list entries, we cannot guarantee // Since we are not iterating over all list entries, we cannot guarantee
// that we can find the maximum freed block in that free list. // that we can find the maximum freed block in that free list.
...@@ -1834,7 +1954,7 @@ class FreeList { ...@@ -1834,7 +1954,7 @@ class FreeList {
return maximum_freed; return maximum_freed;
} }
static FreeListCategoryType SelectFreeListCategoryType(size_t size_in_bytes) { FreeListCategoryType SelectFreeListCategoryType(size_t size_in_bytes) {
if (size_in_bytes <= kTiniestListMax) { if (size_in_bytes <= kTiniestListMax) {
return kTiniest; return kTiniest;
} else if (size_in_bytes <= kTinyListMax) { } else if (size_in_bytes <= kTinyListMax) {
...@@ -1849,7 +1969,25 @@ class FreeList { ...@@ -1849,7 +1969,25 @@ class FreeList {
return kHuge; return kHuge;
} }
FreeList(); Page* GetPageForSize(size_t size_in_bytes) override {
const int minimum_category =
static_cast<int>(SelectFreeListCategoryType(size_in_bytes));
Page* page = GetPageForCategoryType(kHuge);
if (!page && static_cast<int>(kLarge) >= minimum_category)
page = GetPageForCategoryType(kLarge);
if (!page && static_cast<int>(kMedium) >= minimum_category)
page = GetPageForCategoryType(kMedium);
if (!page && static_cast<int>(kSmall) >= minimum_category)
page = GetPageForCategoryType(kSmall);
if (!page && static_cast<int>(kTiny) >= minimum_category)
page = GetPageForCategoryType(kTiny);
if (!page && static_cast<int>(kTiniest) >= minimum_category)
page = GetPageForCategoryType(kTiniest);
return page;
}
FreeListLegacy();
~FreeListLegacy();
// Adds a node on the free list. The block of size {size_in_bytes} starting // Adds a node on the free list. The block of size {size_in_bytes} starting
// at {start} is placed on the free list. The return value is the number of // at {start} is placed on the free list. The return value is the number of
...@@ -1857,92 +1995,18 @@ class FreeList { ...@@ -1857,92 +1995,18 @@ class FreeList {
// was too small. Bookkeeping information will be written to the block, i.e., // was too small. Bookkeeping information will be written to the block, i.e.,
// its contents will be destroyed. The start address should be word aligned, // its contents will be destroyed. The start address should be word aligned,
// and the size should be a non-zero multiple of the word size. // and the size should be a non-zero multiple of the word size.
size_t Free(Address start, size_t size_in_bytes, FreeMode mode); size_t Free(Address start, size_t size_in_bytes, FreeMode mode) override;
// Allocates a free space node frome the free list of at least size_in_bytes // Allocates a free space node frome the free list of at least size_in_bytes
// bytes. Returns the actual node size in node_size which can be bigger than // bytes. Returns the actual node size in node_size which can be bigger than
// size_in_bytes. This method returns null if the allocation request cannot be // size_in_bytes. This method returns null if the allocation request cannot be
// handled by the free list. // handled by the free list.
V8_WARN_UNUSED_RESULT FreeSpace Allocate(size_t size_in_bytes, V8_WARN_UNUSED_RESULT FreeSpace Allocate(size_t size_in_bytes,
size_t* node_size); size_t* node_size) override;
// Clear the free list.
void Reset();
// Return the number of bytes available on the free list.
size_t Available() {
size_t available = 0;
ForAllFreeListCategories([&available](FreeListCategory* category) {
available += category->available();
});
return available;
}
bool IsEmpty() {
bool empty = true;
ForAllFreeListCategories([&empty](FreeListCategory* category) {
if (!category->is_empty()) empty = false;
});
return empty;
}
// Used after booting the VM.
void RepairLists(Heap* heap);
V8_EXPORT_PRIVATE size_t EvictFreeListItems(Page* page);
bool ContainsPageFreeListItems(Page* page);
size_t wasted_bytes() { return wasted_bytes_; }
template <typename Callback>
void ForAllFreeListCategories(FreeListCategoryType type, Callback callback) {
FreeListCategory* current = categories_[type];
while (current != nullptr) {
FreeListCategory* next = current->next();
callback(current);
current = next;
}
}
template <typename Callback>
void ForAllFreeListCategories(Callback callback) {
for (int i = kFirstCategory; i < kNumberOfCategories; i++) {
ForAllFreeListCategories(static_cast<FreeListCategoryType>(i), callback);
}
}
bool AddCategory(FreeListCategory* category);
V8_EXPORT_PRIVATE void RemoveCategory(FreeListCategory* category);
void PrintCategories(FreeListCategoryType type);
// Returns a page containing an entry for a given type, or nullptr otherwise.
inline Page* GetPageForCategoryType(FreeListCategoryType type);
#ifdef DEBUG
size_t SumFreeLists();
bool IsVeryLong();
#endif
private: private:
class FreeListCategoryIterator { enum { kTiniest, kTiny, kSmall, kMedium, kLarge, kHuge };
public:
FreeListCategoryIterator(FreeList* free_list, FreeListCategoryType type)
: current_(free_list->categories_[type]) {}
bool HasNext() { return current_ != nullptr; }
FreeListCategory* Next() {
DCHECK(HasNext());
FreeListCategory* tmp = current_;
current_ = current_->next();
return tmp;
}
private:
FreeListCategory* current_;
};
// The size range of blocks, in bytes.
static const size_t kMinBlockSize = 3 * kTaggedSize; static const size_t kMinBlockSize = 3 * kTaggedSize;
// This is a conservative upper bound. The actual maximum block size takes // This is a conservative upper bound. The actual maximum block size takes
...@@ -1982,13 +2046,10 @@ class FreeList { ...@@ -1982,13 +2046,10 @@ class FreeList {
return kHuge; return kHuge;
} }
FreeListCategory* top(FreeListCategoryType type) const { Page* GetPageForCategoryType(FreeListCategoryType type) {
return categories_[type]; return top(type) ? top(type)->page() : nullptr;
} }
std::atomic<size_t> wasted_bytes_;
FreeListCategory* categories_[kNumberOfCategories];
friend class FreeListCategory; friend class FreeListCategory;
friend class heap::HeapTester; friend class heap::HeapTester;
}; };
...@@ -2056,8 +2117,8 @@ class LocalAllocationBuffer { ...@@ -2056,8 +2117,8 @@ class LocalAllocationBuffer {
class SpaceWithLinearArea : public Space { class SpaceWithLinearArea : public Space {
public: public:
SpaceWithLinearArea(Heap* heap, AllocationSpace id) SpaceWithLinearArea(Heap* heap, AllocationSpace id, FreeList* free_list)
: Space(heap, id), top_on_previous_step_(0) { : Space(heap, id, free_list), top_on_previous_step_(0) {
allocation_info_.Reset(kNullAddress, kNullAddress); allocation_info_.Reset(kNullAddress, kNullAddress);
} }
...@@ -2118,7 +2179,8 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -2118,7 +2179,8 @@ class V8_EXPORT_PRIVATE PagedSpace
static const size_t kCompactionMemoryWanted = 500 * KB; static const size_t kCompactionMemoryWanted = 500 * KB;
// Creates a space with an id. // Creates a space with an id.
PagedSpace(Heap* heap, AllocationSpace id, Executability executable); PagedSpace(Heap* heap, AllocationSpace id, Executability executable,
FreeList* free_list);
~PagedSpace() override { TearDown(); } ~PagedSpace() override { TearDown(); }
...@@ -2146,14 +2208,14 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -2146,14 +2208,14 @@ class V8_EXPORT_PRIVATE PagedSpace
// to the available and wasted totals. The free list is cleared as well. // to the available and wasted totals. The free list is cleared as well.
void ClearAllocatorState() { void ClearAllocatorState() {
accounting_stats_.ClearSize(); accounting_stats_.ClearSize();
free_list_.Reset(); free_list_->Reset();
} }
// Available bytes without growing. These are the bytes on the free list. // Available bytes without growing. These are the bytes on the free list.
// The bytes in the linear allocation area are not included in this total // The bytes in the linear allocation area are not included in this total
// because updating the stats would slow down allocation. New pages are // because updating the stats would slow down allocation. New pages are
// immediately added to the free list so they show up here. // immediately added to the free list so they show up here.
size_t Available() override { return free_list_.Available(); } size_t Available() override { return free_list_->Available(); }
// Allocated bytes in this space. Garbage bytes that were not found due to // Allocated bytes in this space. Garbage bytes that were not found due to
// concurrent sweeping are counted as being allocated! The bytes in the // concurrent sweeping are counted as being allocated! The bytes in the
...@@ -2167,7 +2229,7 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -2167,7 +2229,7 @@ class V8_EXPORT_PRIVATE PagedSpace
// Wasted bytes in this space. These are just the bytes that were thrown away // Wasted bytes in this space. These are just the bytes that were thrown away
// due to being too small to use for allocation. // due to being too small to use for allocation.
virtual size_t Waste() { return free_list_.wasted_bytes(); } virtual size_t Waste() { return free_list_->wasted_bytes(); }
// Allocate the requested number of bytes in the space if possible, return a // Allocate the requested number of bytes in the space if possible, return a
// failure object if not. // failure object if not.
...@@ -2200,7 +2262,7 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -2200,7 +2262,7 @@ class V8_EXPORT_PRIVATE PagedSpace
// If add_to_freelist is false then just accounting stats are updated and // If add_to_freelist is false then just accounting stats are updated and
// no attempt to add area to free list is made. // no attempt to add area to free list is made.
size_t AccountedFree(Address start, size_t size_in_bytes) { size_t AccountedFree(Address start, size_t size_in_bytes) {
size_t wasted = free_list_.Free(start, size_in_bytes, kLinkCategory); size_t wasted = free_list_->Free(start, size_in_bytes, kLinkCategory);
Page* page = Page::FromAddress(start); Page* page = Page::FromAddress(start);
accounting_stats_.DecreaseAllocatedBytes(size_in_bytes, page); accounting_stats_.DecreaseAllocatedBytes(size_in_bytes, page);
DCHECK_GE(size_in_bytes, wasted); DCHECK_GE(size_in_bytes, wasted);
...@@ -2208,7 +2270,7 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -2208,7 +2270,7 @@ class V8_EXPORT_PRIVATE PagedSpace
} }
size_t UnaccountedFree(Address start, size_t size_in_bytes) { size_t UnaccountedFree(Address start, size_t size_in_bytes) {
size_t wasted = free_list_.Free(start, size_in_bytes, kDoNotLinkCategory); size_t wasted = free_list_->Free(start, size_in_bytes, kDoNotLinkCategory);
DCHECK_GE(size_in_bytes, wasted); DCHECK_GE(size_in_bytes, wasted);
return size_in_bytes - wasted; return size_in_bytes - wasted;
} }
...@@ -2302,8 +2364,6 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -2302,8 +2364,6 @@ class V8_EXPORT_PRIVATE PagedSpace
// sweeper. // sweeper.
virtual void RefillFreeList(); virtual void RefillFreeList();
FreeList* free_list() { return &free_list_; }
base::Mutex* mutex() { return &space_mutex_; } base::Mutex* mutex() { return &space_mutex_; }
inline void UnlinkFreeListCategories(Page* page); inline void UnlinkFreeListCategories(Page* page);
...@@ -2395,9 +2455,6 @@ class V8_EXPORT_PRIVATE PagedSpace ...@@ -2395,9 +2455,6 @@ class V8_EXPORT_PRIVATE PagedSpace
// Accounting information for this space. // Accounting information for this space.
AllocationStats accounting_stats_; AllocationStats accounting_stats_;
// The space's free list.
FreeList free_list_;
// Mutex guarding any concurrent access to the space. // Mutex guarding any concurrent access to the space.
base::Mutex space_mutex_; base::Mutex space_mutex_;
...@@ -2423,7 +2480,7 @@ class SemiSpace : public Space { ...@@ -2423,7 +2480,7 @@ class SemiSpace : public Space {
static void Swap(SemiSpace* from, SemiSpace* to); static void Swap(SemiSpace* from, SemiSpace* to);
SemiSpace(Heap* heap, SemiSpaceId semispace) SemiSpace(Heap* heap, SemiSpaceId semispace)
: Space(heap, NEW_SPACE), : Space(heap, NEW_SPACE, new NoFreeList()),
current_capacity_(0), current_capacity_(0),
maximum_capacity_(0), maximum_capacity_(0),
minimum_capacity_(0), minimum_capacity_(0),
...@@ -2866,7 +2923,7 @@ class V8_EXPORT_PRIVATE PauseAllocationObserversScope { ...@@ -2866,7 +2923,7 @@ class V8_EXPORT_PRIVATE PauseAllocationObserversScope {
class V8_EXPORT_PRIVATE CompactionSpace : public PagedSpace { class V8_EXPORT_PRIVATE CompactionSpace : public PagedSpace {
public: public:
CompactionSpace(Heap* heap, AllocationSpace id, Executability executable) CompactionSpace(Heap* heap, AllocationSpace id, Executability executable)
: PagedSpace(heap, id, executable) {} : PagedSpace(heap, id, executable, FreeList::CreateFreeList()) {}
bool is_local() override { return true; } bool is_local() override { return true; }
...@@ -2912,7 +2969,9 @@ class OldSpace : public PagedSpace { ...@@ -2912,7 +2969,9 @@ class OldSpace : public PagedSpace {
public: public:
// Creates an old space object. The constructor does not allocate pages // Creates an old space object. The constructor does not allocate pages
// from OS. // from OS.
explicit OldSpace(Heap* heap) : PagedSpace(heap, OLD_SPACE, NOT_EXECUTABLE) {} explicit OldSpace(Heap* heap)
: PagedSpace(heap, OLD_SPACE, NOT_EXECUTABLE,
FreeList::CreateFreeList()) {}
static bool IsAtPageStart(Address addr) { static bool IsAtPageStart(Address addr) {
return static_cast<intptr_t>(addr & kPageAlignmentMask) == return static_cast<intptr_t>(addr & kPageAlignmentMask) ==
...@@ -2927,7 +2986,8 @@ class CodeSpace : public PagedSpace { ...@@ -2927,7 +2986,8 @@ class CodeSpace : public PagedSpace {
public: public:
// Creates an old space object. The constructor does not allocate pages // Creates an old space object. The constructor does not allocate pages
// from OS. // from OS.
explicit CodeSpace(Heap* heap) : PagedSpace(heap, CODE_SPACE, EXECUTABLE) {} explicit CodeSpace(Heap* heap)
: PagedSpace(heap, CODE_SPACE, EXECUTABLE, FreeList::CreateFreeList()) {}
}; };
// For contiguous spaces, top should be in the space (or at the end) and limit // For contiguous spaces, top should be in the space (or at the end) and limit
...@@ -2944,7 +3004,9 @@ class CodeSpace : public PagedSpace { ...@@ -2944,7 +3004,9 @@ class CodeSpace : public PagedSpace {
class MapSpace : public PagedSpace { class MapSpace : public PagedSpace {
public: public:
// Creates a map space object. // Creates a map space object.
explicit MapSpace(Heap* heap) : PagedSpace(heap, MAP_SPACE, NOT_EXECUTABLE) {} explicit MapSpace(Heap* heap)
: PagedSpace(heap, MAP_SPACE, NOT_EXECUTABLE,
FreeList::CreateFreeList()) {}
int RoundSizeDownToObjectAlignment(int size) override { int RoundSizeDownToObjectAlignment(int size) override {
if (base::bits::IsPowerOfTwo(Map::kSize)) { if (base::bits::IsPowerOfTwo(Map::kSize)) {
......
...@@ -370,7 +370,9 @@ int Sweeper::RawSweep(Page* p, FreeListRebuildingMode free_list_mode, ...@@ -370,7 +370,9 @@ int Sweeper::RawSweep(Page* p, FreeListRebuildingMode free_list_mode,
p->set_concurrent_sweeping_state(Page::kSweepingDone); p->set_concurrent_sweeping_state(Page::kSweepingDone);
if (code_object_registry) code_object_registry->Finalize(); if (code_object_registry) code_object_registry->Finalize();
if (free_list_mode == IGNORE_FREE_LIST) return 0; if (free_list_mode == IGNORE_FREE_LIST) return 0;
return static_cast<int>(FreeList::GuaranteedAllocatable(max_freed_bytes));
return static_cast<int>(
p->free_list()->GuaranteedAllocatable(max_freed_bytes));
} }
void Sweeper::SweepSpaceFromTask(AllocationSpace identity) { void Sweeper::SweepSpaceFromTask(AllocationSpace identity) {
......
...@@ -52,9 +52,7 @@ ...@@ -52,9 +52,7 @@
V(Regress791582) \ V(Regress791582) \
V(Regress845060) \ V(Regress845060) \
V(RegressMissingWriteBarrierInAllocate) \ V(RegressMissingWriteBarrierInAllocate) \
V(WriteBarriersInCopyJSObject) \ V(WriteBarriersInCopyJSObject)
V(AllocateObjTinyFreeList) \
V(EmptyFreeListCategoriesRemoved)
#define HEAP_TEST(Name) \ #define HEAP_TEST(Name) \
CcTest register_test_##Name(v8::internal::heap::HeapTester::Test##Name, \ CcTest register_test_##Name(v8::internal::heap::HeapTester::Test##Name, \
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/heap/spaces-inl.h" #include "src/heap/spaces-inl.h"
#include "src/heap/spaces.h"
#include "src/objects/free-space.h" #include "src/objects/free-space.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
...@@ -741,103 +742,6 @@ TEST(ShrinkPageToHighWaterMarkTwoWordFiller) { ...@@ -741,103 +742,6 @@ TEST(ShrinkPageToHighWaterMarkTwoWordFiller) {
CHECK_EQ(0u, shrunk); CHECK_EQ(0u, shrunk);
} }
HEAP_TEST(AllocateObjTinyFreeList) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
heap::SealCurrentObjects(CcTest::heap());
// tinyObjPage will contain the page that contains the tiny object.
Page* tiny_obj_page;
{
// Allocates a tiny object (ie, that fits in the Tiny freelist).
// It will go at the begining of a page.
// Note that the handlescope is locally scoped.
{
HandleScope tiny_scope(isolate);
size_t tiny_obj_size =
(FreeList::kTinyListMax - FixedArray::kHeaderSize) / kTaggedSize;
Handle<FixedArray> tiny_obj = isolate->factory()->NewFixedArray(
static_cast<int>(tiny_obj_size), AllocationType::kOld);
// Remember the page of this tiny object.
tiny_obj_page = Page::FromHeapObject(*tiny_obj);
}
// Fill up the page entirely.
PagedSpace* old_space = CcTest::heap()->old_space();
int space_remaining =
static_cast<int>(*old_space->allocation_limit_address() -
*old_space->allocation_top_address());
std::vector<Handle<FixedArray>> handles = heap::CreatePadding(
old_space->heap(), space_remaining, AllocationType::kOld);
// Checking that the new objects were indeed allocated on the same page
// as the tiny one.
CHECK_EQ(tiny_obj_page, Page::FromHeapObject(*(handles.back())));
}
// Call gc to reclain tinyObj (since its HandleScope went out of scope).
CcTest::CollectAllGarbage();
isolate->heap()->mark_compact_collector()->EnsureSweepingCompleted();
isolate->heap()->old_space()->FreeLinearAllocationArea();
// Now allocate a tyniest object.
// It should go at the same place as the previous one.
size_t tiniest_obj_size =
(FreeList::kTiniestListMax - FixedArray::kHeaderSize) / kTaggedSize;
Handle<FixedArray> tiniest_obj = isolate->factory()->NewFixedArray(
static_cast<int>(tiniest_obj_size), AllocationType::kOld);
// Check that the new tiny object is in the same page as the previous one.
Page* tiniest_obj_page = Page::FromHeapObject(*tiniest_obj);
CHECK_EQ(tiny_obj_page, tiniest_obj_page);
}
HEAP_TEST(EmptyFreeListCategoriesRemoved) {
ManualGCScope manual_gc_scope;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
heap::SealCurrentObjects(CcTest::heap());
// The maximum size for a Tiny FixedArray.
// (there is no specific reason for using Tiny rather than any other category)
constexpr size_t tiny_obj_size =
(FreeList::kTinyListMax - FixedArray::kHeaderSize) / kTaggedSize;
Page* tiny_obj_page;
{
// Allocate a Tiny object that will be destroyed later.
HandleScope tiny_scope(isolate);
Handle<FixedArray> tiny_obj = isolate->factory()->NewFixedArray(
static_cast<int>(tiny_obj_size), AllocationType::kOld);
tiny_obj_page = Page::FromHeapObject(*tiny_obj);
}
// Fill up the page entirely.
PagedSpace* old_space = CcTest::heap()->old_space();
int space_remaining =
static_cast<int>(*old_space->allocation_limit_address() -
*old_space->allocation_top_address());
std::vector<Handle<FixedArray>> handles = heap::CreatePadding(
old_space->heap(), space_remaining, AllocationType::kOld);
// Call gc to reclaim |tiny_obj| (since its HandleScope went out of scope).
CcTest::CollectAllGarbage();
isolate->heap()->mark_compact_collector()->EnsureSweepingCompleted();
isolate->heap()->old_space()->FreeLinearAllocationArea();
// Allocates a new tiny_obj, which should take the place of the old one.
Handle<FixedArray> tiny_obj = isolate->factory()->NewFixedArray(
static_cast<int>(tiny_obj_size), AllocationType::kOld);
CHECK_EQ(tiny_obj_page, Page::FromHeapObject(*tiny_obj));
// The Tiny FreeListCategory should now be empty
CHECK_NULL(isolate->heap()->old_space()->free_list()->categories_[kTiny]);
}
} // namespace heap } // namespace heap
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -192,237 +192,237 @@ INSTANCE_TYPES = { ...@@ -192,237 +192,237 @@ INSTANCE_TYPES = {
# List of known V8 maps. # List of known V8 maps.
KNOWN_MAPS = { KNOWN_MAPS = {
("read_only_space", 0x00139): (74, "FreeSpaceMap"), ("read_only_space", 0x00111): (74, "FreeSpaceMap"),
("read_only_space", 0x00189): (68, "MetaMap"), ("read_only_space", 0x00161): (68, "MetaMap"),
("read_only_space", 0x00209): (67, "NullMap"), ("read_only_space", 0x001e1): (67, "NullMap"),
("read_only_space", 0x00271): (155, "DescriptorArrayMap"), ("read_only_space", 0x00249): (155, "DescriptorArrayMap"),
("read_only_space", 0x002d1): (150, "WeakFixedArrayMap"), ("read_only_space", 0x002a9): (150, "WeakFixedArrayMap"),
("read_only_space", 0x00321): (77, "OnePointerFillerMap"), ("read_only_space", 0x002f9): (77, "OnePointerFillerMap"),
("read_only_space", 0x00371): (77, "TwoPointerFillerMap"), ("read_only_space", 0x00349): (77, "TwoPointerFillerMap"),
("read_only_space", 0x003f1): (67, "UninitializedMap"), ("read_only_space", 0x003c9): (67, "UninitializedMap"),
("read_only_space", 0x00461): (8, "OneByteInternalizedStringMap"), ("read_only_space", 0x00439): (8, "OneByteInternalizedStringMap"),
("read_only_space", 0x00501): (67, "UndefinedMap"), ("read_only_space", 0x004d9): (67, "UndefinedMap"),
("read_only_space", 0x00561): (65, "HeapNumberMap"), ("read_only_space", 0x00539): (65, "HeapNumberMap"),
("read_only_space", 0x005e1): (67, "TheHoleMap"), ("read_only_space", 0x005b9): (67, "TheHoleMap"),
("read_only_space", 0x00689): (67, "BooleanMap"), ("read_only_space", 0x00661): (67, "BooleanMap"),
("read_only_space", 0x00761): (72, "ByteArrayMap"), ("read_only_space", 0x00739): (72, "ByteArrayMap"),
("read_only_space", 0x007b1): (125, "FixedArrayMap"), ("read_only_space", 0x00789): (125, "FixedArrayMap"),
("read_only_space", 0x00801): (125, "FixedCOWArrayMap"), ("read_only_space", 0x007d9): (125, "FixedCOWArrayMap"),
("read_only_space", 0x00851): (128, "HashTableMap"), ("read_only_space", 0x00829): (128, "HashTableMap"),
("read_only_space", 0x008a1): (64, "SymbolMap"), ("read_only_space", 0x00879): (64, "SymbolMap"),
("read_only_space", 0x008f1): (40, "OneByteStringMap"), ("read_only_space", 0x008c9): (40, "OneByteStringMap"),
("read_only_space", 0x00941): (138, "ScopeInfoMap"), ("read_only_space", 0x00919): (138, "ScopeInfoMap"),
("read_only_space", 0x00991): (162, "SharedFunctionInfoMap"), ("read_only_space", 0x00969): (162, "SharedFunctionInfoMap"),
("read_only_space", 0x009e1): (69, "CodeMap"), ("read_only_space", 0x009b9): (69, "CodeMap"),
("read_only_space", 0x00a31): (145, "FunctionContextMap"), ("read_only_space", 0x00a09): (145, "FunctionContextMap"),
("read_only_space", 0x00a81): (153, "CellMap"), ("read_only_space", 0x00a59): (153, "CellMap"),
("read_only_space", 0x00ad1): (161, "GlobalPropertyCellMap"), ("read_only_space", 0x00aa9): (161, "GlobalPropertyCellMap"),
("read_only_space", 0x00b21): (71, "ForeignMap"), ("read_only_space", 0x00af9): (71, "ForeignMap"),
("read_only_space", 0x00b71): (151, "TransitionArrayMap"), ("read_only_space", 0x00b49): (151, "TransitionArrayMap"),
("read_only_space", 0x00bc1): (157, "FeedbackVectorMap"), ("read_only_space", 0x00b99): (157, "FeedbackVectorMap"),
("read_only_space", 0x00c61): (67, "ArgumentsMarkerMap"), ("read_only_space", 0x00c39): (67, "ArgumentsMarkerMap"),
("read_only_space", 0x00d01): (67, "ExceptionMap"), ("read_only_space", 0x00cd9): (67, "ExceptionMap"),
("read_only_space", 0x00da1): (67, "TerminationExceptionMap"), ("read_only_space", 0x00d79): (67, "TerminationExceptionMap"),
("read_only_space", 0x00e49): (67, "OptimizedOutMap"), ("read_only_space", 0x00e21): (67, "OptimizedOutMap"),
("read_only_space", 0x00ee9): (67, "StaleRegisterMap"), ("read_only_space", 0x00ec1): (67, "StaleRegisterMap"),
("read_only_space", 0x00f59): (147, "NativeContextMap"), ("read_only_space", 0x00f31): (147, "NativeContextMap"),
("read_only_space", 0x00fa9): (146, "ModuleContextMap"), ("read_only_space", 0x00f81): (146, "ModuleContextMap"),
("read_only_space", 0x00ff9): (144, "EvalContextMap"), ("read_only_space", 0x00fd1): (144, "EvalContextMap"),
("read_only_space", 0x01049): (148, "ScriptContextMap"), ("read_only_space", 0x01021): (148, "ScriptContextMap"),
("read_only_space", 0x01099): (140, "AwaitContextMap"), ("read_only_space", 0x01071): (140, "AwaitContextMap"),
("read_only_space", 0x010e9): (141, "BlockContextMap"), ("read_only_space", 0x010c1): (141, "BlockContextMap"),
("read_only_space", 0x01139): (142, "CatchContextMap"), ("read_only_space", 0x01111): (142, "CatchContextMap"),
("read_only_space", 0x01189): (149, "WithContextMap"), ("read_only_space", 0x01161): (149, "WithContextMap"),
("read_only_space", 0x011d9): (143, "DebugEvaluateContextMap"), ("read_only_space", 0x011b1): (143, "DebugEvaluateContextMap"),
("read_only_space", 0x01229): (139, "ScriptContextTableMap"), ("read_only_space", 0x01201): (139, "ScriptContextTableMap"),
("read_only_space", 0x01279): (127, "ClosureFeedbackCellArrayMap"), ("read_only_space", 0x01251): (127, "ClosureFeedbackCellArrayMap"),
("read_only_space", 0x012c9): (76, "FeedbackMetadataArrayMap"), ("read_only_space", 0x012a1): (76, "FeedbackMetadataArrayMap"),
("read_only_space", 0x01319): (125, "ArrayListMap"), ("read_only_space", 0x012f1): (125, "ArrayListMap"),
("read_only_space", 0x01369): (66, "BigIntMap"), ("read_only_space", 0x01341): (66, "BigIntMap"),
("read_only_space", 0x013b9): (126, "ObjectBoilerplateDescriptionMap"), ("read_only_space", 0x01391): (126, "ObjectBoilerplateDescriptionMap"),
("read_only_space", 0x01409): (73, "BytecodeArrayMap"), ("read_only_space", 0x013e1): (73, "BytecodeArrayMap"),
("read_only_space", 0x01459): (154, "CodeDataContainerMap"), ("read_only_space", 0x01431): (154, "CodeDataContainerMap"),
("read_only_space", 0x014a9): (75, "FixedDoubleArrayMap"), ("read_only_space", 0x01481): (75, "FixedDoubleArrayMap"),
("read_only_space", 0x014f9): (133, "GlobalDictionaryMap"), ("read_only_space", 0x014d1): (133, "GlobalDictionaryMap"),
("read_only_space", 0x01549): (156, "ManyClosuresCellMap"), ("read_only_space", 0x01521): (156, "ManyClosuresCellMap"),
("read_only_space", 0x01599): (125, "ModuleInfoMap"), ("read_only_space", 0x01571): (125, "ModuleInfoMap"),
("read_only_space", 0x015e9): (70, "MutableHeapNumberMap"), ("read_only_space", 0x015c1): (70, "MutableHeapNumberMap"),
("read_only_space", 0x01639): (132, "NameDictionaryMap"), ("read_only_space", 0x01611): (132, "NameDictionaryMap"),
("read_only_space", 0x01689): (156, "NoClosuresCellMap"), ("read_only_space", 0x01661): (156, "NoClosuresCellMap"),
("read_only_space", 0x016d9): (134, "NumberDictionaryMap"), ("read_only_space", 0x016b1): (134, "NumberDictionaryMap"),
("read_only_space", 0x01729): (156, "OneClosureCellMap"), ("read_only_space", 0x01701): (156, "OneClosureCellMap"),
("read_only_space", 0x01779): (129, "OrderedHashMapMap"), ("read_only_space", 0x01751): (129, "OrderedHashMapMap"),
("read_only_space", 0x017c9): (130, "OrderedHashSetMap"), ("read_only_space", 0x017a1): (130, "OrderedHashSetMap"),
("read_only_space", 0x01819): (131, "OrderedNameDictionaryMap"), ("read_only_space", 0x017f1): (131, "OrderedNameDictionaryMap"),
("read_only_space", 0x01869): (159, "PreparseDataMap"), ("read_only_space", 0x01841): (159, "PreparseDataMap"),
("read_only_space", 0x018b9): (160, "PropertyArrayMap"), ("read_only_space", 0x01891): (160, "PropertyArrayMap"),
("read_only_space", 0x01909): (152, "SideEffectCallHandlerInfoMap"), ("read_only_space", 0x018e1): (152, "SideEffectCallHandlerInfoMap"),
("read_only_space", 0x01959): (152, "SideEffectFreeCallHandlerInfoMap"), ("read_only_space", 0x01931): (152, "SideEffectFreeCallHandlerInfoMap"),
("read_only_space", 0x019a9): (152, "NextCallSideEffectFreeCallHandlerInfoMap"), ("read_only_space", 0x01981): (152, "NextCallSideEffectFreeCallHandlerInfoMap"),
("read_only_space", 0x019f9): (135, "SimpleNumberDictionaryMap"), ("read_only_space", 0x019d1): (135, "SimpleNumberDictionaryMap"),
("read_only_space", 0x01a49): (125, "SloppyArgumentsElementsMap"), ("read_only_space", 0x01a21): (125, "SloppyArgumentsElementsMap"),
("read_only_space", 0x01a99): (163, "SmallOrderedHashMapMap"), ("read_only_space", 0x01a71): (163, "SmallOrderedHashMapMap"),
("read_only_space", 0x01ae9): (164, "SmallOrderedHashSetMap"), ("read_only_space", 0x01ac1): (164, "SmallOrderedHashSetMap"),
("read_only_space", 0x01b39): (165, "SmallOrderedNameDictionaryMap"), ("read_only_space", 0x01b11): (165, "SmallOrderedNameDictionaryMap"),
("read_only_space", 0x01b89): (121, "SourceTextModuleMap"), ("read_only_space", 0x01b61): (121, "SourceTextModuleMap"),
("read_only_space", 0x01bd9): (136, "StringTableMap"), ("read_only_space", 0x01bb1): (136, "StringTableMap"),
("read_only_space", 0x01c29): (122, "SyntheticModuleMap"), ("read_only_space", 0x01c01): (122, "SyntheticModuleMap"),
("read_only_space", 0x01c79): (167, "UncompiledDataWithoutPreparseDataMap"), ("read_only_space", 0x01c51): (167, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x01cc9): (168, "UncompiledDataWithPreparseDataMap"), ("read_only_space", 0x01ca1): (168, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x01d19): (169, "WeakArrayListMap"), ("read_only_space", 0x01cf1): (169, "WeakArrayListMap"),
("read_only_space", 0x01d69): (137, "EphemeronHashTableMap"), ("read_only_space", 0x01d41): (137, "EphemeronHashTableMap"),
("read_only_space", 0x01db9): (124, "EmbedderDataArrayMap"), ("read_only_space", 0x01d91): (124, "EmbedderDataArrayMap"),
("read_only_space", 0x01e09): (170, "WeakCellMap"), ("read_only_space", 0x01de1): (170, "WeakCellMap"),
("read_only_space", 0x01e59): (58, "NativeSourceStringMap"), ("read_only_space", 0x01e31): (58, "NativeSourceStringMap"),
("read_only_space", 0x01ea9): (32, "StringMap"), ("read_only_space", 0x01e81): (32, "StringMap"),
("read_only_space", 0x01ef9): (41, "ConsOneByteStringMap"), ("read_only_space", 0x01ed1): (41, "ConsOneByteStringMap"),
("read_only_space", 0x01f49): (33, "ConsStringMap"), ("read_only_space", 0x01f21): (33, "ConsStringMap"),
("read_only_space", 0x01f99): (45, "ThinOneByteStringMap"), ("read_only_space", 0x01f71): (45, "ThinOneByteStringMap"),
("read_only_space", 0x01fe9): (37, "ThinStringMap"), ("read_only_space", 0x01fc1): (37, "ThinStringMap"),
("read_only_space", 0x02039): (35, "SlicedStringMap"), ("read_only_space", 0x02011): (35, "SlicedStringMap"),
("read_only_space", 0x02089): (43, "SlicedOneByteStringMap"), ("read_only_space", 0x02061): (43, "SlicedOneByteStringMap"),
("read_only_space", 0x020d9): (34, "ExternalStringMap"), ("read_only_space", 0x020b1): (34, "ExternalStringMap"),
("read_only_space", 0x02129): (42, "ExternalOneByteStringMap"), ("read_only_space", 0x02101): (42, "ExternalOneByteStringMap"),
("read_only_space", 0x02179): (50, "UncachedExternalStringMap"), ("read_only_space", 0x02151): (50, "UncachedExternalStringMap"),
("read_only_space", 0x021c9): (0, "InternalizedStringMap"), ("read_only_space", 0x021a1): (0, "InternalizedStringMap"),
("read_only_space", 0x02219): (2, "ExternalInternalizedStringMap"), ("read_only_space", 0x021f1): (2, "ExternalInternalizedStringMap"),
("read_only_space", 0x02269): (10, "ExternalOneByteInternalizedStringMap"), ("read_only_space", 0x02241): (10, "ExternalOneByteInternalizedStringMap"),
("read_only_space", 0x022b9): (18, "UncachedExternalInternalizedStringMap"), ("read_only_space", 0x02291): (18, "UncachedExternalInternalizedStringMap"),
("read_only_space", 0x02309): (26, "UncachedExternalOneByteInternalizedStringMap"), ("read_only_space", 0x022e1): (26, "UncachedExternalOneByteInternalizedStringMap"),
("read_only_space", 0x02359): (58, "UncachedExternalOneByteStringMap"), ("read_only_space", 0x02331): (58, "UncachedExternalOneByteStringMap"),
("read_only_space", 0x023a9): (67, "SelfReferenceMarkerMap"), ("read_only_space", 0x02381): (67, "SelfReferenceMarkerMap"),
("read_only_space", 0x02411): (88, "EnumCacheMap"), ("read_only_space", 0x023e9): (88, "EnumCacheMap"),
("read_only_space", 0x024b1): (83, "ArrayBoilerplateDescriptionMap"), ("read_only_space", 0x02489): (83, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x026a1): (91, "InterceptorInfoMap"), ("read_only_space", 0x02679): (91, "InterceptorInfoMap"),
("read_only_space", 0x04e81): (78, "AccessCheckInfoMap"), ("read_only_space", 0x04e59): (78, "AccessCheckInfoMap"),
("read_only_space", 0x04ed1): (79, "AccessorInfoMap"), ("read_only_space", 0x04ea9): (79, "AccessorInfoMap"),
("read_only_space", 0x04f21): (80, "AccessorPairMap"), ("read_only_space", 0x04ef9): (80, "AccessorPairMap"),
("read_only_space", 0x04f71): (81, "AliasedArgumentsEntryMap"), ("read_only_space", 0x04f49): (81, "AliasedArgumentsEntryMap"),
("read_only_space", 0x04fc1): (82, "AllocationMementoMap"), ("read_only_space", 0x04f99): (82, "AllocationMementoMap"),
("read_only_space", 0x05011): (84, "AsmWasmDataMap"), ("read_only_space", 0x04fe9): (84, "AsmWasmDataMap"),
("read_only_space", 0x05061): (85, "AsyncGeneratorRequestMap"), ("read_only_space", 0x05039): (85, "AsyncGeneratorRequestMap"),
("read_only_space", 0x050b1): (86, "ClassPositionsMap"), ("read_only_space", 0x05089): (86, "ClassPositionsMap"),
("read_only_space", 0x05101): (87, "DebugInfoMap"), ("read_only_space", 0x050d9): (87, "DebugInfoMap"),
("read_only_space", 0x05151): (89, "FunctionTemplateInfoMap"), ("read_only_space", 0x05129): (89, "FunctionTemplateInfoMap"),
("read_only_space", 0x051a1): (90, "FunctionTemplateRareDataMap"), ("read_only_space", 0x05179): (90, "FunctionTemplateRareDataMap"),
("read_only_space", 0x051f1): (92, "InterpreterDataMap"), ("read_only_space", 0x051c9): (92, "InterpreterDataMap"),
("read_only_space", 0x05241): (93, "ObjectTemplateInfoMap"), ("read_only_space", 0x05219): (93, "ObjectTemplateInfoMap"),
("read_only_space", 0x05291): (94, "PromiseCapabilityMap"), ("read_only_space", 0x05269): (94, "PromiseCapabilityMap"),
("read_only_space", 0x052e1): (95, "PromiseReactionMap"), ("read_only_space", 0x052b9): (95, "PromiseReactionMap"),
("read_only_space", 0x05331): (96, "PrototypeInfoMap"), ("read_only_space", 0x05309): (96, "PrototypeInfoMap"),
("read_only_space", 0x05381): (97, "ScriptMap"), ("read_only_space", 0x05359): (97, "ScriptMap"),
("read_only_space", 0x053d1): (98, "SourcePositionTableWithFrameCacheMap"), ("read_only_space", 0x053a9): (98, "SourcePositionTableWithFrameCacheMap"),
("read_only_space", 0x05421): (99, "SourceTextModuleInfoEntryMap"), ("read_only_space", 0x053f9): (99, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x05471): (100, "StackFrameInfoMap"), ("read_only_space", 0x05449): (100, "StackFrameInfoMap"),
("read_only_space", 0x054c1): (101, "StackTraceFrameMap"), ("read_only_space", 0x05499): (101, "StackTraceFrameMap"),
("read_only_space", 0x05511): (102, "TemplateObjectDescriptionMap"), ("read_only_space", 0x054e9): (102, "TemplateObjectDescriptionMap"),
("read_only_space", 0x05561): (103, "Tuple2Map"), ("read_only_space", 0x05539): (103, "Tuple2Map"),
("read_only_space", 0x055b1): (104, "Tuple3Map"), ("read_only_space", 0x05589): (104, "Tuple3Map"),
("read_only_space", 0x05601): (105, "WasmCapiFunctionDataMap"), ("read_only_space", 0x055d9): (105, "WasmCapiFunctionDataMap"),
("read_only_space", 0x05651): (106, "WasmDebugInfoMap"), ("read_only_space", 0x05629): (106, "WasmDebugInfoMap"),
("read_only_space", 0x056a1): (107, "WasmExceptionTagMap"), ("read_only_space", 0x05679): (107, "WasmExceptionTagMap"),
("read_only_space", 0x056f1): (108, "WasmExportedFunctionDataMap"), ("read_only_space", 0x056c9): (108, "WasmExportedFunctionDataMap"),
("read_only_space", 0x05741): (109, "WasmIndirectFunctionTableMap"), ("read_only_space", 0x05719): (109, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x05791): (110, "WasmJSFunctionDataMap"), ("read_only_space", 0x05769): (110, "WasmJSFunctionDataMap"),
("read_only_space", 0x057e1): (111, "CallableTaskMap"), ("read_only_space", 0x057b9): (111, "CallableTaskMap"),
("read_only_space", 0x05831): (112, "CallbackTaskMap"), ("read_only_space", 0x05809): (112, "CallbackTaskMap"),
("read_only_space", 0x05881): (113, "PromiseFulfillReactionJobTaskMap"), ("read_only_space", 0x05859): (113, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x058d1): (114, "PromiseRejectReactionJobTaskMap"), ("read_only_space", 0x058a9): (114, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05921): (115, "PromiseResolveThenableJobTaskMap"), ("read_only_space", 0x058f9): (115, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x05971): (116, "FinalizationGroupCleanupJobTaskMap"), ("read_only_space", 0x05949): (116, "FinalizationGroupCleanupJobTaskMap"),
("read_only_space", 0x059c1): (117, "InternalClassMap"), ("read_only_space", 0x05999): (117, "InternalClassMap"),
("read_only_space", 0x05a11): (118, "SmiPairMap"), ("read_only_space", 0x059e9): (118, "SmiPairMap"),
("read_only_space", 0x05a61): (119, "SmiBoxMap"), ("read_only_space", 0x05a39): (119, "SmiBoxMap"),
("read_only_space", 0x05ab1): (120, "SortStateMap"), ("read_only_space", 0x05a89): (120, "SortStateMap"),
("read_only_space", 0x05b01): (123, "AllocationSiteWithWeakNextMap"), ("read_only_space", 0x05ad9): (123, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05b51): (123, "AllocationSiteWithoutWeakNextMap"), ("read_only_space", 0x05b29): (123, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x05ba1): (158, "LoadHandler1Map"), ("read_only_space", 0x05b79): (158, "LoadHandler1Map"),
("read_only_space", 0x05bf1): (158, "LoadHandler2Map"), ("read_only_space", 0x05bc9): (158, "LoadHandler2Map"),
("read_only_space", 0x05c41): (158, "LoadHandler3Map"), ("read_only_space", 0x05c19): (158, "LoadHandler3Map"),
("read_only_space", 0x05c91): (166, "StoreHandler0Map"), ("read_only_space", 0x05c69): (166, "StoreHandler0Map"),
("read_only_space", 0x05ce1): (166, "StoreHandler1Map"), ("read_only_space", 0x05cb9): (166, "StoreHandler1Map"),
("read_only_space", 0x05d31): (166, "StoreHandler2Map"), ("read_only_space", 0x05d09): (166, "StoreHandler2Map"),
("read_only_space", 0x05d81): (166, "StoreHandler3Map"), ("read_only_space", 0x05d59): (166, "StoreHandler3Map"),
("map_space", 0x00139): (1057, "ExternalMap"), ("map_space", 0x00111): (1057, "ExternalMap"),
("map_space", 0x00189): (1073, "JSMessageObjectMap"), ("map_space", 0x00161): (1073, "JSMessageObjectMap"),
} }
# List of known V8 objects. # List of known V8 objects.
KNOWN_OBJECTS = { KNOWN_OBJECTS = {
("read_only_space", 0x001d9): "NullValue", ("read_only_space", 0x001b1): "NullValue",
("read_only_space", 0x00259): "EmptyDescriptorArray", ("read_only_space", 0x00231): "EmptyDescriptorArray",
("read_only_space", 0x002c1): "EmptyWeakFixedArray", ("read_only_space", 0x00299): "EmptyWeakFixedArray",
("read_only_space", 0x003c1): "UninitializedValue", ("read_only_space", 0x00399): "UninitializedValue",
("read_only_space", 0x004d1): "UndefinedValue", ("read_only_space", 0x004a9): "UndefinedValue",
("read_only_space", 0x00551): "NanValue", ("read_only_space", 0x00529): "NanValue",
("read_only_space", 0x005b1): "TheHoleValue", ("read_only_space", 0x00589): "TheHoleValue",
("read_only_space", 0x00649): "HoleNanValue", ("read_only_space", 0x00621): "HoleNanValue",
("read_only_space", 0x00659): "TrueValue", ("read_only_space", 0x00631): "TrueValue",
("read_only_space", 0x00709): "FalseValue", ("read_only_space", 0x006e1): "FalseValue",
("read_only_space", 0x00751): "empty_string", ("read_only_space", 0x00729): "empty_string",
("read_only_space", 0x00c11): "EmptyScopeInfo", ("read_only_space", 0x00be9): "EmptyScopeInfo",
("read_only_space", 0x00c21): "EmptyFixedArray", ("read_only_space", 0x00bf9): "EmptyFixedArray",
("read_only_space", 0x00c31): "ArgumentsMarker", ("read_only_space", 0x00c09): "ArgumentsMarker",
("read_only_space", 0x00cd1): "Exception", ("read_only_space", 0x00ca9): "Exception",
("read_only_space", 0x00d71): "TerminationException", ("read_only_space", 0x00d49): "TerminationException",
("read_only_space", 0x00e19): "OptimizedOut", ("read_only_space", 0x00df1): "OptimizedOut",
("read_only_space", 0x00eb9): "StaleRegister", ("read_only_space", 0x00e91): "StaleRegister",
("read_only_space", 0x023f9): "EmptyEnumCache", ("read_only_space", 0x023d1): "EmptyEnumCache",
("read_only_space", 0x02461): "EmptyPropertyArray", ("read_only_space", 0x02439): "EmptyPropertyArray",
("read_only_space", 0x02471): "EmptyByteArray", ("read_only_space", 0x02449): "EmptyByteArray",
("read_only_space", 0x02481): "EmptyObjectBoilerplateDescription", ("read_only_space", 0x02459): "EmptyObjectBoilerplateDescription",
("read_only_space", 0x02499): "EmptyArrayBoilerplateDescription", ("read_only_space", 0x02471): "EmptyArrayBoilerplateDescription",
("read_only_space", 0x02501): "EmptyClosureFeedbackCellArray", ("read_only_space", 0x024d9): "EmptyClosureFeedbackCellArray",
("read_only_space", 0x02511): "EmptySloppyArgumentsElements", ("read_only_space", 0x024e9): "EmptySloppyArgumentsElements",
("read_only_space", 0x02531): "EmptySlowElementDictionary", ("read_only_space", 0x02509): "EmptySlowElementDictionary",
("read_only_space", 0x02579): "EmptyOrderedHashMap", ("read_only_space", 0x02551): "EmptyOrderedHashMap",
("read_only_space", 0x025a1): "EmptyOrderedHashSet", ("read_only_space", 0x02579): "EmptyOrderedHashSet",
("read_only_space", 0x025c9): "EmptyFeedbackMetadata", ("read_only_space", 0x025a1): "EmptyFeedbackMetadata",
("read_only_space", 0x025d9): "EmptyPropertyCell", ("read_only_space", 0x025b1): "EmptyPropertyCell",
("read_only_space", 0x02601): "EmptyPropertyDictionary", ("read_only_space", 0x025d9): "EmptyPropertyDictionary",
("read_only_space", 0x02651): "NoOpInterceptorInfo", ("read_only_space", 0x02629): "NoOpInterceptorInfo",
("read_only_space", 0x026f1): "EmptyWeakArrayList", ("read_only_space", 0x026c9): "EmptyWeakArrayList",
("read_only_space", 0x02709): "InfinityValue", ("read_only_space", 0x026e1): "InfinityValue",
("read_only_space", 0x02719): "MinusZeroValue", ("read_only_space", 0x026f1): "MinusZeroValue",
("read_only_space", 0x02729): "MinusInfinityValue", ("read_only_space", 0x02701): "MinusInfinityValue",
("read_only_space", 0x02739): "SelfReferenceMarker", ("read_only_space", 0x02711): "SelfReferenceMarker",
("read_only_space", 0x02791): "OffHeapTrampolineRelocationInfo", ("read_only_space", 0x02769): "OffHeapTrampolineRelocationInfo",
("read_only_space", 0x027a9): "TrampolineTrivialCodeDataContainer", ("read_only_space", 0x02781): "TrampolineTrivialCodeDataContainer",
("read_only_space", 0x027c1): "TrampolinePromiseRejectionCodeDataContainer", ("read_only_space", 0x02799): "TrampolinePromiseRejectionCodeDataContainer",
("read_only_space", 0x027d9): "HashSeed", ("read_only_space", 0x027b1): "HashSeed",
("old_space", 0x00139): "ArgumentsIteratorAccessor", ("old_space", 0x00111): "ArgumentsIteratorAccessor",
("old_space", 0x001a9): "ArrayLengthAccessor", ("old_space", 0x00181): "ArrayLengthAccessor",
("old_space", 0x00219): "BoundFunctionLengthAccessor", ("old_space", 0x001f1): "BoundFunctionLengthAccessor",
("old_space", 0x00289): "BoundFunctionNameAccessor", ("old_space", 0x00261): "BoundFunctionNameAccessor",
("old_space", 0x002f9): "ErrorStackAccessor", ("old_space", 0x002d1): "ErrorStackAccessor",
("old_space", 0x00369): "FunctionArgumentsAccessor", ("old_space", 0x00341): "FunctionArgumentsAccessor",
("old_space", 0x003d9): "FunctionCallerAccessor", ("old_space", 0x003b1): "FunctionCallerAccessor",
("old_space", 0x00449): "FunctionNameAccessor", ("old_space", 0x00421): "FunctionNameAccessor",
("old_space", 0x004b9): "FunctionLengthAccessor", ("old_space", 0x00491): "FunctionLengthAccessor",
("old_space", 0x00529): "FunctionPrototypeAccessor", ("old_space", 0x00501): "FunctionPrototypeAccessor",
("old_space", 0x00599): "StringLengthAccessor", ("old_space", 0x00571): "StringLengthAccessor",
("old_space", 0x00609): "InvalidPrototypeValidityCell", ("old_space", 0x005e1): "InvalidPrototypeValidityCell",
("old_space", 0x00619): "EmptyScript", ("old_space", 0x005f1): "EmptyScript",
("old_space", 0x00699): "ManyClosuresCell", ("old_space", 0x00671): "ManyClosuresCell",
("old_space", 0x006b1): "ArrayConstructorProtector", ("old_space", 0x00689): "ArrayConstructorProtector",
("old_space", 0x006c1): "NoElementsProtector", ("old_space", 0x00699): "NoElementsProtector",
("old_space", 0x006e9): "IsConcatSpreadableProtector", ("old_space", 0x006c1): "IsConcatSpreadableProtector",
("old_space", 0x006f9): "ArraySpeciesProtector", ("old_space", 0x006d1): "ArraySpeciesProtector",
("old_space", 0x00721): "TypedArraySpeciesProtector", ("old_space", 0x006f9): "TypedArraySpeciesProtector",
("old_space", 0x00749): "PromiseSpeciesProtector", ("old_space", 0x00721): "PromiseSpeciesProtector",
("old_space", 0x00771): "StringLengthProtector", ("old_space", 0x00749): "StringLengthProtector",
("old_space", 0x00781): "ArrayIteratorProtector", ("old_space", 0x00759): "ArrayIteratorProtector",
("old_space", 0x007a9): "ArrayBufferDetachingProtector", ("old_space", 0x00781): "ArrayBufferDetachingProtector",
("old_space", 0x007d1): "PromiseHookProtector", ("old_space", 0x007a9): "PromiseHookProtector",
("old_space", 0x007f9): "PromiseResolveProtector", ("old_space", 0x007d1): "PromiseResolveProtector",
("old_space", 0x00809): "MapIteratorProtector", ("old_space", 0x007e1): "MapIteratorProtector",
("old_space", 0x00831): "PromiseThenProtector", ("old_space", 0x00809): "PromiseThenProtector",
("old_space", 0x00859): "SetIteratorProtector", ("old_space", 0x00831): "SetIteratorProtector",
("old_space", 0x00881): "StringIteratorProtector", ("old_space", 0x00859): "StringIteratorProtector",
("old_space", 0x008a9): "SingleCharacterStringCache", ("old_space", 0x00881): "SingleCharacterStringCache",
("old_space", 0x010b9): "StringSplitCache", ("old_space", 0x01091): "StringSplitCache",
("old_space", 0x018c9): "RegExpMultipleCache", ("old_space", 0x018a1): "RegExpMultipleCache",
("old_space", 0x020d9): "BuiltinsConstantsTable", ("old_space", 0x020b1): "BuiltinsConstantsTable",
} }
# List of known V8 Frame Markers. # List of known V8 Frame Markers.
......
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