From e18aff1c4b89416ade960fe8545c819f721cc847 Mon Sep 17 00:00:00 2001 From: "hpayer@chromium.org" Date: Thu, 13 Feb 2014 15:01:10 +0000 Subject: [PATCH] Use NoBarrier_Load and NoBarrier_Store in FreeListCategory::Concatenate. BUG= R=jarin@chromium.org Review URL: https://codereview.chromium.org/138953018 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19355 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/spaces.cc | 47 ++++++++++++++++++++++++++--------------------- src/spaces.h | 17 +++++++++++------ 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/spaces.cc b/src/spaces.cc index 08b8531..aec5191 100644 --- a/src/spaces.cc +++ b/src/spaces.cc @@ -2075,20 +2075,21 @@ void FreeListNode::set_next(FreeListNode* next) { intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { intptr_t free_bytes = 0; - if (category->top_ != NULL) { - ASSERT(category->end_ != NULL); + 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. LockGuard target_lock_guard(mutex()); LockGuard source_lock_guard(category->mutex()); + ASSERT(category->end_ != NULL); free_bytes = category->available(); if (end_ == NULL) { end_ = category->end(); } else { - category->end()->set_next(top_); + category->end()->set_next(top()); } - top_ = category->top(); + set_top(category->top()); + NoBarrier_Store(&top_, category->top_); available_ += category->available(); category->Reset(); } @@ -2097,15 +2098,16 @@ intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { void FreeListCategory::Reset() { - top_ = NULL; - end_ = NULL; - available_ = 0; + set_top(NULL); + set_end(NULL); + set_available(0); } intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) { int sum = 0; - FreeListNode** n = &top_; + FreeListNode* t = top(); + FreeListNode** n = &t; while (*n != NULL) { if (Page::FromAddress((*n)->address()) == p) { FreeSpace* free_space = reinterpret_cast(*n); @@ -2115,8 +2117,9 @@ intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) { n = (*n)->next_address(); } } - if (top_ == NULL) { - end_ = NULL; + set_top(t); + if (top() == NULL) { + set_end(NULL); } available_ -= sum; return sum; @@ -2124,17 +2127,17 @@ intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) { bool FreeListCategory::ContainsPageFreeListItemsInList(Page* p) { - FreeListNode** n = &top_; - while (*n != NULL) { - if (Page::FromAddress((*n)->address()) == p) return true; - n = (*n)->next_address(); + FreeListNode* node = top(); + while (node != NULL) { + if (Page::FromAddress(node->address()) == p) return true; + node = node->next(); } return false; } FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { - FreeListNode* node = top_; + FreeListNode* node = top(); if (node == NULL) return NULL; @@ -2173,8 +2176,8 @@ FreeListNode* FreeListCategory::PickNodeFromList(int size_in_bytes, void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { - node->set_next(top_); - top_ = node; + node->set_next(top()); + set_top(node); if (end_ == NULL) { end_ = node; } @@ -2183,7 +2186,7 @@ void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { void FreeListCategory::RepairFreeList(Heap* heap) { - FreeListNode* n = top_; + FreeListNode* n = top(); while (n != NULL) { Map** map_location = reinterpret_cast(n->address()); if (*map_location == NULL) { @@ -2292,7 +2295,8 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { } int huge_list_available = huge_list_.available(); - for (FreeListNode** cur = huge_list_.GetTopAddress(); + FreeListNode* top_node = huge_list_.top(); + for (FreeListNode** cur = &top_node; *cur != NULL; cur = (*cur)->next_address()) { FreeListNode* cur_node = *cur; @@ -2326,6 +2330,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { } } + huge_list_.set_top(top_node); if (huge_list_.top() == NULL) { huge_list_.set_end(NULL); } @@ -2479,7 +2484,7 @@ void FreeList::RepairLists(Heap* heap) { #ifdef DEBUG intptr_t FreeListCategory::SumFreeList() { intptr_t sum = 0; - FreeListNode* cur = top_; + FreeListNode* cur = top(); while (cur != NULL) { ASSERT(cur->map() == cur->GetHeap()->raw_unchecked_free_space_map()); FreeSpace* cur_as_free_space = reinterpret_cast(cur); @@ -2495,7 +2500,7 @@ static const int kVeryLongFreeList = 500; int FreeListCategory::FreeListLength() { int length = 0; - FreeListNode* cur = top_; + FreeListNode* cur = top(); while (cur != NULL) { length++; cur = cur->next(); diff --git a/src/spaces.h b/src/spaces.h index 6d3b5fc..bc01719 100644 --- a/src/spaces.h +++ b/src/spaces.h @@ -1518,7 +1518,7 @@ class FreeListNode: public HeapObject { class FreeListCategory { public: FreeListCategory() : - top_(NULL), + top_(0), end_(NULL), available_(0) {} @@ -1536,9 +1536,13 @@ class FreeListCategory { void RepairFreeList(Heap* heap); - FreeListNode** GetTopAddress() { return &top_; } - FreeListNode* top() const { return top_; } - void set_top(FreeListNode* top) { top_ = top; } + FreeListNode* top() const { + return reinterpret_cast(NoBarrier_Load(&top_)); + } + + void set_top(FreeListNode* top) { + NoBarrier_Store(&top_, reinterpret_cast(top)); + } FreeListNode** GetEndAddress() { return &end_; } FreeListNode* end() const { return end_; } @@ -1551,7 +1555,7 @@ class FreeListCategory { Mutex* mutex() { return &mutex_; } bool IsEmpty() { - return top_ == NULL; + return top() == 0; } #ifdef DEBUG @@ -1560,7 +1564,8 @@ class FreeListCategory { #endif private: - FreeListNode* top_; + // top_ points to the top FreeListNode* in the free list category. + AtomicWord top_; FreeListNode* end_; Mutex mutex_; -- 2.7.4