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

Unified Diff: src/heap/spaces.cc

Issue 1356533002: Reland "[heap] Introduce parallel compaction algorithm." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix accounting for moved free list memory Created 5 years, 3 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/heap/spaces.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/spaces.cc
diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc
index b1c9557989fd5a12cd0f5e2043572b548c362997..c74b93f52c1672417ffbf9d250ffebee234b8b76 100644
--- a/src/heap/spaces.cc
+++ b/src/heap/spaces.cc
@@ -80,8 +80,7 @@ CodeRange::CodeRange(Isolate* isolate)
code_range_(NULL),
free_list_(0),
allocation_list_(0),
- current_allocation_block_index_(0),
- emergency_block_() {}
+ current_allocation_block_index_(0) {}
bool CodeRange::SetUp(size_t requested) {
@@ -140,7 +139,6 @@ bool CodeRange::SetUp(size_t requested) {
current_allocation_block_index_ = 0;
LOG(isolate_, NewEvent("CodeRange", code_range_->address(), requested));
- ReserveEmergencyBlock();
return true;
}
@@ -276,24 +274,6 @@ void CodeRange::ReleaseBlock(const FreeBlock* block) {
}
-void CodeRange::ReserveEmergencyBlock() {
- const size_t requested_size = MemoryAllocator::CodePageAreaSize();
- if (emergency_block_.size == 0) {
- ReserveBlock(requested_size, &emergency_block_);
- } else {
- DCHECK(emergency_block_.size >= requested_size);
- }
-}
-
-
-void CodeRange::ReleaseEmergencyBlock() {
- if (emergency_block_.size != 0) {
- ReleaseBlock(&emergency_block_);
- emergency_block_.size = 0;
- }
-}
-
-
// -----------------------------------------------------------------------------
// MemoryAllocator
//
@@ -492,6 +472,7 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size,
chunk->progress_bar_ = 0;
chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base));
chunk->set_parallel_sweeping(SWEEPING_DONE);
+ chunk->parallel_compaction_state().SetValue(kCompactingDone);
chunk->mutex_ = NULL;
chunk->available_in_small_free_list_ = 0;
chunk->available_in_medium_free_list_ = 0;
@@ -974,8 +955,7 @@ PagedSpace::PagedSpace(Heap* heap, AllocationSpace space,
: Space(heap, space, executable),
free_list_(this),
unswept_free_bytes_(0),
- end_of_unswept_pages_(NULL),
- emergency_memory_(NULL) {
+ end_of_unswept_pages_(NULL) {
area_size_ = MemoryAllocator::PageAreaSize(space);
accounting_stats_.Clear();
@@ -1003,30 +983,38 @@ void PagedSpace::TearDown() {
}
+void PagedSpace::MoveOverFreeMemory(PagedSpace* other) {
+ DCHECK(identity() == other->identity());
+ // Destroy the linear allocation space of {other}. This is needed to
+ // (a) not waste the memory and
+ // (b) keep the rest of the chunk in an iterable state (filler is needed).
+ other->EmptyAllocationInfo();
+
+ // Move over the free list. Concatenate makes sure that the source free list
+ // gets properly reset after moving over all nodes.
+ intptr_t freed_bytes = free_list_.Concatenate(other->free_list());
+
+ // Moved memory is not recorded as allocated memory, but rather increases and
+ // decreases capacity of the corresponding spaces. Used size and waste size
+ // are maintained by the receiving space upon allocating and freeing blocks.
+ other->accounting_stats_.DecreaseCapacity(freed_bytes);
+ accounting_stats_.IncreaseCapacity(freed_bytes);
+}
+
+
void PagedSpace::MergeCompactionSpace(CompactionSpace* other) {
// Unmerged fields:
// area_size_
// allocation_info_
- // emergency_memory_
// end_of_unswept_pages_
// unswept_free_bytes_
// anchor_
- // It only makes sense to merge compatible spaces.
- DCHECK(identity() == other->identity());
-
- // Destroy the linear allocation space of {other}. This is needed to (a) not
- // waste the memory and (b) keep the rest of the chunk in an iterable state
- // (filler is needed).
- int linear_size = static_cast<int>(other->limit() - other->top());
- other->Free(other->top(), linear_size);
-
- // Move over the free list.
- free_list_.Concatenate(other->free_list());
+ MoveOverFreeMemory(other);
// Update and clear accounting statistics.
accounting_stats_.Merge(other->accounting_stats_);
- other->accounting_stats_.Clear();
+ other->accounting_stats_.Reset();
// Move over pages.
PageIterator it(other);
@@ -1110,9 +1098,6 @@ bool PagedSpace::Expand() {
if (!heap()->deserialization_complete()) p->MarkNeverEvacuate();
DCHECK(Capacity() <= heap()->MaxOldGenerationSize());
- DCHECK(heap()->CommittedOldGenerationMemory() <=
- heap()->MaxOldGenerationSize() +
- PagedSpace::MaxEmergencyMemoryAllocated());
p->InsertAfter(anchor_.prev_page());
@@ -1182,51 +1167,6 @@ void PagedSpace::ReleasePage(Page* page) {
}
-intptr_t PagedSpace::MaxEmergencyMemoryAllocated() {
- // New space and large object space.
- static const int spaces_without_emergency_memory = 2;
- static const int spaces_with_emergency_memory =
- LAST_SPACE - FIRST_SPACE + 1 - spaces_without_emergency_memory;
- return Page::kPageSize * spaces_with_emergency_memory;
-}
-
-
-void PagedSpace::CreateEmergencyMemory() {
- if (identity() == CODE_SPACE) {
- // Make the emergency block available to the allocator.
- CodeRange* code_range = heap()->isolate()->code_range();
- if (code_range != NULL && code_range->valid()) {
- code_range->ReleaseEmergencyBlock();
- }
- DCHECK(MemoryAllocator::CodePageAreaSize() == AreaSize());
- }
- emergency_memory_ = heap()->isolate()->memory_allocator()->AllocateChunk(
- AreaSize(), AreaSize(), executable(), this);
-}
-
-
-void PagedSpace::FreeEmergencyMemory() {
- Page* page = static_cast<Page*>(emergency_memory_);
- DCHECK(page->LiveBytes() == 0);
- DCHECK(AreaSize() == page->area_size());
- DCHECK(!free_list_.ContainsPageFreeListItems(page));
- heap()->isolate()->memory_allocator()->Free(page);
- emergency_memory_ = NULL;
-}
-
-
-void PagedSpace::UseEmergencyMemory() {
- // Page::Initialize makes the chunk into a real page and adds it to the
- // accounting for this space. Unlike PagedSpace::Expand, we don't check
- // CanExpand first, so we can go over the limits a little here. That's OK,
- // because we are in the process of compacting which will free up at least as
- // much memory as it allocates.
- Page* page = Page::Initialize(heap(), emergency_memory_, executable(), this);
- page->InsertAfter(anchor_.prev_page());
- emergency_memory_ = NULL;
-}
-
-
#ifdef DEBUG
void PagedSpace::Print() {}
#endif
@@ -2133,9 +2073,10 @@ intptr_t FreeListCategory::Concatenate(FreeListCategory* category) {
if (category->top() != NULL) {
// This is safe (not going to deadlock) since Concatenate operations
// are never performed on the same free lists at the same time in
- // reverse order.
- base::LockGuard<base::Mutex> target_lock_guard(mutex());
- base::LockGuard<base::Mutex> source_lock_guard(category->mutex());
+ // reverse order. Furthermore, we only lock if the PagedSpace containing
+ // the free list is know to be globally available, i.e., not local.
+ if (!this->owner()->owner()->is_local()) mutex()->Lock();
+ if (!category->owner()->owner()->is_local()) category->mutex()->Lock();
DCHECK(category->end_ != NULL);
free_bytes = category->available();
if (end_ == NULL) {
@@ -2147,6 +2088,8 @@ intptr_t FreeListCategory::Concatenate(FreeListCategory* category) {
base::NoBarrier_Store(&top_, category->top_);
available_ += category->available();
category->Reset();
+ if (!category->owner()->owner()->is_local()) category->mutex()->Unlock();
+ if (!this->owner()->owner()->is_local()) mutex()->Unlock();
}
return free_bytes;
}
@@ -2254,7 +2197,13 @@ void FreeListCategory::RepairFreeList(Heap* heap) {
}
-FreeList::FreeList(PagedSpace* owner) : owner_(owner), heap_(owner->heap()) {
+FreeList::FreeList(PagedSpace* owner)
+ : owner_(owner),
+ heap_(owner->heap()),
+ small_list_(this),
+ medium_list_(this),
+ large_list_(this),
+ huge_list_(this) {
Reset();
}
« no previous file with comments | « src/heap/spaces.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698