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() {
......
This diff is collapsed.
This diff is collapsed.
...@@ -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
This diff is collapsed.
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