| Index: src/heap/spaces.cc
|
| diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc
|
| index ff398b45fc00ad958bf5760eb2dbf880857d47ee..8fdca694a178d41f836533d43890cc612c896137 100644
|
| --- a/src/heap/spaces.cc
|
| +++ b/src/heap/spaces.cc
|
| @@ -2074,7 +2074,6 @@ intptr_t FreeListCategory::Concatenate(FreeListCategory* category) {
|
| category->end()->set_next(top());
|
| }
|
| set_top(category->top());
|
| - base::NoBarrier_Store(&top_, category->top_);
|
| available_ += category->available();
|
| category->Reset();
|
| }
|
| @@ -2083,9 +2082,9 @@ intptr_t FreeListCategory::Concatenate(FreeListCategory* category) {
|
|
|
|
|
| void FreeListCategory::Reset() {
|
| - set_top(NULL);
|
| - set_end(NULL);
|
| - set_available(0);
|
| + set_top(nullptr);
|
| + set_end(nullptr);
|
| + available_ = 0;
|
| }
|
|
|
|
|
| @@ -2160,6 +2159,55 @@ FreeSpace* FreeListCategory::PickNodeFromList(int size_in_bytes,
|
| }
|
|
|
|
|
| +FreeSpace* FreeListCategory::SearchForNodeInList(int size_in_bytes,
|
| + int* node_size) {
|
| + FreeSpace* return_node = nullptr;
|
| + FreeSpace* top_node = top();
|
| +
|
| + for (FreeSpace** node_it = &top_node; *node_it != NULL;
|
| + node_it = (*node_it)->next_address()) {
|
| + FreeSpace* cur_node = *node_it;
|
| + while (cur_node != NULL &&
|
| + Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) {
|
| + int size = cur_node->Size();
|
| + available_ -= size;
|
| + Page::FromAddress(cur_node->address())
|
| + ->add_available_in_free_list(type_, -size);
|
| + cur_node = cur_node->next();
|
| + }
|
| +
|
| + // Update iterator.
|
| + *node_it = cur_node;
|
| +
|
| + if (cur_node == nullptr) {
|
| + set_end(nullptr);
|
| + break;
|
| + }
|
| +
|
| + int size = cur_node->Size();
|
| + if (size >= size_in_bytes) {
|
| + // Large enough node found. Unlink it from the list.
|
| + return_node = cur_node;
|
| + *node_it = cur_node->next();
|
| + *node_size = size;
|
| + available_ -= size;
|
| + Page::FromAddress(return_node->address())
|
| + ->add_available_in_free_list(type_, -size);
|
| + break;
|
| + }
|
| + }
|
| +
|
| + // Top could've changed if we took the first node. Update top and end
|
| + // accordingly.
|
| + set_top(top_node);
|
| + if (top() == nullptr) {
|
| + set_end(nullptr);
|
| + }
|
| +
|
| + return return_node;
|
| +}
|
| +
|
| +
|
| void FreeListCategory::Free(FreeSpace* free_space, int size_in_bytes) {
|
| free_space->set_next(top());
|
| set_top(free_space);
|
| @@ -2188,10 +2236,10 @@ FreeList::FreeList(PagedSpace* owner)
|
| : owner_(owner),
|
| heap_(owner->heap()),
|
| wasted_bytes_(0),
|
| - small_list_(this),
|
| - medium_list_(this),
|
| - large_list_(this),
|
| - huge_list_(this) {
|
| + small_list_(this, kSmall),
|
| + medium_list_(this, kMedium),
|
| + large_list_(this, kLarge),
|
| + huge_list_(this, kHuge) {
|
| Reset();
|
| }
|
|
|
| @@ -2302,44 +2350,7 @@ FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
|
| }
|
| }
|
|
|
| - int huge_list_available = huge_list_.available();
|
| - FreeSpace* top_node = huge_list_.top();
|
| - for (FreeSpace** cur = &top_node; *cur != NULL;
|
| - cur = (*cur)->next_address()) {
|
| - FreeSpace* cur_node = *cur;
|
| - while (cur_node != NULL &&
|
| - Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) {
|
| - int size = cur_node->Size();
|
| - huge_list_available -= size;
|
| - page = Page::FromAddress(cur_node->address());
|
| - page->add_available_in_huge_free_list(-size);
|
| - cur_node = cur_node->next();
|
| - }
|
| -
|
| - *cur = cur_node;
|
| - if (cur_node == NULL) {
|
| - huge_list_.set_end(NULL);
|
| - break;
|
| - }
|
| -
|
| - int size = cur_node->Size();
|
| - if (size >= size_in_bytes) {
|
| - // Large enough node found. Unlink it from the list.
|
| - node = *cur;
|
| - *cur = node->next();
|
| - *node_size = size;
|
| - huge_list_available -= size;
|
| - page = Page::FromAddress(node->address());
|
| - page->add_available_in_huge_free_list(-size);
|
| - break;
|
| - }
|
| - }
|
| -
|
| - huge_list_.set_top(top_node);
|
| - if (huge_list_.top() == NULL) {
|
| - huge_list_.set_end(NULL);
|
| - }
|
| - huge_list_.set_available(huge_list_available);
|
| + node = huge_list_.SearchForNodeInList(size_in_bytes, node_size);
|
|
|
| if (node != NULL) {
|
| DCHECK(IsVeryLong() || available() == SumFreeLists());
|
|
|