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

Unified Diff: src/spaces.cc

Issue 11348174: Prepare FreeList for parallel and concurrent sweeping. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 1 month 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
« src/spaces.h ('K') | « src/spaces.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/spaces.cc
diff --git a/src/spaces.cc b/src/spaces.cc
index 0ac23d279db6d5c13e3d9b0b67206cdd7f983ce0..66307f6c5df0fca8e35019fa1073dfc4f617c2f4 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -1937,10 +1937,67 @@ FreeList::FreeList(PagedSpace* owner)
void FreeList::Reset() {
available_ = 0;
- small_list_ = NULL;
- medium_list_ = NULL;
- large_list_ = NULL;
- huge_list_ = NULL;
+ Reset(&small_list_);
+ Reset(&medium_list_);
+ Reset(&large_list_);
+ Reset(&huge_list_);
+}
+
+
+void FreeList::Reset(FreeListCategorie *categorie) {
+ categorie->top = NULL;
+ categorie->end = NULL;
+}
+
+
+void FreeList::GetList(struct FreeListCategorie *categorie,
+ FreeListNode** top,
+ FreeListNode** end) {
+ *top = categorie->top;
+ *end = categorie->end;
+ categorie->top = NULL;
+ categorie->end = NULL;
+}
+
+
+void AddList(struct FreeListCategorie *categorie,
+ FreeListNode* top,
+ FreeListNode* end) {
+ end->set_next(categorie->top);
+ categorie->top = top;
+}
+
+
+void FreeList::ConcurrentGetList(struct FreeListCategorie *categorie,
+ FreeListNode** top,
+ FreeListNode** end) {
+ do {
+ *top = categorie->top;
+ *end = categorie->end;
+ } while (*top != categorie->top ||
+ NoBarrier_CompareAndSwap(
+ reinterpret_cast<AtomicWord*>(&categorie->top),
+ reinterpret_cast<AtomicWord>(*top), 0) !=
+ reinterpret_cast<AtomicWord>(*top));
+ NoBarrier_CompareAndSwap(
+ reinterpret_cast<AtomicWord*>(&categorie->end),
+ reinterpret_cast<AtomicWord>(*end), 0);
+}
+
+
+void ConcurrentAddList(struct FreeListCategorie *categorie,
+ FreeListNode* top,
+ FreeListNode* end) {
+ FreeListNode* current_top;
+ do {
+ current_top = categorie->top;
+ end->set_next(current_top);
+ } while(current_top != categorie->top ||
+ NoBarrier_CompareAndSwap(
+ reinterpret_cast<AtomicWord*>(&categorie->top),
+ reinterpret_cast<AtomicWord>(current_top),
+ reinterpret_cast<AtomicWord>(top)) !=
+ reinterpret_cast<AtomicWord>(current_top));
}
@@ -1955,17 +2012,29 @@ int FreeList::Free(Address start, int size_in_bytes) {
// Insert other blocks at the head of a free list of the appropriate
// magnitude.
if (size_in_bytes <= kSmallListMax) {
- node->set_next(small_list_);
- small_list_ = node;
+ node->set_next(small_list_.top);
+ small_list_.top = node;
+ if (small_list_.end == NULL) {
+ small_list_.end = node;
+ }
} else if (size_in_bytes <= kMediumListMax) {
- node->set_next(medium_list_);
- medium_list_ = node;
+ node->set_next(medium_list_.top);
+ medium_list_.top = node;
+ if (medium_list_.end == NULL) {
+ medium_list_.end = node;
+ }
} else if (size_in_bytes <= kLargeListMax) {
- node->set_next(large_list_);
- large_list_ = node;
+ node->set_next(large_list_.top);
+ large_list_.top = node;
+ if (large_list_.end == NULL) {
+ large_list_.end = node;
+ }
} else {
- node->set_next(huge_list_);
- huge_list_ = node;
+ node->set_next(huge_list_.top);
+ huge_list_.top = node;
+ if (huge_list_.end == NULL) {
+ huge_list_.end = node;
+ }
}
available_ += size_in_bytes;
ASSERT(IsVeryLong() || available_ == SumFreeLists());
@@ -1973,8 +2042,9 @@ int FreeList::Free(Address start, int size_in_bytes) {
}
-FreeListNode* FreeList::PickNodeFromList(FreeListNode** list, int* node_size) {
- FreeListNode* node = *list;
+FreeListNode* FreeList::PickNodeFromList(FreeListCategorie* categorie,
+ int* node_size) {
+ FreeListNode* node = categorie->top;
if (node == NULL) return NULL;
@@ -1986,9 +2056,13 @@ FreeListNode* FreeList::PickNodeFromList(FreeListNode** list, int* node_size) {
if (node != NULL) {
*node_size = node->Size();
- *list = node->next();
+ categorie->top = node->next();
} else {
- *list = NULL;
+ categorie->top = NULL;
+ }
+
+ if (categorie->top == NULL) {
+ categorie->end = NULL;
}
return node;
@@ -2013,7 +2087,7 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
if (node != NULL) return node;
}
- for (FreeListNode** cur = &huge_list_;
+ for (FreeListNode** cur = &(huge_list_.top);
*cur != NULL;
cur = (*cur)->next_address()) {
FreeListNode* cur_node = *cur;
@@ -2024,7 +2098,10 @@ FreeListNode* FreeList::FindNodeFor(int size_in_bytes, int* node_size) {
}
*cur = cur_node;
- if (cur_node == NULL) break;
+ if (cur_node == NULL) {
+ huge_list_.end = NULL;
+ break;
+ }
ASSERT((*cur)->map() == HEAP->raw_unchecked_free_space_map());
FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(*cur);
@@ -2116,8 +2193,10 @@ HeapObject* FreeList::Allocate(int size_in_bytes) {
}
-static intptr_t CountFreeListItemsInList(FreeListNode* n, Page* p) {
+static intptr_t CountFreeListItemsInList(FreeListCategorie* categorie,
Michael Starzinger 2012/11/27 13:51:53 I think the code would be easier to read if the st
Hannes Payer (out of office) 2012/11/29 13:17:42 Done. Now we just call the method on the given obj
+ Page* p) {
intptr_t sum = 0;
+ FreeListNode* n = categorie->top;
while (n != NULL) {
if (Page::FromAddress(n->address()) == p) {
FreeSpace* free_space = reinterpret_cast<FreeSpace*>(n);
@@ -2130,11 +2209,11 @@ static intptr_t CountFreeListItemsInList(FreeListNode* n, Page* p) {
void FreeList::CountFreeListItems(Page* p, SizeStats* sizes) {
- sizes->huge_size_ = CountFreeListItemsInList(huge_list_, p);
+ sizes->huge_size_ = CountFreeListItemsInList(&huge_list_, p);
if (sizes->huge_size_ < p->area_size()) {
- sizes->small_size_ = CountFreeListItemsInList(small_list_, p);
- sizes->medium_size_ = CountFreeListItemsInList(medium_list_, p);
- sizes->large_size_ = CountFreeListItemsInList(large_list_, p);
+ sizes->small_size_ = CountFreeListItemsInList(&small_list_, p);
+ sizes->medium_size_ = CountFreeListItemsInList(&medium_list_, p);
+ sizes->large_size_ = CountFreeListItemsInList(&large_list_, p);
} else {
sizes->small_size_ = 0;
sizes->medium_size_ = 0;
@@ -2143,8 +2222,10 @@ void FreeList::CountFreeListItems(Page* p, SizeStats* sizes) {
}
-static intptr_t EvictFreeListItemsInList(FreeListNode** n, Page* p) {
+static intptr_t EvictFreeListItemsInList(FreeListCategorie* categorie,
+ Page* p) {
intptr_t sum = 0;
+ FreeListNode** n = &(categorie->top);
while (*n != NULL) {
if (Page::FromAddress((*n)->address()) == p) {
FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n);
@@ -2174,8 +2255,9 @@ intptr_t FreeList::EvictFreeListItems(Page* p) {
#ifdef DEBUG
-intptr_t FreeList::SumFreeList(FreeListNode* cur) {
+intptr_t FreeList::SumFreeList(FreeListCategorie* categorie) {
intptr_t sum = 0;
+ FreeListNode* cur = categorie->top;
while (cur != NULL) {
ASSERT(cur->map() == HEAP->raw_unchecked_free_space_map());
FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(cur);
@@ -2189,8 +2271,9 @@ intptr_t FreeList::SumFreeList(FreeListNode* cur) {
static const int kVeryLongFreeList = 500;
-int FreeList::FreeListLength(FreeListNode* cur) {
+int FreeList::FreeListLength(FreeListCategorie* categorie) {
int length = 0;
+ FreeListNode* cur = categorie->top;
while (cur != NULL) {
length++;
cur = cur->next();
@@ -2201,10 +2284,10 @@ int FreeList::FreeListLength(FreeListNode* cur) {
bool FreeList::IsVeryLong() {
- if (FreeListLength(small_list_) == kVeryLongFreeList) return true;
- if (FreeListLength(medium_list_) == kVeryLongFreeList) return true;
- if (FreeListLength(large_list_) == kVeryLongFreeList) return true;
- if (FreeListLength(huge_list_) == kVeryLongFreeList) return true;
+ if (FreeListLength(&small_list_) == kVeryLongFreeList) return true;
+ if (FreeListLength(&medium_list_) == kVeryLongFreeList) return true;
+ if (FreeListLength(&large_list_) == kVeryLongFreeList) return true;
+ if (FreeListLength(&huge_list_) == kVeryLongFreeList) return true;
return false;
}
@@ -2213,10 +2296,10 @@ bool FreeList::IsVeryLong() {
// on the free list, so it should not be called if FreeListLength returns
// kVeryLongFreeList.
intptr_t FreeList::SumFreeLists() {
- intptr_t sum = SumFreeList(small_list_);
- sum += SumFreeList(medium_list_);
- sum += SumFreeList(large_list_);
- sum += SumFreeList(huge_list_);
+ intptr_t sum = SumFreeList(&small_list_);
+ sum += SumFreeList(&medium_list_);
+ sum += SumFreeList(&large_list_);
+ sum += SumFreeList(&huge_list_);
return sum;
}
#endif
@@ -2318,10 +2401,10 @@ static void RepairFreeList(Heap* heap, FreeListNode* n) {
void FreeList::RepairLists(Heap* heap) {
- RepairFreeList(heap, small_list_);
- RepairFreeList(heap, medium_list_);
- RepairFreeList(heap, large_list_);
- RepairFreeList(heap, huge_list_);
+ RepairFreeList(heap, small_list_.top);
+ RepairFreeList(heap, medium_list_.top);
+ RepairFreeList(heap, large_list_.top);
+ RepairFreeList(heap, huge_list_.top);
}
« src/spaces.h ('K') | « src/spaces.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698