Index: src/spaces.cc |
=================================================================== |
--- src/spaces.cc (revision 3575) |
+++ src/spaces.cc (working copy) |
@@ -92,6 +92,7 @@ |
cur_addr_ = cur_page->ObjectAreaStart(); |
cur_limit_ = (cur_page == end_page_) ? end_addr_ : cur_page->AllocationTop(); |
+ if (cur_addr_ == end_addr_) return false; |
ASSERT(cur_addr_ < cur_limit_); |
#ifdef DEBUG |
Verify(); |
@@ -1822,6 +1823,53 @@ |
} |
+bool NewSpace::ReserveSpace(int bytes) { |
+ // We can't reliably unpack a partial snapshot that needs more new space |
+ // space than the minimum NewSpace size. |
+ ASSERT(bytes <= InitialCapacity()); |
+ Address limit = allocation_info_.limit; |
+ Address top = allocation_info_.top; |
+ return limit - top >= bytes; |
+} |
+ |
+ |
+bool PagedSpace::ReserveSpace(int bytes) { |
+ Address limit = allocation_info_.limit; |
+ Address top = allocation_info_.top; |
+ if (limit - top >= bytes) return true; |
+ |
+ // There wasn't enough space in the current page. Lets put the rest |
+ // of the page on the free list and start a fresh page. |
+ PutRestOfCurrentPageOnFreeList(TopPageOf(allocation_info_)); |
+ |
+ Page* reserved_page = TopPageOf(allocation_info_); |
+ int bytes_left_to_reserve = bytes; |
+ while (bytes_left_to_reserve > 0) { |
+ if (!reserved_page->next_page()->is_valid()) { |
+ if (Heap::OldGenerationAllocationLimitReached()) return false; |
+ Expand(reserved_page); |
+ } |
+ bytes_left_to_reserve -= Page::kPageSize; |
Mads Ager (chromium)
2010/01/12 14:17:49
Do we need some slack here? Allocating just enoug
|
+ reserved_page = reserved_page->next_page(); |
+ if (!reserved_page->is_valid()) return false; |
+ } |
+ ASSERT(TopPageOf(allocation_info_)->next_page()->is_valid()); |
+ SetAllocationInfo(&allocation_info_, |
+ TopPageOf(allocation_info_)->next_page()); |
+ return true; |
+} |
+ |
+ |
+// You have to call this last, since the implementation from PagedSpace |
+// doesn't know that memory was 'promised' to large object space. |
+bool LargeObjectSpace::ReserveSpace(int bytes) { |
+ // We add a slack-factor of 2 in order to have space for the remembered |
Mads Ager (chromium)
2010/01/12 14:17:49
Is a factor of 2 enough? I would guess that this
|
+ // set and a series of large-object allocations that are only just larger |
+ // than the page size. |
+ return Heap::OldGenerationSpaceAvailable() >= bytes * 2; |
+} |
+ |
+ |
// Slow case for normal allocation. Try in order: (1) allocate in the next |
// page in the space, (2) allocate off the space's free list, (3) expand the |
// space, (4) fail. |
@@ -1865,19 +1913,37 @@ |
} |
+void OldSpace::PutRestOfCurrentPageOnFreeList(Page* current_page) { |
+ int free_size = |
+ static_cast<int>(current_page->ObjectAreaEnd() - allocation_info_.top); |
+ if (free_size > 0) { |
+ int wasted_bytes = free_list_.Free(allocation_info_.top, free_size); |
+ accounting_stats_.WasteBytes(wasted_bytes); |
+ } |
+} |
+ |
+ |
+void FixedSpace::PutRestOfCurrentPageOnFreeList(Page* current_page) { |
+ int free_size = |
+ static_cast<int>(current_page->ObjectAreaEnd() - allocation_info_.top); |
+ // In the fixed space free list all the free list items have the right size. |
+ // We use up the rest of the page while preserving this invariant. |
+ while (free_size >= object_size_in_bytes_) { |
+ free_list_.Free(allocation_info_.top); |
+ allocation_info_.top += object_size_in_bytes_; |
+ free_size -= object_size_in_bytes_; |
+ accounting_stats_.WasteBytes(object_size_in_bytes_); |
+ } |
+} |
+ |
+ |
// Add the block at the top of the page to the space's free list, set the |
// allocation info to the next page (assumed to be one), and allocate |
// linearly there. |
HeapObject* OldSpace::AllocateInNextPage(Page* current_page, |
int size_in_bytes) { |
ASSERT(current_page->next_page()->is_valid()); |
- // Add the block at the top of this page to the free list. |
- int free_size = |
- static_cast<int>(current_page->ObjectAreaEnd() - allocation_info_.top); |
- if (free_size > 0) { |
- int wasted_bytes = free_list_.Free(allocation_info_.top, free_size); |
- accounting_stats_.WasteBytes(wasted_bytes); |
- } |
+ PutRestOfCurrentPageOnFreeList(current_page); |
SetAllocationInfo(&allocation_info_, current_page->next_page()); |
return AllocateLinearly(&allocation_info_, size_in_bytes); |
} |