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

Side by Side Diff: src/spaces.cc

Issue 181453002: Reset trunk to 3.24.35.4 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/spaces.h ('k') | src/stub-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 chunk->area_start_ = area_start; 476 chunk->area_start_ = area_start;
477 chunk->area_end_ = area_end; 477 chunk->area_end_ = area_end;
478 chunk->flags_ = 0; 478 chunk->flags_ = 0;
479 chunk->set_owner(owner); 479 chunk->set_owner(owner);
480 chunk->InitializeReservedMemory(); 480 chunk->InitializeReservedMemory();
481 chunk->slots_buffer_ = NULL; 481 chunk->slots_buffer_ = NULL;
482 chunk->skip_list_ = NULL; 482 chunk->skip_list_ = NULL;
483 chunk->write_barrier_counter_ = kWriteBarrierCounterGranularity; 483 chunk->write_barrier_counter_ = kWriteBarrierCounterGranularity;
484 chunk->progress_bar_ = 0; 484 chunk->progress_bar_ = 0;
485 chunk->high_water_mark_ = static_cast<int>(area_start - base); 485 chunk->high_water_mark_ = static_cast<int>(area_start - base);
486 chunk->set_parallel_sweeping(PARALLEL_SWEEPING_DONE); 486 chunk->parallel_sweeping_ = 0;
487 chunk->available_in_small_free_list_ = 0; 487 chunk->available_in_small_free_list_ = 0;
488 chunk->available_in_medium_free_list_ = 0; 488 chunk->available_in_medium_free_list_ = 0;
489 chunk->available_in_large_free_list_ = 0; 489 chunk->available_in_large_free_list_ = 0;
490 chunk->available_in_huge_free_list_ = 0; 490 chunk->available_in_huge_free_list_ = 0;
491 chunk->non_available_small_blocks_ = 0; 491 chunk->non_available_small_blocks_ = 0;
492 chunk->ResetLiveBytes(); 492 chunk->ResetLiveBytes();
493 Bitmap::Clear(chunk); 493 Bitmap::Clear(chunk);
494 chunk->initialize_scan_on_scavenge(false); 494 chunk->initialize_scan_on_scavenge(false);
495 chunk->SetFlag(WAS_SWEPT_PRECISELY); 495 chunk->SetFlag(WAS_SWEPT_PRECISELY);
496 496
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 if (!code_range->UncommitRawMemory(start, length)) return false; 553 if (!code_range->UncommitRawMemory(start, length)) return false;
554 } 554 }
555 } 555 }
556 556
557 area_end_ = area_start_ + requested; 557 area_end_ = area_start_ + requested;
558 return true; 558 return true;
559 } 559 }
560 560
561 561
562 void MemoryChunk::InsertAfter(MemoryChunk* other) { 562 void MemoryChunk::InsertAfter(MemoryChunk* other) {
563 MemoryChunk* other_next = other->next_chunk(); 563 next_chunk_ = other->next_chunk_;
564 prev_chunk_ = other;
564 565
565 set_next_chunk(other_next); 566 // This memory barrier is needed since concurrent sweeper threads may iterate
566 set_prev_chunk(other); 567 // over the list of pages while a new page is inserted.
567 other_next->set_prev_chunk(this); 568 // TODO(hpayer): find a cleaner way to guarantee that the page list can be
568 other->set_next_chunk(this); 569 // expanded concurrently
570 MemoryBarrier();
571
572 // The following two write operations can take effect in arbitrary order
573 // since pages are always iterated by the sweeper threads in LIFO order, i.e,
574 // the inserted page becomes visible for the sweeper threads after
575 // other->next_chunk_ = this;
576 other->next_chunk_->prev_chunk_ = this;
577 other->next_chunk_ = this;
569 } 578 }
570 579
571 580
572 void MemoryChunk::Unlink() { 581 void MemoryChunk::Unlink() {
573 if (!InNewSpace() && IsFlagSet(SCAN_ON_SCAVENGE)) { 582 if (!InNewSpace() && IsFlagSet(SCAN_ON_SCAVENGE)) {
574 heap_->decrement_scan_on_scavenge_pages(); 583 heap_->decrement_scan_on_scavenge_pages();
575 ClearFlag(SCAN_ON_SCAVENGE); 584 ClearFlag(SCAN_ON_SCAVENGE);
576 } 585 }
577 MemoryChunk* next_element = next_chunk(); 586 next_chunk_->prev_chunk_ = prev_chunk_;
578 MemoryChunk* prev_element = prev_chunk(); 587 prev_chunk_->next_chunk_ = next_chunk_;
579 next_element->set_prev_chunk(prev_element); 588 prev_chunk_ = NULL;
580 prev_element->set_next_chunk(next_element); 589 next_chunk_ = NULL;
581 set_prev_chunk(NULL);
582 set_next_chunk(NULL);
583 } 590 }
584 591
585 592
586 MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t reserve_area_size, 593 MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t reserve_area_size,
587 intptr_t commit_area_size, 594 intptr_t commit_area_size,
588 Executability executable, 595 Executability executable,
589 Space* owner) { 596 Space* owner) {
590 ASSERT(commit_area_size <= reserve_area_size); 597 ASSERT(commit_area_size <= reserve_area_size);
591 598
592 size_t chunk_size; 599 size_t chunk_size;
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 reinterpret_cast<Address>(next); 2075 reinterpret_cast<Address>(next);
2069 } else { 2076 } else {
2070 Memory::Address_at(address() + kPointerSize) = 2077 Memory::Address_at(address() + kPointerSize) =
2071 reinterpret_cast<Address>(next); 2078 reinterpret_cast<Address>(next);
2072 } 2079 }
2073 } 2080 }
2074 2081
2075 2082
2076 intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { 2083 intptr_t FreeListCategory::Concatenate(FreeListCategory* category) {
2077 intptr_t free_bytes = 0; 2084 intptr_t free_bytes = 0;
2078 if (category->top() != NULL) { 2085 if (category->top_ != NULL) {
2086 ASSERT(category->end_ != NULL);
2079 // This is safe (not going to deadlock) since Concatenate operations 2087 // This is safe (not going to deadlock) since Concatenate operations
2080 // are never performed on the same free lists at the same time in 2088 // are never performed on the same free lists at the same time in
2081 // reverse order. 2089 // reverse order.
2082 LockGuard<Mutex> target_lock_guard(mutex()); 2090 LockGuard<Mutex> target_lock_guard(mutex());
2083 LockGuard<Mutex> source_lock_guard(category->mutex()); 2091 LockGuard<Mutex> source_lock_guard(category->mutex());
2084 ASSERT(category->end_ != NULL);
2085 free_bytes = category->available(); 2092 free_bytes = category->available();
2086 if (end_ == NULL) { 2093 if (end_ == NULL) {
2087 end_ = category->end(); 2094 end_ = category->end();
2088 } else { 2095 } else {
2089 category->end()->set_next(top()); 2096 category->end()->set_next(top_);
2090 } 2097 }
2091 set_top(category->top()); 2098 top_ = category->top();
2092 NoBarrier_Store(&top_, category->top_);
2093 available_ += category->available(); 2099 available_ += category->available();
2094 category->Reset(); 2100 category->Reset();
2095 } 2101 }
2096 return free_bytes; 2102 return free_bytes;
2097 } 2103 }
2098 2104
2099 2105
2100 void FreeListCategory::Reset() { 2106 void FreeListCategory::Reset() {
2101 set_top(NULL); 2107 top_ = NULL;
2102 set_end(NULL); 2108 end_ = NULL;
2103 set_available(0); 2109 available_ = 0;
2104 } 2110 }
2105 2111
2106 2112
2107 intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) { 2113 intptr_t FreeListCategory::EvictFreeListItemsInList(Page* p) {
2108 int sum = 0; 2114 int sum = 0;
2109 FreeListNode* t = top(); 2115 FreeListNode** n = &top_;
2110 FreeListNode** n = &t;
2111 while (*n != NULL) { 2116 while (*n != NULL) {
2112 if (Page::FromAddress((*n)->address()) == p) { 2117 if (Page::FromAddress((*n)->address()) == p) {
2113 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n); 2118 FreeSpace* free_space = reinterpret_cast<FreeSpace*>(*n);
2114 sum += free_space->Size(); 2119 sum += free_space->Size();
2115 *n = (*n)->next(); 2120 *n = (*n)->next();
2116 } else { 2121 } else {
2117 n = (*n)->next_address(); 2122 n = (*n)->next_address();
2118 } 2123 }
2119 } 2124 }
2120 set_top(t); 2125 if (top_ == NULL) {
2121 if (top() == NULL) { 2126 end_ = NULL;
2122 set_end(NULL);
2123 } 2127 }
2124 available_ -= sum; 2128 available_ -= sum;
2125 return sum; 2129 return sum;
2126 } 2130 }
2127 2131
2128 2132
2129 bool FreeListCategory::ContainsPageFreeListItemsInList(Page* p) { 2133 bool FreeListCategory::ContainsPageFreeListItemsInList(Page* p) {
2130 FreeListNode* node = top(); 2134 FreeListNode** n = &top_;
2131 while (node != NULL) { 2135 while (*n != NULL) {
2132 if (Page::FromAddress(node->address()) == p) return true; 2136 if (Page::FromAddress((*n)->address()) == p) return true;
2133 node = node->next(); 2137 n = (*n)->next_address();
2134 } 2138 }
2135 return false; 2139 return false;
2136 } 2140 }
2137 2141
2138 2142
2139 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) { 2143 FreeListNode* FreeListCategory::PickNodeFromList(int *node_size) {
2140 FreeListNode* node = top(); 2144 FreeListNode* node = top_;
2141 2145
2142 if (node == NULL) return NULL; 2146 if (node == NULL) return NULL;
2143 2147
2144 while (node != NULL && 2148 while (node != NULL &&
2145 Page::FromAddress(node->address())->IsEvacuationCandidate()) { 2149 Page::FromAddress(node->address())->IsEvacuationCandidate()) {
2146 available_ -= reinterpret_cast<FreeSpace*>(node)->Size(); 2150 available_ -= reinterpret_cast<FreeSpace*>(node)->Size();
2147 node = node->next(); 2151 node = node->next();
2148 } 2152 }
2149 2153
2150 if (node != NULL) { 2154 if (node != NULL) {
(...skipping 18 matching lines...) Expand all
2169 if (node != NULL && *node_size < size_in_bytes) { 2173 if (node != NULL && *node_size < size_in_bytes) {
2170 Free(node, *node_size); 2174 Free(node, *node_size);
2171 *node_size = 0; 2175 *node_size = 0;
2172 return NULL; 2176 return NULL;
2173 } 2177 }
2174 return node; 2178 return node;
2175 } 2179 }
2176 2180
2177 2181
2178 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) { 2182 void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) {
2179 node->set_next(top()); 2183 node->set_next(top_);
2180 set_top(node); 2184 top_ = node;
2181 if (end_ == NULL) { 2185 if (end_ == NULL) {
2182 end_ = node; 2186 end_ = node;
2183 } 2187 }
2184 available_ += size_in_bytes; 2188 available_ += size_in_bytes;
2185 } 2189 }
2186 2190
2187 2191
2188 void FreeListCategory::RepairFreeList(Heap* heap) { 2192 void FreeListCategory::RepairFreeList(Heap* heap) {
2189 FreeListNode* n = top(); 2193 FreeListNode* n = top_;
2190 while (n != NULL) { 2194 while (n != NULL) {
2191 Map** map_location = reinterpret_cast<Map**>(n->address()); 2195 Map** map_location = reinterpret_cast<Map**>(n->address());
2192 if (*map_location == NULL) { 2196 if (*map_location == NULL) {
2193 *map_location = heap->free_space_map(); 2197 *map_location = heap->free_space_map();
2194 } else { 2198 } else {
2195 ASSERT(*map_location == heap->free_space_map()); 2199 ASSERT(*map_location == heap->free_space_map());
2196 } 2200 }
2197 n = n->next(); 2201 n = n->next();
2198 } 2202 }
2199 } 2203 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 if (node != NULL) { 2292 if (node != NULL) {
2289 ASSERT(size_in_bytes <= *node_size); 2293 ASSERT(size_in_bytes <= *node_size);
2290 page = Page::FromAddress(node->address()); 2294 page = Page::FromAddress(node->address());
2291 page->add_available_in_large_free_list(-(*node_size)); 2295 page->add_available_in_large_free_list(-(*node_size));
2292 ASSERT(IsVeryLong() || available() == SumFreeLists()); 2296 ASSERT(IsVeryLong() || available() == SumFreeLists());
2293 return node; 2297 return node;
2294 } 2298 }
2295 } 2299 }
2296 2300
2297 int huge_list_available = huge_list_.available(); 2301 int huge_list_available = huge_list_.available();
2298 FreeListNode* top_node = huge_list_.top(); 2302 for (FreeListNode** cur = huge_list_.GetTopAddress();
2299 for (FreeListNode** cur = &top_node;
2300 *cur != NULL; 2303 *cur != NULL;
2301 cur = (*cur)->next_address()) { 2304 cur = (*cur)->next_address()) {
2302 FreeListNode* cur_node = *cur; 2305 FreeListNode* cur_node = *cur;
2303 while (cur_node != NULL && 2306 while (cur_node != NULL &&
2304 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) { 2307 Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) {
2305 int size = reinterpret_cast<FreeSpace*>(cur_node)->Size(); 2308 int size = reinterpret_cast<FreeSpace*>(cur_node)->Size();
2306 huge_list_available -= size; 2309 huge_list_available -= size;
2307 page = Page::FromAddress(cur_node->address()); 2310 page = Page::FromAddress(cur_node->address());
2308 page->add_available_in_huge_free_list(-size); 2311 page->add_available_in_huge_free_list(-size);
2309 cur_node = cur_node->next(); 2312 cur_node = cur_node->next();
(...skipping 13 matching lines...) Expand all
2323 node = *cur; 2326 node = *cur;
2324 *cur = node->next(); 2327 *cur = node->next();
2325 *node_size = size; 2328 *node_size = size;
2326 huge_list_available -= size; 2329 huge_list_available -= size;
2327 page = Page::FromAddress(node->address()); 2330 page = Page::FromAddress(node->address());
2328 page->add_available_in_huge_free_list(-size); 2331 page->add_available_in_huge_free_list(-size);
2329 break; 2332 break;
2330 } 2333 }
2331 } 2334 }
2332 2335
2333 huge_list_.set_top(top_node);
2334 if (huge_list_.top() == NULL) { 2336 if (huge_list_.top() == NULL) {
2335 huge_list_.set_end(NULL); 2337 huge_list_.set_end(NULL);
2336 } 2338 }
2337 huge_list_.set_available(huge_list_available); 2339 huge_list_.set_available(huge_list_available);
2338 2340
2339 if (node != NULL) { 2341 if (node != NULL) {
2340 ASSERT(IsVeryLong() || available() == SumFreeLists()); 2342 ASSERT(IsVeryLong() || available() == SumFreeLists());
2341 return node; 2343 return node;
2342 } 2344 }
2343 2345
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2477 small_list_.RepairFreeList(heap); 2479 small_list_.RepairFreeList(heap);
2478 medium_list_.RepairFreeList(heap); 2480 medium_list_.RepairFreeList(heap);
2479 large_list_.RepairFreeList(heap); 2481 large_list_.RepairFreeList(heap);
2480 huge_list_.RepairFreeList(heap); 2482 huge_list_.RepairFreeList(heap);
2481 } 2483 }
2482 2484
2483 2485
2484 #ifdef DEBUG 2486 #ifdef DEBUG
2485 intptr_t FreeListCategory::SumFreeList() { 2487 intptr_t FreeListCategory::SumFreeList() {
2486 intptr_t sum = 0; 2488 intptr_t sum = 0;
2487 FreeListNode* cur = top(); 2489 FreeListNode* cur = top_;
2488 while (cur != NULL) { 2490 while (cur != NULL) {
2489 ASSERT(cur->map() == cur->GetHeap()->raw_unchecked_free_space_map()); 2491 ASSERT(cur->map() == cur->GetHeap()->raw_unchecked_free_space_map());
2490 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(cur); 2492 FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(cur);
2491 sum += cur_as_free_space->Size(); 2493 sum += cur_as_free_space->Size();
2492 cur = cur->next(); 2494 cur = cur->next();
2493 } 2495 }
2494 return sum; 2496 return sum;
2495 } 2497 }
2496 2498
2497 2499
2498 static const int kVeryLongFreeList = 500; 2500 static const int kVeryLongFreeList = 500;
2499 2501
2500 2502
2501 int FreeListCategory::FreeListLength() { 2503 int FreeListCategory::FreeListLength() {
2502 int length = 0; 2504 int length = 0;
2503 FreeListNode* cur = top(); 2505 FreeListNode* cur = top_;
2504 while (cur != NULL) { 2506 while (cur != NULL) {
2505 length++; 2507 length++;
2506 cur = cur->next(); 2508 cur = cur->next();
2507 if (length == kVeryLongFreeList) return length; 2509 if (length == kVeryLongFreeList) return length;
2508 } 2510 }
2509 return length; 2511 return length;
2510 } 2512 }
2511 2513
2512 2514
2513 bool FreeList::IsVeryLong() { 2515 bool FreeList::IsVeryLong() {
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
3199 object->ShortPrint(); 3201 object->ShortPrint();
3200 PrintF("\n"); 3202 PrintF("\n");
3201 } 3203 }
3202 printf(" --------------------------------------\n"); 3204 printf(" --------------------------------------\n");
3203 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3205 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3204 } 3206 }
3205 3207
3206 #endif // DEBUG 3208 #endif // DEBUG
3207 3209
3208 } } // namespace v8::internal 3210 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/spaces.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698