| Index: src/heap/spaces.cc
|
| diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc
|
| index b973a4ae60552bcaa707e659bc5cdbe8aadedef0..3d13144b0fad703880e30c365b9cb991c71f1171 100644
|
| --- a/src/heap/spaces.cc
|
| +++ b/src/heap/spaces.cc
|
| @@ -1014,7 +1014,7 @@ void PagedSpace::MergeCompactionSpace(CompactionSpace* other) {
|
|
|
| // Update and clear accounting statistics.
|
| accounting_stats_.Merge(other->accounting_stats_);
|
| - other->accounting_stats_.Reset();
|
| + other->accounting_stats_.Clear();
|
|
|
| // Move over pages.
|
| PageIterator it(other);
|
| @@ -2211,6 +2211,44 @@ intptr_t FreeList::Concatenate(FreeList* free_list) {
|
| }
|
|
|
|
|
| +FreeSpace* PagedSpace::TryRemoveMemory() {
|
| + FreeSpace* space = nullptr;
|
| + int node_size = 0;
|
| + space = free_list()->FindNodeIn(FreeList::kHuge, &node_size);
|
| + if (space == nullptr)
|
| + space = free_list()->FindNodeIn(FreeList::kLarge, &node_size);
|
| + if (space == nullptr)
|
| + space = free_list()->FindNodeIn(FreeList::kMedium, &node_size);
|
| + if (space == nullptr)
|
| + space = free_list()->FindNodeIn(FreeList::kSmall, &node_size);
|
| + if (space != nullptr) {
|
| + accounting_stats_.AllocateBytes(node_size);
|
| + }
|
| + return space;
|
| +}
|
| +
|
| +
|
| +void PagedSpace::DivideMemory(CompactionSpaceCollection** other, int num,
|
| + intptr_t limit) {
|
| + CHECK(num > 0);
|
| + CHECK(other != nullptr);
|
| +
|
| + if (limit == 0) limit = std::numeric_limits<intptr_t>::max();
|
| +
|
| + EmptyAllocationInfo();
|
| +
|
| + int index = 0;
|
| + FreeSpace* node = nullptr;
|
| + for (CompactionSpace* space = other[index]->Get(identity());
|
| + ((node = TryRemoveMemory()) != nullptr) &&
|
| + (space->free_list()->available() < limit);
|
| + space = other[++index % num]->Get(identity())) {
|
| + CHECK(space->identity() == identity());
|
| + space->AddMemory(node->address(), node->size());
|
| + }
|
| +}
|
| +
|
| +
|
| void FreeList::Reset() {
|
| small_list_.Reset();
|
| medium_list_.Reset();
|
| @@ -2254,39 +2292,62 @@ int FreeList::Free(Address start, int size_in_bytes) {
|
| }
|
|
|
|
|
| +void FreeList::UpdateFragmentationStats(FreeListCategoryType category,
|
| + Address address, int size) {
|
| + Page* page = Page::FromAddress(address);
|
| + switch (category) {
|
| + case kSmall:
|
| + page->add_available_in_small_free_list(size);
|
| + break;
|
| + case kMedium:
|
| + page->add_available_in_medium_free_list(size);
|
| + break;
|
| + case kLarge:
|
| + page->add_available_in_large_free_list(size);
|
| + break;
|
| + case kHuge:
|
| + page->add_available_in_huge_free_list(size);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +
|
| +FreeSpace* FreeList::FindNodeIn(FreeListCategoryType category, int* node_size) {
|
| + FreeSpace* node = GetFreeListCategory(category)->PickNodeFromList(node_size);
|
| + if (node != nullptr) {
|
| + UpdateFragmentationStats(category, node->address(), -(*node_size));
|
| + DCHECK(IsVeryLong() || available() == SumFreeLists());
|
| + }
|
| + return node;
|
| +}
|
| +
|
| +
|
| FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
|
| FreeSpace* node = NULL;
|
| Page* page = NULL;
|
|
|
| if (size_in_bytes <= kSmallAllocationMax) {
|
| - node = small_list_.PickNodeFromList(node_size);
|
| - if (node != NULL) {
|
| - DCHECK(size_in_bytes <= *node_size);
|
| - page = Page::FromAddress(node->address());
|
| - page->add_available_in_small_free_list(-(*node_size));
|
| - DCHECK(IsVeryLong() || available() == SumFreeLists());
|
| + node = FindNodeIn(kSmall, node_size);
|
| + if (node != nullptr) {
|
| + DCHECK(size_in_bytes <= node->size());
|
| return node;
|
| }
|
| }
|
|
|
| if (size_in_bytes <= kMediumAllocationMax) {
|
| - node = medium_list_.PickNodeFromList(node_size);
|
| - if (node != NULL) {
|
| - DCHECK(size_in_bytes <= *node_size);
|
| - page = Page::FromAddress(node->address());
|
| - page->add_available_in_medium_free_list(-(*node_size));
|
| - DCHECK(IsVeryLong() || available() == SumFreeLists());
|
| + node = FindNodeIn(kMedium, node_size);
|
| + if (node != nullptr) {
|
| + DCHECK(size_in_bytes <= node->size());
|
| return node;
|
| }
|
| }
|
|
|
| if (size_in_bytes <= kLargeAllocationMax) {
|
| - node = large_list_.PickNodeFromList(node_size);
|
| - if (node != NULL) {
|
| - DCHECK(size_in_bytes <= *node_size);
|
| - page = Page::FromAddress(node->address());
|
| - page->add_available_in_large_free_list(-(*node_size));
|
| - DCHECK(IsVeryLong() || available() == SumFreeLists());
|
| + node = FindNodeIn(kLarge, node_size);
|
| + if (node != nullptr) {
|
| + DCHECK(size_in_bytes <= node->size());
|
| return node;
|
| }
|
| }
|
| @@ -2542,7 +2603,6 @@ intptr_t PagedSpace::SizeOfObjects() {
|
| (unswept_free_bytes_ == 0));
|
| const intptr_t size = Size() - unswept_free_bytes_ - (limit() - top());
|
| DCHECK_GE(size, 0);
|
| - USE(size);
|
| return size;
|
| }
|
|
|
|
|