Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Unified Diff: src/spaces.cc

Issue 14208005: Use worst-fit allocation in old space for prentured objects. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/spaces.cc
diff --git a/src/spaces.cc b/src/spaces.cc
index 7202e1bbc07556ce31efc1d758418064d2a393f0..9cc8304aad0908078f85e56c72463eb2aadc2ab4 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -2215,36 +2215,8 @@ int FreeList::Free(Address start, int size_in_bytes) {
}
-FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
+FreeListNode* FreeList::FindNodeInHugeList(int size_in_bytes, int* node_size) {
FreeListNode* node = NULL;
- Page* page = NULL;
-
- if (size_in_bytes <= kSmallAllocationMax) {
- node = small_list_.PickNodeFromList(node_size);
- if (node != NULL) {
- page = Page::FromAddress(node->address());
- page->add_available_in_small_free_list(-(*node_size));
- return node;
- }
- }
-
- if (size_in_bytes <= kMediumAllocationMax) {
- node = medium_list_.PickNodeFromList(node_size);
- if (node != NULL) {
- page = Page::FromAddress(node->address());
- page->add_available_in_medium_free_list(-(*node_size));
- return node;
- }
- }
-
- if (size_in_bytes <= kLargeAllocationMax) {
- node = large_list_.PickNodeFromList(node_size);
- if (node != NULL) {
- page = Page::FromAddress(node->address());
- page->add_available_in_large_free_list(-(*node_size));
- return node;
- }
- }
int huge_list_available = huge_list_.available();
for (FreeListNode** cur = huge_list_.GetTopAddress();
@@ -2255,7 +2227,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) {
int size = reinterpret_cast<FreeSpace*>(cur_node)->Size();
huge_list_available -= size;
- page = Page::FromAddress(cur_node->address());
+ Page* page = Page::FromAddress(cur_node->address());
page->add_available_in_huge_free_list(-size);
cur_node = cur_node->next();
}
@@ -2275,7 +2247,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
*cur = node->next();
*node_size = size;
huge_list_available -= size;
- page = Page::FromAddress(node->address());
+ Page* page = Page::FromAddress(node->address());
page->add_available_in_huge_free_list(-size);
break;
}
@@ -2292,10 +2264,80 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
}
+FreeListNode* FreeList::FindNodeForWorstFit(int size_in_bytes, int* node_size) {
+ FreeListNode* node = FindNodeInHugeList(size_in_bytes, node_size);
+ if (node != NULL) {
+ return node;
+ }
+
+ if (size_in_bytes <= kLargeAllocationMax) {
+ node = large_list_.PickNodeFromList(node_size);
+ if (node != NULL) {
+ Page* page = Page::FromAddress(node->address());
+ page->add_available_in_large_free_list(-(*node_size));
+ return node;
+ }
+ }
+
+ if (size_in_bytes <= kMediumAllocationMax) {
+ node = medium_list_.PickNodeFromList(node_size);
+ if (node != NULL) {
+ Page* page = Page::FromAddress(node->address());
+ page->add_available_in_medium_free_list(-(*node_size));
+ return node;
+ }
+ }
+
+ return node;
+}
+
+
+FreeListNode* FreeList::FindNodeForBestFit(int size_in_bytes, int* node_size) {
+ FreeListNode* node = NULL;
+
+ if (size_in_bytes <= kSmallAllocationMax) {
+ node = small_list_.PickNodeFromList(node_size);
+ if (node != NULL) {
+ Page* page = Page::FromAddress(node->address());
+ page->add_available_in_small_free_list(-(*node_size));
+ return node;
+ }
+ }
+
+ if (size_in_bytes <= kMediumAllocationMax) {
+ node = medium_list_.PickNodeFromList(node_size);
+ if (node != NULL) {
+ Page* page = Page::FromAddress(node->address());
+ page->add_available_in_medium_free_list(-(*node_size));
+ return node;
+ }
+ }
+
+ if (size_in_bytes <= kLargeAllocationMax) {
+ node = large_list_.PickNodeFromList(node_size);
+ if (node != NULL) {
+ Page* page = Page::FromAddress(node->address());
+ page->add_available_in_large_free_list(-(*node_size));
+ return node;
+ }
+ }
+
+ node = FindNodeInHugeList(size_in_bytes, node_size);
+ return node;
+}
+
+
+template HeapObject* FreeList::Allocate<FreeList::BEST_FIT>(int size_in_bytes);
+
+
+template HeapObject* FreeList::Allocate<FreeList::WORST_FIT>(int size_in_bytes);
+
+
// Allocation on the old space free list. If it succeeds then a new linear
// allocation space has been set up with the top and limit of the space. If
// the allocation fails then NULL is returned, and the caller can perform a GC
// or allocate a new page before retrying.
+template<FreeList::AllocationStrategy strategy>
HeapObject* FreeList::Allocate(int size_in_bytes) {
ASSERT(0 < size_in_bytes);
ASSERT(size_in_bytes <= kMaxBlockSize);
@@ -2304,7 +2346,12 @@ HeapObject* FreeList::Allocate(int size_in_bytes) {
ASSERT(owner_->limit() - owner_->top() < size_in_bytes);
int new_node_size = 0;
- FreeListNode* new_node = FindNodeFor(size_in_bytes, &new_node_size);
+ FreeListNode* new_node;
+ if (FreeList::BEST_FIT == strategy) {
+ new_node = FindNodeForBestFit(size_in_bytes, &new_node_size);
+ } else {
+ new_node = FindNodeForWorstFit(size_in_bytes, &new_node_size);
+ }
if (new_node == NULL) return NULL;
@@ -2335,10 +2382,17 @@ HeapObject* FreeList::Allocate(int size_in_bytes) {
const int kThreshold = IncrementalMarking::kAllocatedThreshold;
// Memory in the linear allocation area is counted as allocated. We may free
- // a little of this again immediately - see below.
+ // a little of this again immediately - see below. We try to create large
+ // bump pointer ranges when we use worst-fit, therefore we do not give
+ // memory back to the free-list.
owner_->Allocate(new_node_size);
- if (bytes_left > kThreshold &&
+ if (FreeList::WORST_FIT == strategy) {
+ owner_->AllocatePretenure(new_node_size);
+ }
+
+ if (FreeList::BEST_FIT == strategy &&
+ bytes_left > kThreshold &&
owner_->heap()->incremental_marking()->IsMarkingIncomplete() &&
FLAG_incremental_marking_steps) {
int linear_size = owner_->RoundSizeDownToObjectAlignment(kThreshold);
@@ -2507,8 +2561,10 @@ bool PagedSpace::ReserveSpace(int size_in_bytes) {
Address new_top = current_top + size_in_bytes;
if (new_top <= allocation_info_.limit) return true;
- HeapObject* new_area = free_list_.Allocate(size_in_bytes);
- if (new_area == NULL) new_area = SlowAllocateRaw(size_in_bytes);
+ HeapObject* new_area = free_list_.Allocate<FreeList::BEST_FIT>(size_in_bytes);
+ if (new_area == NULL) {
+ new_area = SlowAllocateRaw<FreeList::BEST_FIT>(size_in_bytes);
+ }
if (new_area == NULL) return false;
int old_linear_size = static_cast<int>(limit() - top());
@@ -2613,6 +2669,15 @@ bool PagedSpace::EnsureSweeperProgress(intptr_t size_in_bytes) {
}
+template HeapObject* PagedSpace::
+ SlowAllocateRaw<FreeList::BEST_FIT>(int size_in_bytes);
+
+
+template HeapObject* PagedSpace::
+ SlowAllocateRaw<FreeList::WORST_FIT>(int size_in_bytes);
+
+
+template<FreeList::AllocationStrategy strategy>
HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
// Allocation in this space has failed.
@@ -2625,7 +2690,7 @@ HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
sweeping_complete = EnsureSweeperProgress(size_in_bytes);
// Retry the free list allocation.
- HeapObject* object = free_list_.Allocate(size_in_bytes);
+ HeapObject* object = free_list_.Allocate<strategy>(size_in_bytes);
if (object != NULL) return object;
}
@@ -2633,13 +2698,14 @@ HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
// hit the old generation size limit that should cause a garbage
// collection.
if (!heap()->always_allocate() &&
+ !heap()->AggressivePromotionMode() &&
heap()->OldGenerationAllocationLimitReached()) {
return NULL;
}
// Try to expand the space and allocate in the new next page.
if (Expand()) {
- return free_list_.Allocate(size_in_bytes);
+ return free_list_.Allocate<strategy>(size_in_bytes);
}
// Last ditch, sweep all the remaining pages to try to find space. This may
@@ -2648,7 +2714,7 @@ HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
EnsureSweeperProgress(kMaxInt);
// Retry the free list allocation.
- HeapObject* object = free_list_.Allocate(size_in_bytes);
+ HeapObject* object = free_list_.Allocate<strategy>(size_in_bytes);
if (object != NULL) return object;
}
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698