Commit 9e70cb84 authored by hpayer@chromium.org's avatar hpayer@chromium.org

As a last resort try to allocate out of the smaller size size-class in

the free list allocator.

BUG=
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/17058002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15146 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2987b117
...@@ -2118,13 +2118,13 @@ FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { ...@@ -2118,13 +2118,13 @@ FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) {
while (node != NULL && while (node != NULL &&
Page::FromAddress(node->address())->IsEvacuationCandidate()) { Page::FromAddress(node->address())->IsEvacuationCandidate()) {
available_ -= node->Size(); available_ -= reinterpret_cast<FreeSpace*>(node)->Size();
node = node->next(); node = node->next();
} }
if (node != NULL) { if (node != NULL) {
set_top(node->next()); set_top(node->next());
*node_size = node->Size(); *node_size = reinterpret_cast<FreeSpace*>(node)->Size();
available_ -= *node_size; available_ -= *node_size;
} else { } else {
set_top(NULL); set_top(NULL);
...@@ -2138,6 +2138,18 @@ FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { ...@@ -2138,6 +2138,18 @@ FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) {
} }
FreeListNode* FreeListCategory::PickNodeFromList(int size_in_bytes,
int *node_size) {
FreeListNode* node = PickNodeFromList(node_size);
if (node != NULL && *node_size < size_in_bytes) {
Free(node, *node_size);
*node_size = 0;
return NULL;
}
return node;
}
void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) {
node->set_next(top_); node->set_next(top_);
top_ = node; top_ = node;
...@@ -2202,11 +2214,6 @@ int FreeList::Free(Address start, int size_in_bytes) { ...@@ -2202,11 +2214,6 @@ int FreeList::Free(Address start, int size_in_bytes) {
// Insert other blocks at the head of a free list of the appropriate // Insert other blocks at the head of a free list of the appropriate
// magnitude. // magnitude.
if (size_in_bytes <= kSmallListMax) { if (size_in_bytes <= kSmallListMax) {
ASSERT(!owner_->ConstantAllocationSize() ||
(owner_->identity() == MAP_SPACE && size_in_bytes >= Map::kSize) ||
(owner_->identity() == CELL_SPACE && size_in_bytes >= Cell::kSize) ||
(owner_->identity() == PROPERTY_CELL_SPACE &&
size_in_bytes >= JSGlobalPropertyCell::kSize));
small_list_.Free(node, size_in_bytes); small_list_.Free(node, size_in_bytes);
page->add_available_in_small_free_list(size_in_bytes); page->add_available_in_small_free_list(size_in_bytes);
} else if (size_in_bytes <= kMediumListMax) { } else if (size_in_bytes <= kMediumListMax) {
...@@ -2229,13 +2236,13 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { ...@@ -2229,13 +2236,13 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
FreeListNode* node = NULL; FreeListNode* node = NULL;
Page* page = NULL; Page* page = NULL;
if ((owner_->ConstantAllocationSize() && size_in_bytes <= kSmallListMax) || if (size_in_bytes <= kSmallAllocationMax) {
size_in_bytes <= kSmallAllocationMax) {
node = small_list_.PickNodeFromList(node_size); node = small_list_.PickNodeFromList(node_size);
if (node != NULL) { if (node != NULL) {
ASSERT(size_in_bytes <= *node_size); ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address()); page = Page::FromAddress(node->address());
page->add_available_in_small_free_list(-(*node_size)); page->add_available_in_small_free_list(-(*node_size));
ASSERT(IsVeryLong() || available() == SumFreeLists());
return node; return node;
} }
} }
...@@ -2246,6 +2253,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { ...@@ -2246,6 +2253,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
ASSERT(size_in_bytes <= *node_size); ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address()); page = Page::FromAddress(node->address());
page->add_available_in_medium_free_list(-(*node_size)); page->add_available_in_medium_free_list(-(*node_size));
ASSERT(IsVeryLong() || available() == SumFreeLists());
return node; return node;
} }
} }
...@@ -2256,6 +2264,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { ...@@ -2256,6 +2264,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
ASSERT(size_in_bytes <= *node_size); ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address()); page = Page::FromAddress(node->address());
page->add_available_in_large_free_list(-(*node_size)); page->add_available_in_large_free_list(-(*node_size));
ASSERT(IsVeryLong() || available() == SumFreeLists());
return node; return node;
} }
} }
...@@ -2298,10 +2307,37 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { ...@@ -2298,10 +2307,37 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
if (huge_list_.top() == NULL) { if (huge_list_.top() == NULL) {
huge_list_.set_end(NULL); huge_list_.set_end(NULL);
} }
huge_list_.set_available(huge_list_available); huge_list_.set_available(huge_list_available);
ASSERT(IsVeryLong() || available() == SumFreeLists());
if (node != NULL) {
ASSERT(IsVeryLong() || available() == SumFreeLists());
return node;
}
if (size_in_bytes <= kSmallListMax) {
node = small_list_.PickNodeFromList(size_in_bytes, node_size);
if (node != NULL) {
ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address());
page->add_available_in_small_free_list(-(*node_size));
}
} else if (size_in_bytes <= kMediumListMax) {
node = medium_list_.PickNodeFromList(size_in_bytes, node_size);
if (node != NULL) {
ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address());
page->add_available_in_medium_free_list(-(*node_size));
}
} else if (size_in_bytes <= kLargeListMax) {
node = large_list_.PickNodeFromList(size_in_bytes, node_size);
if (node != NULL) {
ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address());
page->add_available_in_large_free_list(-(*node_size));
}
}
ASSERT(IsVeryLong() || available() == SumFreeLists());
return node; return node;
} }
......
...@@ -1454,6 +1454,7 @@ class FreeListCategory { ...@@ -1454,6 +1454,7 @@ class FreeListCategory {
void Free(FreeListNode* node, int size_in_bytes); void Free(FreeListNode* node, int size_in_bytes);
FreeListNode* PickNodeFromList(int *node_size); FreeListNode* PickNodeFromList(int *node_size);
FreeListNode* PickNodeFromList(int size_in_bytes, int *node_size);
intptr_t EvictFreeListItemsInList(Page* p); intptr_t EvictFreeListItemsInList(Page* p);
...@@ -1820,11 +1821,6 @@ class PagedSpace : public Space { ...@@ -1820,11 +1821,6 @@ class PagedSpace : public Space {
return area_size_; return area_size_;
} }
bool ConstantAllocationSize() {
return identity() == MAP_SPACE || identity() == CELL_SPACE ||
identity() == PROPERTY_CELL_SPACE;
}
protected: protected:
FreeList* free_list() { return &free_list_; } FreeList* free_list() { return &free_list_; }
......
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