Index: src/spaces.cc |
diff --git a/src/spaces.cc b/src/spaces.cc |
index 50530a19572afec1f9fde0fa6e9a3a83fc4d6344..d477e15f6961d8b6c16113861d13ac2145c61030 100644 |
--- a/src/spaces.cc |
+++ b/src/spaces.cc |
@@ -2118,13 +2118,13 @@ FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { |
while (node != NULL && |
Page::FromAddress(node->address())->IsEvacuationCandidate()) { |
- available_ -= node->Size(); |
+ available_ -= reinterpret_cast<FreeSpace*>(node)->Size(); |
node = node->next(); |
} |
if (node != NULL) { |
set_top(node->next()); |
- *node_size = node->Size(); |
+ *node_size = reinterpret_cast<FreeSpace*>(node)->Size(); |
available_ -= *node_size; |
} else { |
set_top(NULL); |
@@ -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) { |
node->set_next(top_); |
top_ = node; |
@@ -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 |
// magnitude. |
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); |
page->add_available_in_small_free_list(size_in_bytes); |
} else if (size_in_bytes <= kMediumListMax) { |
@@ -2229,13 +2236,13 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
FreeListNode* node = NULL; |
Page* page = NULL; |
- if ((owner_->ConstantAllocationSize() && size_in_bytes <= kSmallListMax) || |
- size_in_bytes <= kSmallAllocationMax) { |
+ if (size_in_bytes <= kSmallAllocationMax) { |
node = small_list_.PickNodeFromList(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)); |
+ ASSERT(IsVeryLong() || available() == SumFreeLists()); |
return node; |
} |
} |
@@ -2246,6 +2253,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
ASSERT(size_in_bytes <= *node_size); |
page = Page::FromAddress(node->address()); |
page->add_available_in_medium_free_list(-(*node_size)); |
+ ASSERT(IsVeryLong() || available() == SumFreeLists()); |
return node; |
} |
} |
@@ -2256,6 +2264,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
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; |
} |
} |
@@ -2298,10 +2307,37 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
if (huge_list_.top() == NULL) { |
huge_list_.set_end(NULL); |
} |
- |
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; |
} |