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

Side by Side Diff: src/heap/spaces.cc

Issue 1382003002: [heap] Divide available memory upon compaction tasks (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@counters
Patch Set: Rework tests Created 5 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/heap/spaces.h" 5 #include "src/heap/spaces.h"
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/base/platform/platform.h" 8 #include "src/base/platform/platform.h"
9 #include "src/full-codegen/full-codegen.h" 9 #include "src/full-codegen/full-codegen.h"
10 #include "src/heap/slots-buffer.h" 10 #include "src/heap/slots-buffer.h"
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 PageIterator iterator(this); 975 PageIterator iterator(this);
976 while (iterator.has_next()) { 976 while (iterator.has_next()) {
977 heap()->isolate()->memory_allocator()->Free(iterator.next()); 977 heap()->isolate()->memory_allocator()->Free(iterator.next());
978 } 978 }
979 anchor_.set_next_page(&anchor_); 979 anchor_.set_next_page(&anchor_);
980 anchor_.set_prev_page(&anchor_); 980 anchor_.set_prev_page(&anchor_);
981 accounting_stats_.Clear(); 981 accounting_stats_.Clear();
982 } 982 }
983 983
984 984
985 void PagedSpace::AddMemory(Address start, intptr_t size) {
986 accounting_stats_.ExpandSpace(static_cast<int>(size));
987 Free(start, static_cast<int>(size));
988 }
989
990
991 FreeSpace* PagedSpace::TryRemoveMemory(intptr_t size_in_bytes) {
992 FreeSpace* space = free_list()->TryRemoveMemory(size_in_bytes);
993 if (space != nullptr) {
994 accounting_stats_.DecreaseCapacity(space->size());
995 }
996 return space;
997 }
998
999
1000 void PagedSpace::DivideUponCompactionSpaces(CompactionSpaceCollection** other,
1001 int num, intptr_t limit) {
1002 DCHECK_GT(num, 0);
1003 DCHECK(other != nullptr);
1004
1005 if (limit == 0) limit = std::numeric_limits<intptr_t>::max();
1006
1007 EmptyAllocationInfo();
1008
1009 int index = 0;
1010 FreeSpace* node = nullptr;
1011 // We evenly distribute existing memory among compaction spaces, i.e., while
1012 // iterating over them in round-robin fashion, we check whether they have
1013 // reached the {limit} of available bytes and try to add some memory if not.
1014 for (CompactionSpace* space = other[index]->Get(identity());
ulan 2015/10/09 11:48:48 Let's simplify the "for" statement so that the cor
Michael Lippautz 2015/10/09 12:20:13 Done, rewrote the loop. The intention is summariz
1015 (space->free_list()->available() < limit) &&
1016 ((node = TryRemoveMemory(limit - space->free_list()->available())) !=
1017 nullptr);
1018 space = other[++index % num]->Get(identity())) {
1019 CHECK(space->identity() == identity());
1020 space->AddMemory(node->address(), node->size());
1021 }
1022 }
1023
1024
985 void PagedSpace::MoveOverFreeMemory(PagedSpace* other) { 1025 void PagedSpace::MoveOverFreeMemory(PagedSpace* other) {
986 DCHECK(identity() == other->identity()); 1026 DCHECK(identity() == other->identity());
987 // Destroy the linear allocation space of {other}. This is needed to 1027 // Destroy the linear allocation space of {other}. This is needed to
988 // (a) not waste the memory and 1028 // (a) not waste the memory and
989 // (b) keep the rest of the chunk in an iterable state (filler is needed). 1029 // (b) keep the rest of the chunk in an iterable state (filler is needed).
990 other->EmptyAllocationInfo(); 1030 other->EmptyAllocationInfo();
991 1031
992 // Move over the free list. Concatenate makes sure that the source free list 1032 // Move over the free list. Concatenate makes sure that the source free list
993 // gets properly reset after moving over all nodes. 1033 // gets properly reset after moving over all nodes.
994 intptr_t added = free_list_.Concatenate(other->free_list()); 1034 intptr_t added = free_list_.Concatenate(other->free_list());
995 1035
996 // Moved memory is not recorded as allocated memory, but rather increases and 1036 // Moved memory is not recorded as allocated memory, but rather increases and
997 // decreases capacity of the corresponding spaces. Used size and waste size 1037 // decreases capacity of the corresponding spaces.
998 // are maintained by the receiving space upon allocating and freeing blocks.
999 other->accounting_stats_.DecreaseCapacity(added); 1038 other->accounting_stats_.DecreaseCapacity(added);
1000 accounting_stats_.IncreaseCapacity(added); 1039 accounting_stats_.IncreaseCapacity(added);
1001 } 1040 }
1002 1041
1003 1042
1004 void PagedSpace::MergeCompactionSpace(CompactionSpace* other) { 1043 void PagedSpace::MergeCompactionSpace(CompactionSpace* other) {
1005 // Unmerged fields: 1044 // Unmerged fields:
1006 // area_size_ 1045 // area_size_
1007 // allocation_info_
1008 // end_of_unswept_pages_
1009 // unswept_free_bytes_
1010 // anchor_ 1046 // anchor_
1011 1047
1012 MoveOverFreeMemory(other); 1048 MoveOverFreeMemory(other);
1013 1049
1014 // Update and clear accounting statistics. 1050 // Update and clear accounting statistics.
1015 accounting_stats_.Merge(other->accounting_stats_); 1051 accounting_stats_.Merge(other->accounting_stats_);
1016 other->accounting_stats_.Reset(); 1052 other->accounting_stats_.Clear();
1053
1054 // The linear allocation area of {other} should be destroyed now.
1055 DCHECK(other->top() == nullptr);
1056 DCHECK(other->limit() == nullptr);
1057
1058 DCHECK(other->end_of_unswept_pages_ == nullptr);
1017 1059
1018 AccountCommitted(other->CommittedMemory()); 1060 AccountCommitted(other->CommittedMemory());
1019 1061
1020 // Move over pages. 1062 // Move over pages.
1021 PageIterator it(other); 1063 PageIterator it(other);
1022 Page* p = nullptr; 1064 Page* p = nullptr;
1023 while (it.has_next()) { 1065 while (it.has_next()) {
1024 p = it.next(); 1066 p = it.next();
1025 p->Unlink(); 1067 p->Unlink();
1026 p->set_owner(this); 1068 p->set_owner(this);
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after
2385 page = Page::FromAddress(node->address()); 2427 page = Page::FromAddress(node->address());
2386 page->add_available_in_large_free_list(-(*node_size)); 2428 page->add_available_in_large_free_list(-(*node_size));
2387 } 2429 }
2388 } 2430 }
2389 2431
2390 DCHECK(IsVeryLong() || available() == SumFreeLists()); 2432 DCHECK(IsVeryLong() || available() == SumFreeLists());
2391 return node; 2433 return node;
2392 } 2434 }
2393 2435
2394 2436
2437 FreeSpace* FreeList::TryRemoveMemory(intptr_t size_in_bytes) {
ulan 2015/10/09 11:48:48 Could you please comment the postconditions of thi
Michael Lippautz 2015/10/09 12:20:13 Done. I added a high-level description to the .h f
2438 base::LockGuard<base::Mutex> guard(&mutex_);
2439 FreeSpace* node = nullptr;
2440 int node_size = 0;
2441 // Try to find a node that fits exactly.
2442 node = FindNodeFor(static_cast<int>(size_in_bytes), &node_size);
2443 // If no node could be found get as much memory as possible.
2444 if (node == nullptr) node = FindNodeIn(kHuge, &node_size);
2445 if (node == nullptr) node = FindNodeIn(kLarge, &node_size);
2446 if (node == nullptr) node = FindNodeIn(kMedium, &node_size);
2447 if (node == nullptr) node = FindNodeIn(kSmall, &node_size);
2448 if (node != nullptr) {
2449 // Give back left overs that were not required by {size_in_bytes}.
Michael Lippautz 2015/10/09 11:08:59 This could potentially increase fragmentation, but
2450 intptr_t aligned_size = RoundUp(size_in_bytes, kPointerSize);
2451 intptr_t left_over = node_size - aligned_size;
2452 if (left_over > 0) {
2453 Free(node->address() + aligned_size, static_cast<int>(left_over));
2454 node->set_size(static_cast<int>(aligned_size));
2455 }
2456 }
2457 return node;
2458 }
2459
2460
2395 // Allocation on the old space free list. If it succeeds then a new linear 2461 // Allocation on the old space free list. If it succeeds then a new linear
2396 // allocation space has been set up with the top and limit of the space. If 2462 // allocation space has been set up with the top and limit of the space. If
2397 // the allocation fails then NULL is returned, and the caller can perform a GC 2463 // the allocation fails then NULL is returned, and the caller can perform a GC
2398 // or allocate a new page before retrying. 2464 // or allocate a new page before retrying.
2399 HeapObject* FreeList::Allocate(int size_in_bytes) { 2465 HeapObject* FreeList::Allocate(int size_in_bytes) {
2400 DCHECK(0 < size_in_bytes); 2466 DCHECK(0 < size_in_bytes);
2401 DCHECK(size_in_bytes <= kMaxBlockSize); 2467 DCHECK(size_in_bytes <= kMaxBlockSize);
2402 DCHECK(IsAligned(size_in_bytes, kPointerSize)); 2468 DCHECK(IsAligned(size_in_bytes, kPointerSize));
2403 // Don't free list allocate if there is linear space available. 2469 // Don't free list allocate if there is linear space available.
2404 DCHECK(owner_->limit() - owner_->top() < size_in_bytes); 2470 DCHECK(owner_->limit() - owner_->top() < size_in_bytes);
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
3158 object->ShortPrint(); 3224 object->ShortPrint();
3159 PrintF("\n"); 3225 PrintF("\n");
3160 } 3226 }
3161 printf(" --------------------------------------\n"); 3227 printf(" --------------------------------------\n");
3162 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3228 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3163 } 3229 }
3164 3230
3165 #endif // DEBUG 3231 #endif // DEBUG
3166 } // namespace internal 3232 } // namespace internal
3167 } // namespace v8 3233 } // namespace v8
OLDNEW
« src/heap/mark-compact.cc ('K') | « src/heap/spaces.h ('k') | test/cctest/heap-tester.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698