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

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

Issue 11782028: Parallel and concurrent sweeping. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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/mark-compact.h ('k') | src/spaces.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 // 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 22 matching lines...) Expand all
33 #include "execution.h" 33 #include "execution.h"
34 #include "gdb-jit.h" 34 #include "gdb-jit.h"
35 #include "global-handles.h" 35 #include "global-handles.h"
36 #include "heap-profiler.h" 36 #include "heap-profiler.h"
37 #include "ic-inl.h" 37 #include "ic-inl.h"
38 #include "incremental-marking.h" 38 #include "incremental-marking.h"
39 #include "mark-compact.h" 39 #include "mark-compact.h"
40 #include "objects-visiting.h" 40 #include "objects-visiting.h"
41 #include "objects-visiting-inl.h" 41 #include "objects-visiting-inl.h"
42 #include "stub-cache.h" 42 #include "stub-cache.h"
43 #include "sweeper-thread.h"
43 44
44 namespace v8 { 45 namespace v8 {
45 namespace internal { 46 namespace internal {
46 47
47 48
48 const char* Marking::kWhiteBitPattern = "00"; 49 const char* Marking::kWhiteBitPattern = "00";
49 const char* Marking::kBlackBitPattern = "10"; 50 const char* Marking::kBlackBitPattern = "10";
50 const char* Marking::kGreyBitPattern = "11"; 51 const char* Marking::kGreyBitPattern = "11";
51 const char* Marking::kImpossibleBitPattern = "01"; 52 const char* Marking::kImpossibleBitPattern = "01";
52 53
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 497 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
497 MarkBit mark_bit = Marking::MarkBitFrom(obj); 498 MarkBit mark_bit = Marking::MarkBitFrom(obj);
498 mark_bit.Clear(); 499 mark_bit.Clear();
499 mark_bit.Next().Clear(); 500 mark_bit.Next().Clear();
500 Page::FromAddress(obj->address())->ResetProgressBar(); 501 Page::FromAddress(obj->address())->ResetProgressBar();
501 Page::FromAddress(obj->address())->ResetLiveBytes(); 502 Page::FromAddress(obj->address())->ResetLiveBytes();
502 } 503 }
503 } 504 }
504 505
505 506
507 void MarkCompactCollector::StartSweeperThreads() {
508 SweeperThread::set_sweeping_pending(true);
509 for (int i = 0; i < FLAG_sweeper_threads; i++) {
510 heap()->isolate()->sweeper_threads()[i]->StartSweeping();
511 }
512 }
513
514
515 void MarkCompactCollector::WaitUntilSweepingCompleted() {
516 if (SweeperThread::sweeping_pending()) {
517 for (int i = 0; i < FLAG_sweeper_threads; i++) {
518 heap()->isolate()->sweeper_threads()[i]->WaitForSweeperThread();
519 }
520 SweeperThread::set_sweeping_pending(false);
521 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_DATA_SPACE));
522 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_POINTER_SPACE));
523 heap()->FreeQueuedChunks();
524 }
525 }
526
527
528 intptr_t MarkCompactCollector::
529 StealMemoryFromSweeperThreads(PagedSpace* space) {
530 intptr_t freed_bytes = 0;
531 for (int i = 0; i < FLAG_sweeper_threads; i++) {
532 freed_bytes += heap()->isolate()->sweeper_threads()[i]->StealMemory(space);
533 }
534 return freed_bytes;
535 }
536
537
538 bool MarkCompactCollector::AreSweeperThreadsActivated() {
539 return heap()->isolate()->sweeper_threads() != NULL;
540 }
541
542
506 bool Marking::TransferMark(Address old_start, Address new_start) { 543 bool Marking::TransferMark(Address old_start, Address new_start) {
507 // This is only used when resizing an object. 544 // This is only used when resizing an object.
508 ASSERT(MemoryChunk::FromAddress(old_start) == 545 ASSERT(MemoryChunk::FromAddress(old_start) ==
509 MemoryChunk::FromAddress(new_start)); 546 MemoryChunk::FromAddress(new_start));
510 547
511 // If the mark doesn't move, we don't check the color of the object. 548 // If the mark doesn't move, we don't check the color of the object.
512 // It doesn't matter whether the object is black, since it hasn't changed 549 // It doesn't matter whether the object is black, since it hasn't changed
513 // size, so the adjustment to the live data count will be zero anyway. 550 // size, so the adjustment to the live data count will be zero anyway.
514 if (old_start == new_start) return false; 551 if (old_start == new_start) return false;
515 552
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 // variable. 835 // variable.
799 tracer_ = tracer; 836 tracer_ = tracer;
800 837
801 #ifdef DEBUG 838 #ifdef DEBUG
802 ASSERT(state_ == IDLE); 839 ASSERT(state_ == IDLE);
803 state_ = PREPARE_GC; 840 state_ = PREPARE_GC;
804 #endif 841 #endif
805 842
806 ASSERT(!FLAG_never_compact || !FLAG_always_compact); 843 ASSERT(!FLAG_never_compact || !FLAG_always_compact);
807 844
845 if (AreSweeperThreadsActivated() && FLAG_concurrent_sweeping) {
846 // Instead of waiting we could also abort the sweeper threads here.
847 WaitUntilSweepingCompleted();
848 }
849
808 // Clear marking bits if incremental marking is aborted. 850 // Clear marking bits if incremental marking is aborted.
809 if (was_marked_incrementally_ && abort_incremental_marking_) { 851 if (was_marked_incrementally_ && abort_incremental_marking_) {
810 heap()->incremental_marking()->Abort(); 852 heap()->incremental_marking()->Abort();
811 ClearMarkbits(); 853 ClearMarkbits();
812 AbortCompaction(); 854 AbortCompaction();
813 was_marked_incrementally_ = false; 855 was_marked_incrementally_ = false;
814 } 856 }
815 857
816 // Don't start compaction if we are in the middle of incremental 858 // Don't start compaction if we are in the middle of incremental
817 // marking cycle. We did not collect any slots. 859 // marking cycle. We did not collect any slots.
(...skipping 2306 matching lines...) Expand 10 before | Expand all | Expand 10 after
3124 } else { 3166 } else {
3125 if (FLAG_gc_verbose) { 3167 if (FLAG_gc_verbose) {
3126 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 3168 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
3127 reinterpret_cast<intptr_t>(p)); 3169 reinterpret_cast<intptr_t>(p));
3128 } 3170 }
3129 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3171 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3130 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 3172 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3131 3173
3132 switch (space->identity()) { 3174 switch (space->identity()) {
3133 case OLD_DATA_SPACE: 3175 case OLD_DATA_SPACE:
3134 SweepConservatively(space, p); 3176 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p);
3135 break; 3177 break;
3136 case OLD_POINTER_SPACE: 3178 case OLD_POINTER_SPACE:
3137 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>( 3179 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>(
3138 space, p, &updating_visitor); 3180 space, p, &updating_visitor);
3139 break; 3181 break;
3140 case CODE_SPACE: 3182 case CODE_SPACE:
3141 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>( 3183 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>(
3142 space, p, &updating_visitor); 3184 space, p, &updating_visitor);
3143 break; 3185 break;
3144 default: 3186 default:
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
3483 } 3525 }
3484 uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1; 3526 uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1;
3485 ASSERT((first_set_bit & cell) == first_set_bit); 3527 ASSERT((first_set_bit & cell) == first_set_bit);
3486 int live_objects = MarkWordToObjectStarts(first_set_bit, offsets); 3528 int live_objects = MarkWordToObjectStarts(first_set_bit, offsets);
3487 ASSERT(live_objects == 1); 3529 ASSERT(live_objects == 1);
3488 USE(live_objects); 3530 USE(live_objects);
3489 return block_address + offsets[0] * kPointerSize; 3531 return block_address + offsets[0] * kPointerSize;
3490 } 3532 }
3491 3533
3492 3534
3535 template<MarkCompactCollector::SweepingParallelism mode>
3536 static intptr_t Free(PagedSpace* space,
3537 FreeList* free_list,
3538 Address start,
3539 int size) {
3540 if (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY) {
3541 return space->Free(start, size);
3542 } else {
3543 return size - free_list->Free(start, size);
3544 }
3545 }
3546
3547
3493 // Sweeps a space conservatively. After this has been done the larger free 3548 // Sweeps a space conservatively. After this has been done the larger free
3494 // spaces have been put on the free list and the smaller ones have been 3549 // spaces have been put on the free list and the smaller ones have been
3495 // ignored and left untouched. A free space is always either ignored or put 3550 // ignored and left untouched. A free space is always either ignored or put
3496 // on the free list, never split up into two parts. This is important 3551 // on the free list, never split up into two parts. This is important
3497 // because it means that any FreeSpace maps left actually describe a region of 3552 // because it means that any FreeSpace maps left actually describe a region of
3498 // memory that can be ignored when scanning. Dead objects other than free 3553 // memory that can be ignored when scanning. Dead objects other than free
3499 // spaces will not contain the free space map. 3554 // spaces will not contain the free space map.
3500 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { 3555 template<MarkCompactCollector::SweepingParallelism mode>
3556 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
3557 FreeList* free_list,
3558 Page* p) {
3501 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3559 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
3502 double start_time = 0.0; 3560 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL &&
3503 if (FLAG_print_cumulative_gc_stat) { 3561 free_list != NULL) ||
3504 start_time = OS::TimeCurrentMillis(); 3562 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY &&
3505 } 3563 free_list == NULL));
3506 3564
3507 MarkBit::CellType* cells = p->markbits()->cells(); 3565 MarkBit::CellType* cells = p->markbits()->cells();
3508 p->MarkSweptConservatively(); 3566 p->MarkSweptConservatively();
3509 3567
3510 int last_cell_index = 3568 int last_cell_index =
3511 Bitmap::IndexToCell( 3569 Bitmap::IndexToCell(
3512 Bitmap::CellAlignIndex( 3570 Bitmap::CellAlignIndex(
3513 p->AddressToMarkbitIndex(p->area_end()))); 3571 p->AddressToMarkbitIndex(p->area_end())));
3514 3572
3515 int cell_index = 3573 int cell_index =
3516 Bitmap::IndexToCell( 3574 Bitmap::IndexToCell(
3517 Bitmap::CellAlignIndex( 3575 Bitmap::CellAlignIndex(
3518 p->AddressToMarkbitIndex(p->area_start()))); 3576 p->AddressToMarkbitIndex(p->area_start())));
3519 3577
3520 intptr_t freed_bytes = 0; 3578 intptr_t freed_bytes = 0;
3521 3579
3522 // This is the start of the 32 word block that we are currently looking at. 3580 // This is the start of the 32 word block that we are currently looking at.
3523 Address block_address = p->area_start(); 3581 Address block_address = p->area_start();
3524 3582
3525 // Skip over all the dead objects at the start of the page and mark them free. 3583 // Skip over all the dead objects at the start of the page and mark them free.
3526 for (; 3584 for (;
3527 cell_index < last_cell_index; 3585 cell_index < last_cell_index;
3528 cell_index++, block_address += 32 * kPointerSize) { 3586 cell_index++, block_address += 32 * kPointerSize) {
3529 if (cells[cell_index] != 0) break; 3587 if (cells[cell_index] != 0) break;
3530 } 3588 }
3531 size_t size = block_address - p->area_start(); 3589 size_t size = block_address - p->area_start();
3532 if (cell_index == last_cell_index) { 3590 if (cell_index == last_cell_index) {
3533 freed_bytes += static_cast<int>(space->Free(p->area_start(), 3591 freed_bytes += Free<mode>(space, free_list, p->area_start(), size);
3534 static_cast<int>(size)));
3535 ASSERT_EQ(0, p->LiveBytes()); 3592 ASSERT_EQ(0, p->LiveBytes());
3536 return freed_bytes; 3593 return freed_bytes;
3537 } 3594 }
3538 // Grow the size of the start-of-page free space a little to get up to the 3595 // Grow the size of the start-of-page free space a little to get up to the
3539 // first live object. 3596 // first live object.
3540 Address free_end = StartOfLiveObject(block_address, cells[cell_index]); 3597 Address free_end = StartOfLiveObject(block_address, cells[cell_index]);
3541 // Free the first free space. 3598 // Free the first free space.
3542 size = free_end - p->area_start(); 3599 size = free_end - p->area_start();
3543 freed_bytes += space->Free(p->area_start(), 3600 freed_bytes += Free<mode>(space, free_list, p->area_start(), size);
3544 static_cast<int>(size)); 3601
3545 // The start of the current free area is represented in undigested form by 3602 // The start of the current free area is represented in undigested form by
3546 // the address of the last 32-word section that contained a live object and 3603 // the address of the last 32-word section that contained a live object and
3547 // the marking bitmap for that cell, which describes where the live object 3604 // the marking bitmap for that cell, which describes where the live object
3548 // started. Unless we find a large free space in the bitmap we will not 3605 // started. Unless we find a large free space in the bitmap we will not
3549 // digest this pair into a real address. We start the iteration here at the 3606 // digest this pair into a real address. We start the iteration here at the
3550 // first word in the marking bit map that indicates a live object. 3607 // first word in the marking bit map that indicates a live object.
3551 Address free_start = block_address; 3608 Address free_start = block_address;
3552 uint32_t free_start_cell = cells[cell_index]; 3609 uint32_t free_start_cell = cells[cell_index];
3553 3610
3554 for ( ; 3611 for ( ;
3555 cell_index < last_cell_index; 3612 cell_index < last_cell_index;
3556 cell_index++, block_address += 32 * kPointerSize) { 3613 cell_index++, block_address += 32 * kPointerSize) {
3557 ASSERT(static_cast<unsigned>(cell_index) == 3614 ASSERT((unsigned)cell_index ==
3558 Bitmap::IndexToCell( 3615 Bitmap::IndexToCell(
3559 Bitmap::CellAlignIndex( 3616 Bitmap::CellAlignIndex(
3560 p->AddressToMarkbitIndex(block_address)))); 3617 p->AddressToMarkbitIndex(block_address))));
3561 uint32_t cell = cells[cell_index]; 3618 uint32_t cell = cells[cell_index];
3562 if (cell != 0) { 3619 if (cell != 0) {
3563 // We have a live object. Check approximately whether it is more than 32 3620 // We have a live object. Check approximately whether it is more than 32
3564 // words since the last live object. 3621 // words since the last live object.
3565 if (block_address - free_start > 32 * kPointerSize) { 3622 if (block_address - free_start > 32 * kPointerSize) {
3566 free_start = DigestFreeStart(free_start, free_start_cell); 3623 free_start = DigestFreeStart(free_start, free_start_cell);
3567 if (block_address - free_start > 32 * kPointerSize) { 3624 if (block_address - free_start > 32 * kPointerSize) {
3568 // Now that we know the exact start of the free space it still looks 3625 // Now that we know the exact start of the free space it still looks
3569 // like we have a large enough free space to be worth bothering with. 3626 // like we have a large enough free space to be worth bothering with.
3570 // so now we need to find the start of the first live object at the 3627 // so now we need to find the start of the first live object at the
3571 // end of the free space. 3628 // end of the free space.
3572 free_end = StartOfLiveObject(block_address, cell); 3629 free_end = StartOfLiveObject(block_address, cell);
3573 freed_bytes += space->Free(free_start, 3630 freed_bytes += Free<mode>(space, free_list, free_start,
3574 static_cast<int>(free_end - free_start)); 3631 static_cast<int>(free_end - free_start));
3575 } 3632 }
3576 } 3633 }
3577 // Update our undigested record of where the current free area started. 3634 // Update our undigested record of where the current free area started.
3578 free_start = block_address; 3635 free_start = block_address;
3579 free_start_cell = cell; 3636 free_start_cell = cell;
3580 // Clear marking bits for current cell. 3637 // Clear marking bits for current cell.
3581 cells[cell_index] = 0; 3638 cells[cell_index] = 0;
3582 } 3639 }
3583 } 3640 }
3584 3641
3585 // Handle the free space at the end of the page. 3642 // Handle the free space at the end of the page.
3586 if (block_address - free_start > 32 * kPointerSize) { 3643 if (block_address - free_start > 32 * kPointerSize) {
3587 free_start = DigestFreeStart(free_start, free_start_cell); 3644 free_start = DigestFreeStart(free_start, free_start_cell);
3588 freed_bytes += space->Free(free_start, 3645 freed_bytes += Free<mode>(space, free_list, free_start,
3589 static_cast<int>(block_address - free_start)); 3646 static_cast<int>(block_address - free_start));
3590 } 3647 }
3591 3648
3592 p->ResetLiveBytes(); 3649 p->ResetLiveBytes();
3650 return freed_bytes;
3651 }
3593 3652
3594 if (FLAG_print_cumulative_gc_stat) { 3653
3595 space->heap()->AddSweepingTime(OS::TimeCurrentMillis() - start_time); 3654 void MarkCompactCollector::SweepInParallel(PagedSpace* space,
3655 FreeList* private_free_list,
3656 FreeList* free_list) {
3657 PageIterator it(space);
3658 while (it.has_next()) {
3659 Page* p = it.next();
3660
3661 if (p->TryParallelSweeping()) {
3662 SweepConservatively<SWEEP_IN_PARALLEL>(space, private_free_list, p);
3663 free_list->Concatenate(private_free_list);
3664 }
3596 } 3665 }
3597 return freed_bytes;
3598 } 3666 }
3599 3667
3600 3668
3601 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 3669 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
3602 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 3670 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
3603 sweeper == LAZY_CONSERVATIVE); 3671 sweeper == LAZY_CONSERVATIVE);
3604
3605 space->ClearStats(); 3672 space->ClearStats();
3606 3673
3607 PageIterator it(space); 3674 PageIterator it(space);
3608 3675
3609 intptr_t freed_bytes = 0; 3676 intptr_t freed_bytes = 0;
3610 int pages_swept = 0; 3677 int pages_swept = 0;
3611 bool lazy_sweeping_active = false; 3678 bool lazy_sweeping_active = false;
3612 bool unused_page_present = false; 3679 bool unused_page_present = false;
3613 3680
3614 while (it.has_next()) { 3681 while (it.has_next()) {
3615 Page* p = it.next(); 3682 Page* p = it.next();
3616 3683
3684 ASSERT(p->parallel_sweeping() == 0);
3617 // Clear sweeping flags indicating that marking bits are still intact. 3685 // Clear sweeping flags indicating that marking bits are still intact.
3618 p->ClearSweptPrecisely(); 3686 p->ClearSweptPrecisely();
3619 p->ClearSweptConservatively(); 3687 p->ClearSweptConservatively();
3620 3688
3621 if (p->IsEvacuationCandidate()) { 3689 if (p->IsEvacuationCandidate()) {
3622 ASSERT(evacuation_candidates_.length() > 0); 3690 ASSERT(evacuation_candidates_.length() > 0);
3623 continue; 3691 continue;
3624 } 3692 }
3625 3693
3626 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 3694 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
(...skipping 25 matching lines...) Expand all
3652 space->IncreaseUnsweptFreeBytes(p); 3720 space->IncreaseUnsweptFreeBytes(p);
3653 continue; 3721 continue;
3654 } 3722 }
3655 3723
3656 switch (sweeper) { 3724 switch (sweeper) {
3657 case CONSERVATIVE: { 3725 case CONSERVATIVE: {
3658 if (FLAG_gc_verbose) { 3726 if (FLAG_gc_verbose) {
3659 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 3727 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
3660 reinterpret_cast<intptr_t>(p)); 3728 reinterpret_cast<intptr_t>(p));
3661 } 3729 }
3662 SweepConservatively(space, p); 3730 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p);
3663 pages_swept++; 3731 pages_swept++;
3664 break; 3732 break;
3665 } 3733 }
3666 case LAZY_CONSERVATIVE: { 3734 case LAZY_CONSERVATIVE: {
3667 if (FLAG_gc_verbose) { 3735 if (FLAG_gc_verbose) {
3668 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively as needed.\n", 3736 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively as needed.\n",
3669 reinterpret_cast<intptr_t>(p)); 3737 reinterpret_cast<intptr_t>(p));
3670 } 3738 }
3671 freed_bytes += SweepConservatively(space, p); 3739 freed_bytes += SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p);
3672 pages_swept++; 3740 pages_swept++;
3673 space->SetPagesToSweep(p->next_page()); 3741 space->SetPagesToSweep(p->next_page());
3674 lazy_sweeping_active = true; 3742 lazy_sweeping_active = true;
3675 break; 3743 break;
3676 } 3744 }
3745 case PARALLEL_CONSERVATIVE: {
3746 if (FLAG_gc_verbose) {
3747 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n",
3748 reinterpret_cast<intptr_t>(p));
3749 }
3750 p->set_parallel_sweeping(1);
3751 break;
3752 }
3677 case PRECISE: { 3753 case PRECISE: {
3678 if (FLAG_gc_verbose) { 3754 if (FLAG_gc_verbose) {
3679 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n", 3755 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n",
3680 reinterpret_cast<intptr_t>(p)); 3756 reinterpret_cast<intptr_t>(p));
3681 } 3757 }
3682 if (space->identity() == CODE_SPACE) { 3758 if (space->identity() == CODE_SPACE) {
3683 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(space, p, NULL); 3759 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(space, p, NULL);
3684 } else { 3760 } else {
3685 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(space, p, NULL); 3761 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(space, p, NULL);
3686 } 3762 }
(...skipping 19 matching lines...) Expand all
3706 3782
3707 void MarkCompactCollector::SweepSpaces() { 3783 void MarkCompactCollector::SweepSpaces() {
3708 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); 3784 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
3709 #ifdef DEBUG 3785 #ifdef DEBUG
3710 state_ = SWEEP_SPACES; 3786 state_ = SWEEP_SPACES;
3711 #endif 3787 #endif
3712 SweeperType how_to_sweep = 3788 SweeperType how_to_sweep =
3713 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; 3789 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE;
3714 if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE; 3790 if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE;
3715 if (sweep_precisely_) how_to_sweep = PRECISE; 3791 if (sweep_precisely_) how_to_sweep = PRECISE;
3792 if (AreSweeperThreadsActivated()) how_to_sweep = PARALLEL_CONSERVATIVE;
3716 // Noncompacting collections simply sweep the spaces to clear the mark 3793 // Noncompacting collections simply sweep the spaces to clear the mark
3717 // bits and free the nonlive blocks (for old and map spaces). We sweep 3794 // bits and free the nonlive blocks (for old and map spaces). We sweep
3718 // the map space last because freeing non-live maps overwrites them and 3795 // the map space last because freeing non-live maps overwrites them and
3719 // the other spaces rely on possibly non-live maps to get the sizes for 3796 // the other spaces rely on possibly non-live maps to get the sizes for
3720 // non-live objects. 3797 // non-live objects.
3798
3721 SweepSpace(heap()->old_pointer_space(), how_to_sweep); 3799 SweepSpace(heap()->old_pointer_space(), how_to_sweep);
3722 SweepSpace(heap()->old_data_space(), how_to_sweep); 3800 SweepSpace(heap()->old_data_space(), how_to_sweep);
3723 3801
3724 RemoveDeadInvalidatedCode(); 3802 RemoveDeadInvalidatedCode();
3725 SweepSpace(heap()->code_space(), PRECISE); 3803 SweepSpace(heap()->code_space(), PRECISE);
3726 3804
3727 SweepSpace(heap()->cell_space(), PRECISE); 3805 SweepSpace(heap()->cell_space(), PRECISE);
3728 3806
3729 EvacuateNewSpaceAndCandidates(); 3807 EvacuateNewSpaceAndCandidates();
3730 3808
3809 if (AreSweeperThreadsActivated()) {
3810 // TODO(hpayer): The starting of the sweeper threads should be after
3811 // SweepSpace old data space.
3812 StartSweeperThreads();
3813 if (FLAG_parallel_sweeping && !FLAG_concurrent_sweeping) {
3814 WaitUntilSweepingCompleted();
3815 }
3816 }
3817
3731 // ClearNonLiveTransitions depends on precise sweeping of map space to 3818 // ClearNonLiveTransitions depends on precise sweeping of map space to
3732 // detect whether unmarked map became dead in this collection or in one 3819 // detect whether unmarked map became dead in this collection or in one
3733 // of the previous ones. 3820 // of the previous ones.
3734 SweepSpace(heap()->map_space(), PRECISE); 3821 SweepSpace(heap()->map_space(), PRECISE);
3735 3822
3736 // Deallocate unmarked objects and clear marked bits for marked objects. 3823 // Deallocate unmarked objects and clear marked bits for marked objects.
3737 heap_->lo_space()->FreeUnmarkedObjects(); 3824 heap_->lo_space()->FreeUnmarkedObjects();
3738 } 3825 }
3739 3826
3740 3827
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
3928 while (buffer != NULL) { 4015 while (buffer != NULL) {
3929 SlotsBuffer* next_buffer = buffer->next(); 4016 SlotsBuffer* next_buffer = buffer->next();
3930 DeallocateBuffer(buffer); 4017 DeallocateBuffer(buffer);
3931 buffer = next_buffer; 4018 buffer = next_buffer;
3932 } 4019 }
3933 *buffer_address = NULL; 4020 *buffer_address = NULL;
3934 } 4021 }
3935 4022
3936 4023
3937 } } // namespace v8::internal 4024 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698