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