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

Side by Side Diff: src/heap/mark-compact.cc

Issue 1023443004: Version 4.3.48.1 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@4.3.48
Patch Set: Created 5 years, 9 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
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compilation-cache.h" 10 #include "src/compilation-cache.h"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 PageIterator it(space); 128 PageIterator it(space);
129 129
130 while (it.has_next()) { 130 while (it.has_next()) {
131 Page* p = it.next(); 131 Page* p = it.next();
132 VerifyMarking(space->heap(), p->area_start(), p->area_end()); 132 VerifyMarking(space->heap(), p->area_start(), p->area_end());
133 } 133 }
134 } 134 }
135 135
136 136
137 static void VerifyMarking(Heap* heap) { 137 static void VerifyMarking(Heap* heap) {
138 VerifyMarking(heap->old_space()); 138 VerifyMarking(heap->old_pointer_space());
139 VerifyMarking(heap->old_data_space());
139 VerifyMarking(heap->code_space()); 140 VerifyMarking(heap->code_space());
140 VerifyMarking(heap->cell_space()); 141 VerifyMarking(heap->cell_space());
141 VerifyMarking(heap->map_space()); 142 VerifyMarking(heap->map_space());
142 VerifyMarking(heap->new_space()); 143 VerifyMarking(heap->new_space());
143 144
144 VerifyMarkingVisitor visitor(heap); 145 VerifyMarkingVisitor visitor(heap);
145 146
146 LargeObjectIterator it(heap->lo_space()); 147 LargeObjectIterator it(heap->lo_space());
147 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 148 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
148 if (MarkCompactCollector::IsMarked(obj)) { 149 if (MarkCompactCollector::IsMarked(obj)) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 while (current < limit) { 193 while (current < limit) {
193 HeapObject* object = HeapObject::FromAddress(current); 194 HeapObject* object = HeapObject::FromAddress(current);
194 object->Iterate(&visitor); 195 object->Iterate(&visitor);
195 current += object->Size(); 196 current += object->Size();
196 } 197 }
197 } 198 }
198 } 199 }
199 200
200 201
201 static void VerifyEvacuation(Heap* heap, PagedSpace* space) { 202 static void VerifyEvacuation(Heap* heap, PagedSpace* space) {
202 if (FLAG_use_allocation_folding && (space == heap->old_space())) { 203 if (FLAG_use_allocation_folding &&
204 (space == heap->old_pointer_space() || space == heap->old_data_space())) {
203 return; 205 return;
204 } 206 }
205 PageIterator it(space); 207 PageIterator it(space);
206 208
207 while (it.has_next()) { 209 while (it.has_next()) {
208 Page* p = it.next(); 210 Page* p = it.next();
209 if (p->IsEvacuationCandidate()) continue; 211 if (p->IsEvacuationCandidate()) continue;
210 VerifyEvacuation(p); 212 VerifyEvacuation(p);
211 } 213 }
212 } 214 }
213 215
214 216
215 static void VerifyEvacuation(Heap* heap) { 217 static void VerifyEvacuation(Heap* heap) {
216 VerifyEvacuation(heap, heap->old_space()); 218 VerifyEvacuation(heap, heap->old_pointer_space());
219 VerifyEvacuation(heap, heap->old_data_space());
217 VerifyEvacuation(heap, heap->code_space()); 220 VerifyEvacuation(heap, heap->code_space());
218 VerifyEvacuation(heap, heap->cell_space()); 221 VerifyEvacuation(heap, heap->cell_space());
219 VerifyEvacuation(heap, heap->map_space()); 222 VerifyEvacuation(heap, heap->map_space());
220 VerifyEvacuation(heap->new_space()); 223 VerifyEvacuation(heap->new_space());
221 224
222 VerifyEvacuationVisitor visitor; 225 VerifyEvacuationVisitor visitor;
223 heap->IterateStrongRoots(&visitor, VISIT_ALL); 226 heap->IterateStrongRoots(&visitor, VISIT_ALL);
224 } 227 }
225 #endif // VERIFY_HEAP 228 #endif // VERIFY_HEAP
226 229
227 230
228 void MarkCompactCollector::SetUp() { 231 void MarkCompactCollector::SetUp() {
229 free_list_old_space_.Reset(new FreeList(heap_->old_space())); 232 free_list_old_data_space_.Reset(new FreeList(heap_->old_data_space()));
233 free_list_old_pointer_space_.Reset(new FreeList(heap_->old_pointer_space()));
230 } 234 }
231 235
232 236
233 void MarkCompactCollector::TearDown() { 237 void MarkCompactCollector::TearDown() {
234 AbortCompaction(); 238 AbortCompaction();
235 delete marking_deque_memory_; 239 delete marking_deque_memory_;
236 } 240 }
237 241
238 242
239 void MarkCompactCollector::AddEvacuationCandidate(Page* p) { 243 void MarkCompactCollector::AddEvacuationCandidate(Page* p) {
(...skipping 10 matching lines...) Expand all
250 PrintF("[%s]: %d pages, %d (%.1f%%) free\n", 254 PrintF("[%s]: %d pages, %d (%.1f%%) free\n",
251 AllocationSpaceName(space->identity()), number_of_pages, 255 AllocationSpaceName(space->identity()), number_of_pages,
252 static_cast<int>(free), static_cast<double>(free) * 100 / reserved); 256 static_cast<int>(free), static_cast<double>(free) * 100 / reserved);
253 } 257 }
254 258
255 259
256 bool MarkCompactCollector::StartCompaction(CompactionMode mode) { 260 bool MarkCompactCollector::StartCompaction(CompactionMode mode) {
257 if (!compacting_) { 261 if (!compacting_) {
258 DCHECK(evacuation_candidates_.length() == 0); 262 DCHECK(evacuation_candidates_.length() == 0);
259 263
260 CollectEvacuationCandidates(heap()->old_space()); 264 CollectEvacuationCandidates(heap()->old_pointer_space());
265 CollectEvacuationCandidates(heap()->old_data_space());
261 266
262 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION || 267 if (FLAG_compact_code_space && (mode == NON_INCREMENTAL_COMPACTION ||
263 FLAG_incremental_code_compaction)) { 268 FLAG_incremental_code_compaction)) {
264 CollectEvacuationCandidates(heap()->code_space()); 269 CollectEvacuationCandidates(heap()->code_space());
265 } else if (FLAG_trace_fragmentation) { 270 } else if (FLAG_trace_fragmentation) {
266 TraceFragmentation(heap()->code_space()); 271 TraceFragmentation(heap()->code_space());
267 } 272 }
268 273
269 if (FLAG_trace_fragmentation) { 274 if (FLAG_trace_fragmentation) {
270 TraceFragmentation(heap()->map_space()); 275 TraceFragmentation(heap()->map_space());
271 TraceFragmentation(heap()->cell_space()); 276 TraceFragmentation(heap()->cell_space());
272 } 277 }
273 278
274 heap()->old_space()->EvictEvacuationCandidatesFromFreeLists(); 279 heap()->old_pointer_space()->EvictEvacuationCandidatesFromFreeLists();
280 heap()->old_data_space()->EvictEvacuationCandidatesFromFreeLists();
275 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists(); 281 heap()->code_space()->EvictEvacuationCandidatesFromFreeLists();
276 282
277 compacting_ = evacuation_candidates_.length() > 0; 283 compacting_ = evacuation_candidates_.length() > 0;
278 } 284 }
279 285
280 return compacting_; 286 return compacting_;
281 } 287 }
282 288
283 289
284 void MarkCompactCollector::CollectGarbage() { 290 void MarkCompactCollector::CollectGarbage() {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 357
352 while (it.has_next()) { 358 while (it.has_next()) {
353 NewSpacePage* p = it.next(); 359 NewSpacePage* p = it.next();
354 CHECK(p->markbits()->IsClean()); 360 CHECK(p->markbits()->IsClean());
355 CHECK_EQ(0, p->LiveBytes()); 361 CHECK_EQ(0, p->LiveBytes());
356 } 362 }
357 } 363 }
358 364
359 365
360 void MarkCompactCollector::VerifyMarkbitsAreClean() { 366 void MarkCompactCollector::VerifyMarkbitsAreClean() {
361 VerifyMarkbitsAreClean(heap_->old_space()); 367 VerifyMarkbitsAreClean(heap_->old_pointer_space());
368 VerifyMarkbitsAreClean(heap_->old_data_space());
362 VerifyMarkbitsAreClean(heap_->code_space()); 369 VerifyMarkbitsAreClean(heap_->code_space());
363 VerifyMarkbitsAreClean(heap_->cell_space()); 370 VerifyMarkbitsAreClean(heap_->cell_space());
364 VerifyMarkbitsAreClean(heap_->map_space()); 371 VerifyMarkbitsAreClean(heap_->map_space());
365 VerifyMarkbitsAreClean(heap_->new_space()); 372 VerifyMarkbitsAreClean(heap_->new_space());
366 373
367 LargeObjectIterator it(heap_->lo_space()); 374 LargeObjectIterator it(heap_->lo_space());
368 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 375 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
369 MarkBit mark_bit = Marking::MarkBitFrom(obj); 376 MarkBit mark_bit = Marking::MarkBitFrom(obj);
370 CHECK(Marking::IsWhite(mark_bit)); 377 CHECK(Marking::IsWhite(mark_bit));
371 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); 378 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 416
410 while (it.has_next()) { 417 while (it.has_next()) {
411 Bitmap::Clear(it.next()); 418 Bitmap::Clear(it.next());
412 } 419 }
413 } 420 }
414 421
415 422
416 void MarkCompactCollector::ClearMarkbits() { 423 void MarkCompactCollector::ClearMarkbits() {
417 ClearMarkbitsInPagedSpace(heap_->code_space()); 424 ClearMarkbitsInPagedSpace(heap_->code_space());
418 ClearMarkbitsInPagedSpace(heap_->map_space()); 425 ClearMarkbitsInPagedSpace(heap_->map_space());
419 ClearMarkbitsInPagedSpace(heap_->old_space()); 426 ClearMarkbitsInPagedSpace(heap_->old_pointer_space());
427 ClearMarkbitsInPagedSpace(heap_->old_data_space());
420 ClearMarkbitsInPagedSpace(heap_->cell_space()); 428 ClearMarkbitsInPagedSpace(heap_->cell_space());
421 ClearMarkbitsInNewSpace(heap_->new_space()); 429 ClearMarkbitsInNewSpace(heap_->new_space());
422 430
423 LargeObjectIterator it(heap_->lo_space()); 431 LargeObjectIterator it(heap_->lo_space());
424 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 432 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
425 MarkBit mark_bit = Marking::MarkBitFrom(obj); 433 MarkBit mark_bit = Marking::MarkBitFrom(obj);
426 mark_bit.Clear(); 434 mark_bit.Clear();
427 mark_bit.Next().Clear(); 435 mark_bit.Next().Clear();
428 Page::FromAddress(obj->address())->ResetProgressBar(); 436 Page::FromAddress(obj->address())->ResetProgressBar();
429 Page::FromAddress(obj->address())->ResetLiveBytes(); 437 Page::FromAddress(obj->address())->ResetLiveBytes();
(...skipping 15 matching lines...) Expand all
445 } 453 }
446 454
447 Heap* heap_; 455 Heap* heap_;
448 PagedSpace* space_; 456 PagedSpace* space_;
449 457
450 DISALLOW_COPY_AND_ASSIGN(SweeperTask); 458 DISALLOW_COPY_AND_ASSIGN(SweeperTask);
451 }; 459 };
452 460
453 461
454 void MarkCompactCollector::StartSweeperThreads() { 462 void MarkCompactCollector::StartSweeperThreads() {
455 DCHECK(free_list_old_space_.get()->IsEmpty()); 463 DCHECK(free_list_old_pointer_space_.get()->IsEmpty());
464 DCHECK(free_list_old_data_space_.get()->IsEmpty());
456 V8::GetCurrentPlatform()->CallOnBackgroundThread( 465 V8::GetCurrentPlatform()->CallOnBackgroundThread(
457 new SweeperTask(heap(), heap()->old_space()), 466 new SweeperTask(heap(), heap()->old_data_space()),
467 v8::Platform::kShortRunningTask);
468 V8::GetCurrentPlatform()->CallOnBackgroundThread(
469 new SweeperTask(heap(), heap()->old_pointer_space()),
458 v8::Platform::kShortRunningTask); 470 v8::Platform::kShortRunningTask);
459 } 471 }
460 472
461 473
462 void MarkCompactCollector::EnsureSweepingCompleted() { 474 void MarkCompactCollector::EnsureSweepingCompleted() {
463 DCHECK(sweeping_in_progress_ == true); 475 DCHECK(sweeping_in_progress_ == true);
464 476
465 // If sweeping is not completed or not running at all, we try to complete it 477 // If sweeping is not completed or not running at all, we try to complete it
466 // here. 478 // here.
467 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { 479 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) {
468 SweepInParallel(heap()->paged_space(OLD_SPACE), 0); 480 SweepInParallel(heap()->paged_space(OLD_DATA_SPACE), 0);
481 SweepInParallel(heap()->paged_space(OLD_POINTER_SPACE), 0);
469 } 482 }
470 // Wait twice for both jobs. 483 // Wait twice for both jobs.
471 if (heap()->concurrent_sweeping_enabled()) { 484 if (heap()->concurrent_sweeping_enabled()) {
472 pending_sweeper_jobs_semaphore_.Wait(); 485 pending_sweeper_jobs_semaphore_.Wait();
486 pending_sweeper_jobs_semaphore_.Wait();
473 } 487 }
474 ParallelSweepSpacesComplete(); 488 ParallelSweepSpacesComplete();
475 sweeping_in_progress_ = false; 489 sweeping_in_progress_ = false;
476 RefillFreeList(heap()->paged_space(OLD_SPACE)); 490 RefillFreeList(heap()->paged_space(OLD_DATA_SPACE));
477 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes(); 491 RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE));
492 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes();
493 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes();
478 494
479 #ifdef VERIFY_HEAP 495 #ifdef VERIFY_HEAP
480 if (FLAG_verify_heap && !evacuation()) { 496 if (FLAG_verify_heap && !evacuation()) {
481 VerifyEvacuation(heap_); 497 VerifyEvacuation(heap_);
482 } 498 }
483 #endif 499 #endif
484 } 500 }
485 501
486 502
487 bool MarkCompactCollector::IsSweepingCompleted() { 503 bool MarkCompactCollector::IsSweepingCompleted() {
488 if (!pending_sweeper_jobs_semaphore_.WaitFor( 504 if (!pending_sweeper_jobs_semaphore_.WaitFor(
489 base::TimeDelta::FromSeconds(0))) { 505 base::TimeDelta::FromSeconds(0))) {
490 return false; 506 return false;
491 } 507 }
492 pending_sweeper_jobs_semaphore_.Signal(); 508 pending_sweeper_jobs_semaphore_.Signal();
493 return true; 509 return true;
494 } 510 }
495 511
496 512
497 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { 513 void MarkCompactCollector::RefillFreeList(PagedSpace* space) {
498 FreeList* free_list; 514 FreeList* free_list;
499 515
500 if (space == heap()->old_space()) { 516 if (space == heap()->old_pointer_space()) {
501 free_list = free_list_old_space_.get(); 517 free_list = free_list_old_pointer_space_.get();
518 } else if (space == heap()->old_data_space()) {
519 free_list = free_list_old_data_space_.get();
502 } else { 520 } else {
503 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure 521 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure
504 // to only refill them for the old space. 522 // to only refill them for old data and pointer spaces.
505 return; 523 return;
506 } 524 }
507 525
508 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); 526 intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
509 space->AddToAccountingStats(freed_bytes); 527 space->AddToAccountingStats(freed_bytes);
510 space->DecrementUnsweptFreeBytes(freed_bytes); 528 space->DecrementUnsweptFreeBytes(freed_bytes);
511 } 529 }
512 530
513 531
514 void Marking::TransferMark(Address old_start, Address new_start) { 532 void Marking::TransferMark(Address old_start, Address new_start) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 ObjectColor new_color = Color(new_mark_bit); 566 ObjectColor new_color = Color(new_mark_bit);
549 DCHECK(new_color == old_color); 567 DCHECK(new_color == old_color);
550 #endif 568 #endif
551 } 569 }
552 570
553 571
554 const char* AllocationSpaceName(AllocationSpace space) { 572 const char* AllocationSpaceName(AllocationSpace space) {
555 switch (space) { 573 switch (space) {
556 case NEW_SPACE: 574 case NEW_SPACE:
557 return "NEW_SPACE"; 575 return "NEW_SPACE";
558 case OLD_SPACE: 576 case OLD_POINTER_SPACE:
559 return "OLD_SPACE"; 577 return "OLD_POINTER_SPACE";
578 case OLD_DATA_SPACE:
579 return "OLD_DATA_SPACE";
560 case CODE_SPACE: 580 case CODE_SPACE:
561 return "CODE_SPACE"; 581 return "CODE_SPACE";
562 case MAP_SPACE: 582 case MAP_SPACE:
563 return "MAP_SPACE"; 583 return "MAP_SPACE";
564 case CELL_SPACE: 584 case CELL_SPACE:
565 return "CELL_SPACE"; 585 return "CELL_SPACE";
566 case LO_SPACE: 586 case LO_SPACE:
567 return "LO_SPACE"; 587 return "LO_SPACE";
568 default: 588 default:
569 UNREACHABLE(); 589 UNREACHABLE();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 return 1; 638 return 1;
619 } 639 }
620 640
621 if (ratio <= ratio_threshold) return 0; // Not fragmented. 641 if (ratio <= ratio_threshold) return 0; // Not fragmented.
622 642
623 return static_cast<int>(ratio - ratio_threshold); 643 return static_cast<int>(ratio - ratio_threshold);
624 } 644 }
625 645
626 646
627 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { 647 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
628 DCHECK(space->identity() == OLD_SPACE || space->identity() == CODE_SPACE); 648 DCHECK(space->identity() == OLD_POINTER_SPACE ||
649 space->identity() == OLD_DATA_SPACE ||
650 space->identity() == CODE_SPACE);
629 651
630 static const int kMaxMaxEvacuationCandidates = 1000; 652 static const int kMaxMaxEvacuationCandidates = 1000;
631 int number_of_pages = space->CountTotalPages(); 653 int number_of_pages = space->CountTotalPages();
632 int max_evacuation_candidates = 654 int max_evacuation_candidates =
633 static_cast<int>(std::sqrt(number_of_pages / 2.0) + 1); 655 static_cast<int>(std::sqrt(number_of_pages / 2.0) + 1);
634 656
635 if (FLAG_stress_compaction || FLAG_always_compact) { 657 if (FLAG_stress_compaction || FLAG_always_compact) {
636 max_evacuation_candidates = kMaxMaxEvacuationCandidates; 658 max_evacuation_candidates = kMaxMaxEvacuationCandidates;
637 } 659 }
638 660
(...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 (next_cell << (Bitmap::kBitsPerCell - 1))); 1806 (next_cell << (Bitmap::kBitsPerCell - 1)));
1785 } else { 1807 } else {
1786 grey_objects = current_cell & (current_cell >> 1); 1808 grey_objects = current_cell & (current_cell >> 1);
1787 } 1809 }
1788 1810
1789 int offset = 0; 1811 int offset = 0;
1790 while (grey_objects != 0) { 1812 while (grey_objects != 0) {
1791 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects); 1813 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects);
1792 grey_objects >>= trailing_zeros; 1814 grey_objects >>= trailing_zeros;
1793 offset += trailing_zeros; 1815 offset += trailing_zeros;
1794 MarkBit markbit(cell, 1 << offset); 1816 MarkBit markbit(cell, 1 << offset, false);
1795 DCHECK(Marking::IsGrey(markbit)); 1817 DCHECK(Marking::IsGrey(markbit));
1796 Marking::GreyToBlack(markbit); 1818 Marking::GreyToBlack(markbit);
1797 Address addr = cell_base + offset * kPointerSize; 1819 Address addr = cell_base + offset * kPointerSize;
1798 HeapObject* object = HeapObject::FromAddress(addr); 1820 HeapObject* object = HeapObject::FromAddress(addr);
1799 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); 1821 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size());
1800 marking_deque->PushBlack(object); 1822 marking_deque->PushBlack(object);
1801 if (marking_deque->IsFull()) return; 1823 if (marking_deque->IsFull()) return;
1802 offset += 2; 1824 offset += 2;
1803 grey_objects >>= 2; 1825 grey_objects >>= 2;
1804 } 1826 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 // push them on the marking stack. Stop early if the marking stack fills 2030 // push them on the marking stack. Stop early if the marking stack fills
2009 // before sweeping completes. If sweeping completes, there are no remaining 2031 // before sweeping completes. If sweeping completes, there are no remaining
2010 // overflowed objects in the heap so the overflow flag on the markings stack 2032 // overflowed objects in the heap so the overflow flag on the markings stack
2011 // is cleared. 2033 // is cleared.
2012 void MarkCompactCollector::RefillMarkingDeque() { 2034 void MarkCompactCollector::RefillMarkingDeque() {
2013 DCHECK(marking_deque_.overflowed()); 2035 DCHECK(marking_deque_.overflowed());
2014 2036
2015 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); 2037 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_);
2016 if (marking_deque_.IsFull()) return; 2038 if (marking_deque_.IsFull()) return;
2017 2039
2018 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_space()); 2040 DiscoverGreyObjectsInSpace(heap(), &marking_deque_,
2041 heap()->old_pointer_space());
2042 if (marking_deque_.IsFull()) return;
2043
2044 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_data_space());
2019 if (marking_deque_.IsFull()) return; 2045 if (marking_deque_.IsFull()) return;
2020 2046
2021 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); 2047 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space());
2022 if (marking_deque_.IsFull()) return; 2048 if (marking_deque_.IsFull()) return;
2023 2049
2024 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); 2050 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space());
2025 if (marking_deque_.IsFull()) return; 2051 if (marking_deque_.IsFull()) return;
2026 2052
2027 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); 2053 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space());
2028 if (marking_deque_.IsFull()) return; 2054 if (marking_deque_.IsFull()) return;
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 // to new space. We should clear them to avoid encountering them during next 2704 // to new space. We should clear them to avoid encountering them during next
2679 // pointer iteration. This is an issue if the store buffer overflows and we 2705 // pointer iteration. This is an issue if the store buffer overflows and we
2680 // have to scan the entire old space, including dead objects, looking for 2706 // have to scan the entire old space, including dead objects, looking for
2681 // pointers to new space. 2707 // pointers to new space.
2682 void MarkCompactCollector::MigrateObject(HeapObject* dst, HeapObject* src, 2708 void MarkCompactCollector::MigrateObject(HeapObject* dst, HeapObject* src,
2683 int size, AllocationSpace dest) { 2709 int size, AllocationSpace dest) {
2684 Address dst_addr = dst->address(); 2710 Address dst_addr = dst->address();
2685 Address src_addr = src->address(); 2711 Address src_addr = src->address();
2686 DCHECK(heap()->AllowedToBeMigrated(src, dest)); 2712 DCHECK(heap()->AllowedToBeMigrated(src, dest));
2687 DCHECK(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize); 2713 DCHECK(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize);
2688 if (dest == OLD_SPACE) { 2714 if (dest == OLD_POINTER_SPACE) {
2689 Address src_slot = src_addr; 2715 Address src_slot = src_addr;
2690 Address dst_slot = dst_addr; 2716 Address dst_slot = dst_addr;
2691 DCHECK(IsAligned(size, kPointerSize)); 2717 DCHECK(IsAligned(size, kPointerSize));
2692 2718
2693 bool may_contain_raw_values = src->MayContainRawValues(); 2719 bool may_contain_raw_values = src->MayContainRawValues();
2694 #if V8_DOUBLE_FIELDS_UNBOXING 2720 #if V8_DOUBLE_FIELDS_UNBOXING
2695 LayoutDescriptorHelper helper(src->map()); 2721 LayoutDescriptorHelper helper(src->map());
2696 bool has_only_tagged_fields = helper.all_fields_tagged(); 2722 bool has_only_tagged_fields = helper.all_fields_tagged();
2697 #endif 2723 #endif
2698 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { 2724 for (int remaining = size / kPointerSize; remaining > 0; remaining--) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2750 } 2776 }
2751 } 2777 }
2752 } else if (dest == CODE_SPACE) { 2778 } else if (dest == CODE_SPACE) {
2753 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr)); 2779 PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr));
2754 heap()->MoveBlock(dst_addr, src_addr, size); 2780 heap()->MoveBlock(dst_addr, src_addr, size);
2755 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, 2781 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_,
2756 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr, 2782 SlotsBuffer::RELOCATED_CODE_OBJECT, dst_addr,
2757 SlotsBuffer::IGNORE_OVERFLOW); 2783 SlotsBuffer::IGNORE_OVERFLOW);
2758 Code::cast(dst)->Relocate(dst_addr - src_addr); 2784 Code::cast(dst)->Relocate(dst_addr - src_addr);
2759 } else { 2785 } else {
2760 DCHECK(dest == NEW_SPACE); 2786 DCHECK(dest == OLD_DATA_SPACE || dest == NEW_SPACE);
2761 heap()->MoveBlock(dst_addr, src_addr, size); 2787 heap()->MoveBlock(dst_addr, src_addr, size);
2762 } 2788 }
2763 heap()->OnMoveEvent(dst, src, size); 2789 heap()->OnMoveEvent(dst, src, size);
2764 Memory::Address_at(src_addr) = dst_addr; 2790 Memory::Address_at(src_addr) = dst_addr;
2765 } 2791 }
2766 2792
2767 2793
2768 // Visitor for updating pointers from live objects in old spaces to new space. 2794 // Visitor for updating pointers from live objects in old spaces to new space.
2769 // It does not expect to encounter pointers to dead objects. 2795 // It does not expect to encounter pointers to dead objects.
2770 class PointersUpdatingVisitor : public ObjectVisitor { 2796 class PointersUpdatingVisitor : public ObjectVisitor {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2872 data[index++] = reinterpret_cast<uintptr_t>(slot); 2898 data[index++] = reinterpret_cast<uintptr_t>(slot);
2873 data[index++] = 0x15aaaaaaaaUL; 2899 data[index++] = 0x15aaaaaaaaUL;
2874 2900
2875 Address slot_address = reinterpret_cast<Address>(slot); 2901 Address slot_address = reinterpret_cast<Address>(slot);
2876 2902
2877 uintptr_t space_owner_id = 0xb001; 2903 uintptr_t space_owner_id = 0xb001;
2878 if (heap->new_space()->ToSpaceContains(slot_address)) { 2904 if (heap->new_space()->ToSpaceContains(slot_address)) {
2879 space_owner_id = 1; 2905 space_owner_id = 1;
2880 } else if (heap->new_space()->FromSpaceContains(slot_address)) { 2906 } else if (heap->new_space()->FromSpaceContains(slot_address)) {
2881 space_owner_id = 2; 2907 space_owner_id = 2;
2882 } else if (heap->old_space()->ContainsSafe(slot_address)) { 2908 } else if (heap->old_pointer_space()->ContainsSafe(slot_address)) {
2883 space_owner_id = 3; 2909 space_owner_id = 3;
2910 } else if (heap->old_data_space()->ContainsSafe(slot_address)) {
2911 space_owner_id = 4;
2884 } else if (heap->code_space()->ContainsSafe(slot_address)) { 2912 } else if (heap->code_space()->ContainsSafe(slot_address)) {
2885 space_owner_id = 4; 2913 space_owner_id = 5;
2886 } else if (heap->map_space()->ContainsSafe(slot_address)) { 2914 } else if (heap->map_space()->ContainsSafe(slot_address)) {
2887 space_owner_id = 5; 2915 space_owner_id = 6;
2888 } else if (heap->cell_space()->ContainsSafe(slot_address)) { 2916 } else if (heap->cell_space()->ContainsSafe(slot_address)) {
2889 space_owner_id = 6; 2917 space_owner_id = 7;
2890 } else { 2918 } else {
2891 // Lo space or other. 2919 // Lo space or other.
2892 space_owner_id = 7; 2920 space_owner_id = 8;
2893 } 2921 }
2894 data[index++] = space_owner_id; 2922 data[index++] = space_owner_id;
2895 data[index++] = 0x20aaaaaaaaUL; 2923 data[index++] = 0x20aaaaaaaaUL;
2896 2924
2897 // Find map word lying near before the slot address (usually the map word is 2925 // Find map word lying near before the slot address (usually the map word is
2898 // at -3 words from the slot but just in case we look up further. 2926 // at -3 words from the slot but just in case we look up further.
2899 Object** map_slot = slot; 2927 Object** map_slot = slot;
2900 bool found = false; 2928 bool found = false;
2901 const int kMaxDistanceToMap = 64; 2929 const int kMaxDistanceToMap = 64;
2902 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) { 2930 for (int i = 0; i < kMaxDistanceToMap; i++, map_slot--) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2973 } 3001 }
2974 3002
2975 return String::cast(*p); 3003 return String::cast(*p);
2976 } 3004 }
2977 3005
2978 3006
2979 bool MarkCompactCollector::TryPromoteObject(HeapObject* object, 3007 bool MarkCompactCollector::TryPromoteObject(HeapObject* object,
2980 int object_size) { 3008 int object_size) {
2981 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 3009 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
2982 3010
2983 OldSpace* old_space = heap()->old_space(); 3011 OldSpace* target_space = heap()->TargetSpace(object);
2984 3012
3013 DCHECK(target_space == heap()->old_pointer_space() ||
3014 target_space == heap()->old_data_space());
2985 HeapObject* target; 3015 HeapObject* target;
2986 AllocationResult allocation = old_space->AllocateRaw(object_size); 3016 AllocationResult allocation = target_space->AllocateRaw(object_size);
2987 if (allocation.To(&target)) { 3017 if (allocation.To(&target)) {
2988 MigrateObject(target, object, object_size, old_space->identity()); 3018 MigrateObject(target, object, object_size, target_space->identity());
2989 heap()->IncrementPromotedObjectsSize(object_size); 3019 heap()->IncrementPromotedObjectsSize(object_size);
2990 return true; 3020 return true;
2991 } 3021 }
2992 3022
2993 return false; 3023 return false;
2994 } 3024 }
2995 3025
2996 3026
2997 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot) { 3027 bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot) {
2998 // This function does not support large objects right now. 3028 // This function does not support large objects right now.
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
3464 3494
3465 return true; 3495 return true;
3466 } 3496 }
3467 3497
3468 3498
3469 static bool IsOnInvalidatedCodeObject(Address addr) { 3499 static bool IsOnInvalidatedCodeObject(Address addr) {
3470 // We did not record any slots in large objects thus 3500 // We did not record any slots in large objects thus
3471 // we can safely go to the page from the slot address. 3501 // we can safely go to the page from the slot address.
3472 Page* p = Page::FromAddress(addr); 3502 Page* p = Page::FromAddress(addr);
3473 3503
3474 // First check owner's identity because old space is swept concurrently or 3504 // First check owner's identity because old pointer and old data spaces
3475 // lazily and might still have non-zero mark-bits on some pages. 3505 // are swept lazily and might still have non-zero mark-bits on some
3506 // pages.
3476 if (p->owner()->identity() != CODE_SPACE) return false; 3507 if (p->owner()->identity() != CODE_SPACE) return false;
3477 3508
3478 // In code space only bits on evacuation candidates (but we don't record 3509 // In code space only bits on evacuation candidates (but we don't record
3479 // any slots on them) and under invalidated code objects are non-zero. 3510 // any slots on them) and under invalidated code objects are non-zero.
3480 MarkBit mark_bit = 3511 MarkBit mark_bit =
3481 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr)); 3512 p->markbits()->MarkBitFromIndex(Page::FastAddressToMarkbitIndex(addr));
3482 3513
3483 return mark_bit.Get(); 3514 return mark_bit.Get();
3484 } 3515 }
3485 3516
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
3643 if (list != NULL) list->Clear(); 3674 if (list != NULL) list->Clear();
3644 } else { 3675 } else {
3645 if (FLAG_gc_verbose) { 3676 if (FLAG_gc_verbose) {
3646 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 3677 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
3647 reinterpret_cast<intptr_t>(p)); 3678 reinterpret_cast<intptr_t>(p));
3648 } 3679 }
3649 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3680 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3650 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 3681 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3651 3682
3652 switch (space->identity()) { 3683 switch (space->identity()) {
3653 case OLD_SPACE: 3684 case OLD_DATA_SPACE:
3654 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3685 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3655 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, 3686 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3656 &updating_visitor); 3687 &updating_visitor);
3688 break;
3689 case OLD_POINTER_SPACE:
3690 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3691 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3692 &updating_visitor);
3657 break; 3693 break;
3658 case CODE_SPACE: 3694 case CODE_SPACE:
3659 if (FLAG_zap_code_space) { 3695 if (FLAG_zap_code_space) {
3660 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3696 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3661 REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p, 3697 REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p,
3662 &updating_visitor); 3698 &updating_visitor);
3663 } else { 3699 } else {
3664 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3700 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3665 REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, 3701 REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
3666 &updating_visitor); 3702 &updating_visitor);
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
4154 max_freed_overall = Max(max_freed, max_freed_overall); 4190 max_freed_overall = Max(max_freed, max_freed_overall);
4155 if (p == space->end_of_unswept_pages()) break; 4191 if (p == space->end_of_unswept_pages()) break;
4156 } 4192 }
4157 return max_freed_overall; 4193 return max_freed_overall;
4158 } 4194 }
4159 4195
4160 4196
4161 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { 4197 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) {
4162 int max_freed = 0; 4198 int max_freed = 0;
4163 if (page->TryParallelSweeping()) { 4199 if (page->TryParallelSweeping()) {
4164 FreeList* free_list = free_list_old_space_.get(); 4200 FreeList* free_list = space == heap()->old_pointer_space()
4201 ? free_list_old_pointer_space_.get()
4202 : free_list_old_data_space_.get();
4165 FreeList private_free_list(space); 4203 FreeList private_free_list(space);
4166 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, 4204 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
4167 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); 4205 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
4168 free_list->Concatenate(&private_free_list); 4206 free_list->Concatenate(&private_free_list);
4169 } 4207 }
4170 return max_freed; 4208 return max_freed;
4171 } 4209 }
4172 4210
4173 4211
4174 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 4212 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4279 MoveEvacuationCandidatesToEndOfPagesList(); 4317 MoveEvacuationCandidatesToEndOfPagesList();
4280 4318
4281 // Noncompacting collections simply sweep the spaces to clear the mark 4319 // Noncompacting collections simply sweep the spaces to clear the mark
4282 // bits and free the nonlive blocks (for old and map spaces). We sweep 4320 // bits and free the nonlive blocks (for old and map spaces). We sweep
4283 // the map space last because freeing non-live maps overwrites them and 4321 // the map space last because freeing non-live maps overwrites them and
4284 // the other spaces rely on possibly non-live maps to get the sizes for 4322 // the other spaces rely on possibly non-live maps to get the sizes for
4285 // non-live objects. 4323 // non-live objects.
4286 { 4324 {
4287 GCTracer::Scope sweep_scope(heap()->tracer(), 4325 GCTracer::Scope sweep_scope(heap()->tracer(),
4288 GCTracer::Scope::MC_SWEEP_OLDSPACE); 4326 GCTracer::Scope::MC_SWEEP_OLDSPACE);
4289 { SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING); } 4327 {
4328 SweepSpace(heap()->old_pointer_space(), CONCURRENT_SWEEPING);
4329 SweepSpace(heap()->old_data_space(), CONCURRENT_SWEEPING);
4330 }
4290 sweeping_in_progress_ = true; 4331 sweeping_in_progress_ = true;
4291 if (heap()->concurrent_sweeping_enabled()) { 4332 if (heap()->concurrent_sweeping_enabled()) {
4292 StartSweeperThreads(); 4333 StartSweeperThreads();
4293 } 4334 }
4294 } 4335 }
4295 RemoveDeadInvalidatedCode(); 4336 RemoveDeadInvalidatedCode();
4296 4337
4297 { 4338 {
4298 GCTracer::Scope sweep_scope(heap()->tracer(), 4339 GCTracer::Scope sweep_scope(heap()->tracer(),
4299 GCTracer::Scope::MC_SWEEP_CODE); 4340 GCTracer::Scope::MC_SWEEP_CODE);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4341 if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) { 4382 if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) {
4342 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE); 4383 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE);
4343 p->SetWasSwept(); 4384 p->SetWasSwept();
4344 } 4385 }
4345 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); 4386 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
4346 } 4387 }
4347 } 4388 }
4348 4389
4349 4390
4350 void MarkCompactCollector::ParallelSweepSpacesComplete() { 4391 void MarkCompactCollector::ParallelSweepSpacesComplete() {
4351 ParallelSweepSpaceComplete(heap()->old_space()); 4392 ParallelSweepSpaceComplete(heap()->old_pointer_space());
4393 ParallelSweepSpaceComplete(heap()->old_data_space());
4352 } 4394 }
4353 4395
4354 4396
4355 void MarkCompactCollector::EnableCodeFlushing(bool enable) { 4397 void MarkCompactCollector::EnableCodeFlushing(bool enable) {
4356 if (isolate()->debug()->is_loaded() || 4398 if (isolate()->debug()->is_loaded() ||
4357 isolate()->debug()->has_break_points()) { 4399 isolate()->debug()->has_break_points()) {
4358 enable = false; 4400 enable = false;
4359 } 4401 }
4360 4402
4361 if (enable) { 4403 if (enable) {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
4552 SlotsBuffer* buffer = *buffer_address; 4594 SlotsBuffer* buffer = *buffer_address;
4553 while (buffer != NULL) { 4595 while (buffer != NULL) {
4554 SlotsBuffer* next_buffer = buffer->next(); 4596 SlotsBuffer* next_buffer = buffer->next();
4555 DeallocateBuffer(buffer); 4597 DeallocateBuffer(buffer);
4556 buffer = next_buffer; 4598 buffer = next_buffer;
4557 } 4599 }
4558 *buffer_address = NULL; 4600 *buffer_address = NULL;
4559 } 4601 }
4560 } 4602 }
4561 } // namespace v8::internal 4603 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698