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

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
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 23 matching lines...) Expand all
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 "liveobjectlist-inl.h" 39 #include "liveobjectlist-inl.h"
40 #include "mark-compact.h" 40 #include "mark-compact.h"
41 #include "objects-visiting.h" 41 #include "objects-visiting.h"
42 #include "objects-visiting-inl.h" 42 #include "objects-visiting-inl.h"
43 #include "stub-cache.h" 43 #include "stub-cache.h"
44 #include "sweeper-thread.h"
44 45
45 namespace v8 { 46 namespace v8 {
46 namespace internal { 47 namespace internal {
47 48
48 49
49 const char* Marking::kWhiteBitPattern = "00"; 50 const char* Marking::kWhiteBitPattern = "00";
50 const char* Marking::kBlackBitPattern = "10"; 51 const char* Marking::kBlackBitPattern = "10";
51 const char* Marking::kGreyBitPattern = "11"; 52 const char* Marking::kGreyBitPattern = "11";
52 const char* Marking::kImpossibleBitPattern = "01"; 53 const char* Marking::kImpossibleBitPattern = "01";
53 54
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 488 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
488 MarkBit mark_bit = Marking::MarkBitFrom(obj); 489 MarkBit mark_bit = Marking::MarkBitFrom(obj);
489 mark_bit.Clear(); 490 mark_bit.Clear();
490 mark_bit.Next().Clear(); 491 mark_bit.Next().Clear();
491 Page::FromAddress(obj->address())->ResetProgressBar(); 492 Page::FromAddress(obj->address())->ResetProgressBar();
492 Page::FromAddress(obj->address())->ResetLiveBytes(); 493 Page::FromAddress(obj->address())->ResetLiveBytes();
493 } 494 }
494 } 495 }
495 496
496 497
498 void MarkCompactCollector::StartSweeperThreads() {
499 SweeperThread::set_sweeping_pending(true);
500 for (int i = 0; i < FLAG_sweeper_threads; i++) {
501 heap()->isolate()->sweeper_threads()[i]->StartSweeping();
502 }
503 }
504
505
506 void MarkCompactCollector::WaitUntilSweepingCompleted() {
507 if (SweeperThread::sweeping_pending()) {
508 for (int i = 0; i < FLAG_sweeper_threads; i++) {
509 heap()->isolate()->sweeper_threads()[i]->WaitForSweeperThread();
510 }
511 SweeperThread::set_sweeping_pending(false);
512 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_DATA_SPACE));
513 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_POINTER_SPACE));
514 heap()->FreeQueuedChunks();
515 }
516 }
517
518
519 intptr_t MarkCompactCollector::
520 StealMemoryFromSweeperThreads(PagedSpace* space) {
521 intptr_t freed_bytes = 0;
522 for (int i = 0; i < FLAG_sweeper_threads; i++) {
523 freed_bytes += heap()->isolate()->sweeper_threads()[i]->StealMemory(space);
524 }
525 return freed_bytes;
526 }
527
528
529 bool MarkCompactCollector::AreSweeperThreadsActivated() {
530 return heap()->isolate()->sweeper_threads() != NULL;
531 }
532
533
497 bool Marking::TransferMark(Address old_start, Address new_start) { 534 bool Marking::TransferMark(Address old_start, Address new_start) {
498 // This is only used when resizing an object. 535 // This is only used when resizing an object.
499 ASSERT(MemoryChunk::FromAddress(old_start) == 536 ASSERT(MemoryChunk::FromAddress(old_start) ==
500 MemoryChunk::FromAddress(new_start)); 537 MemoryChunk::FromAddress(new_start));
501 538
502 // If the mark doesn't move, we don't check the color of the object. 539 // If the mark doesn't move, we don't check the color of the object.
503 // It doesn't matter whether the object is black, since it hasn't changed 540 // It doesn't matter whether the object is black, since it hasn't changed
504 // size, so the adjustment to the live data count will be zero anyway. 541 // size, so the adjustment to the live data count will be zero anyway.
505 if (old_start == new_start) return false; 542 if (old_start == new_start) return false;
506 543
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 // variable. 826 // variable.
790 tracer_ = tracer; 827 tracer_ = tracer;
791 828
792 #ifdef DEBUG 829 #ifdef DEBUG
793 ASSERT(state_ == IDLE); 830 ASSERT(state_ == IDLE);
794 state_ = PREPARE_GC; 831 state_ = PREPARE_GC;
795 #endif 832 #endif
796 833
797 ASSERT(!FLAG_never_compact || !FLAG_always_compact); 834 ASSERT(!FLAG_never_compact || !FLAG_always_compact);
798 835
836 if (AreSweeperThreadsActivated() && FLAG_concurrent_sweeping) {
837 // Instead of waiting we could also abort the sweeper threads here.
838 WaitUntilSweepingCompleted();
839 }
840
799 // Clear marking bits if incremental marking is aborted. 841 // Clear marking bits if incremental marking is aborted.
800 if (was_marked_incrementally_ && abort_incremental_marking_) { 842 if (was_marked_incrementally_ && abort_incremental_marking_) {
801 heap()->incremental_marking()->Abort(); 843 heap()->incremental_marking()->Abort();
802 ClearMarkbits(); 844 ClearMarkbits();
803 AbortCompaction(); 845 AbortCompaction();
804 was_marked_incrementally_ = false; 846 was_marked_incrementally_ = false;
805 } 847 }
806 848
807 // Don't start compaction if we are in the middle of incremental 849 // Don't start compaction if we are in the middle of incremental
808 // marking cycle. We did not collect any slots. 850 // marking cycle. We did not collect any slots.
(...skipping 2211 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 } else { 3062 } else {
3021 if (FLAG_gc_verbose) { 3063 if (FLAG_gc_verbose) {
3022 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 3064 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
3023 reinterpret_cast<intptr_t>(p)); 3065 reinterpret_cast<intptr_t>(p));
3024 } 3066 }
3025 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3067 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3026 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 3068 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3027 3069
3028 switch (space->identity()) { 3070 switch (space->identity()) {
3029 case OLD_DATA_SPACE: 3071 case OLD_DATA_SPACE:
3030 SweepConservatively(space, p); 3072 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p);
3031 break; 3073 break;
3032 case OLD_POINTER_SPACE: 3074 case OLD_POINTER_SPACE:
3033 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>( 3075 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>(
3034 space, p, &updating_visitor); 3076 space, p, &updating_visitor);
3035 break; 3077 break;
3036 case CODE_SPACE: 3078 case CODE_SPACE:
3037 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>( 3079 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>(
3038 space, p, &updating_visitor); 3080 space, p, &updating_visitor);
3039 break; 3081 break;
3040 default: 3082 default:
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
3376 } 3418 }
3377 uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1; 3419 uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1;
3378 ASSERT((first_set_bit & cell) == first_set_bit); 3420 ASSERT((first_set_bit & cell) == first_set_bit);
3379 int live_objects = MarkWordToObjectStarts(first_set_bit, offsets); 3421 int live_objects = MarkWordToObjectStarts(first_set_bit, offsets);
3380 ASSERT(live_objects == 1); 3422 ASSERT(live_objects == 1);
3381 USE(live_objects); 3423 USE(live_objects);
3382 return block_address + offsets[0] * kPointerSize; 3424 return block_address + offsets[0] * kPointerSize;
3383 } 3425 }
3384 3426
3385 3427
3428 static intptr_t Free(FreeList* free_list,
3429 Address start,
3430 int size) {
3431 return size - free_list->Free(start, size);
3432 }
3433
3434
3386 // Sweeps a space conservatively. After this has been done the larger free 3435 // Sweeps a space conservatively. After this has been done the larger free
3387 // spaces have been put on the free list and the smaller ones have been 3436 // spaces have been put on the free list and the smaller ones have been
3388 // ignored and left untouched. A free space is always either ignored or put 3437 // ignored and left untouched. A free space is always either ignored or put
3389 // on the free list, never split up into two parts. This is important 3438 // on the free list, never split up into two parts. This is important
3390 // because it means that any FreeSpace maps left actually describe a region of 3439 // because it means that any FreeSpace maps left actually describe a region of
3391 // memory that can be ignored when scanning. Dead objects other than free 3440 // memory that can be ignored when scanning. Dead objects other than free
3392 // spaces will not contain the free space map. 3441 // spaces will not contain the free space map.
3393 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { 3442 template<MarkCompactCollector::SweepingParallelism mode>
3443 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
3444 FreeList* free_list,
3445 Page* p) {
3394 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3446 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
3447 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL &&
3448 free_list != NULL) ||
3449 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY &&
3450 free_list == NULL));
3451
3395 MarkBit::CellType* cells = p->markbits()->cells(); 3452 MarkBit::CellType* cells = p->markbits()->cells();
3396 p->MarkSweptConservatively(); 3453 p->MarkSweptConservatively();
3397 3454
3398 int last_cell_index = 3455 int last_cell_index =
3399 Bitmap::IndexToCell( 3456 Bitmap::IndexToCell(
3400 Bitmap::CellAlignIndex( 3457 Bitmap::CellAlignIndex(
3401 p->AddressToMarkbitIndex(p->area_end()))); 3458 p->AddressToMarkbitIndex(p->area_end())));
3402 3459
3403 int cell_index = 3460 int cell_index =
3404 Bitmap::IndexToCell( 3461 Bitmap::IndexToCell(
3405 Bitmap::CellAlignIndex( 3462 Bitmap::CellAlignIndex(
3406 p->AddressToMarkbitIndex(p->area_start()))); 3463 p->AddressToMarkbitIndex(p->area_start())));
3407 3464
3408 intptr_t freed_bytes = 0; 3465 intptr_t freed_bytes = 0;
3409 3466
3410 // This is the start of the 32 word block that we are currently looking at. 3467 // This is the start of the 32 word block that we are currently looking at.
3411 Address block_address = p->area_start(); 3468 Address block_address = p->area_start();
3412 3469
3413 // Skip over all the dead objects at the start of the page and mark them free. 3470 // Skip over all the dead objects at the start of the page and mark them free.
3414 for (; 3471 for (;
3415 cell_index < last_cell_index; 3472 cell_index < last_cell_index;
3416 cell_index++, block_address += 32 * kPointerSize) { 3473 cell_index++, block_address += 32 * kPointerSize) {
3417 if (cells[cell_index] != 0) break; 3474 if (cells[cell_index] != 0) break;
3418 } 3475 }
3419 size_t size = block_address - p->area_start(); 3476 size_t size = block_address - p->area_start();
3420 if (cell_index == last_cell_index) { 3477 if (cell_index == last_cell_index) {
3421 freed_bytes += static_cast<int>(space->Free(p->area_start(), 3478 if (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY) {
Michael Starzinger 2013/01/30 11:01:19 You could factor out this logic and move it into t
Hannes Payer (out of office) 2013/01/30 12:07:32 I templatized Free, the code looks cleaner. On 20
3422 static_cast<int>(size))); 3479 freed_bytes += static_cast<int>(space->Free(p->area_start(),
3480 static_cast<int>(size)));
3481 } else {
3482 freed_bytes += Free(free_list, p->area_start(), static_cast<int>(size));
3483 }
3423 ASSERT_EQ(0, p->LiveBytes()); 3484 ASSERT_EQ(0, p->LiveBytes());
3424 return freed_bytes; 3485 return freed_bytes;
3425 } 3486 }
3426 // Grow the size of the start-of-page free space a little to get up to the 3487 // Grow the size of the start-of-page free space a little to get up to the
3427 // first live object. 3488 // first live object.
3428 Address free_end = StartOfLiveObject(block_address, cells[cell_index]); 3489 Address free_end = StartOfLiveObject(block_address, cells[cell_index]);
3429 // Free the first free space. 3490 // Free the first free space.
3430 size = free_end - p->area_start(); 3491 size = free_end - p->area_start();
3431 freed_bytes += space->Free(p->area_start(), 3492 if (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY) {
3432 static_cast<int>(size)); 3493 freed_bytes += space->Free(p->area_start(), static_cast<int>(size));
3494 } else {
3495 freed_bytes += Free(free_list, p->area_start(), static_cast<int>(size));
3496 }
3433 // The start of the current free area is represented in undigested form by 3497 // The start of the current free area is represented in undigested form by
3434 // the address of the last 32-word section that contained a live object and 3498 // the address of the last 32-word section that contained a live object and
3435 // the marking bitmap for that cell, which describes where the live object 3499 // the marking bitmap for that cell, which describes where the live object
3436 // started. Unless we find a large free space in the bitmap we will not 3500 // started. Unless we find a large free space in the bitmap we will not
3437 // digest this pair into a real address. We start the iteration here at the 3501 // digest this pair into a real address. We start the iteration here at the
3438 // first word in the marking bit map that indicates a live object. 3502 // first word in the marking bit map that indicates a live object.
3439 Address free_start = block_address; 3503 Address free_start = block_address;
3440 uint32_t free_start_cell = cells[cell_index]; 3504 uint32_t free_start_cell = cells[cell_index];
3441 3505
3442 for ( ; 3506 for ( ;
3443 cell_index < last_cell_index; 3507 cell_index < last_cell_index;
3444 cell_index++, block_address += 32 * kPointerSize) { 3508 cell_index++, block_address += 32 * kPointerSize) {
3445 ASSERT((unsigned)cell_index == 3509 ASSERT((unsigned)cell_index ==
3446 Bitmap::IndexToCell( 3510 Bitmap::IndexToCell(
3447 Bitmap::CellAlignIndex( 3511 Bitmap::CellAlignIndex(
3448 p->AddressToMarkbitIndex(block_address)))); 3512 p->AddressToMarkbitIndex(block_address))));
3449 uint32_t cell = cells[cell_index]; 3513 uint32_t cell = cells[cell_index];
3450 if (cell != 0) { 3514 if (cell != 0) {
3451 // We have a live object. Check approximately whether it is more than 32 3515 // We have a live object. Check approximately whether it is more than 32
3452 // words since the last live object. 3516 // words since the last live object.
3453 if (block_address - free_start > 32 * kPointerSize) { 3517 if (block_address - free_start > 32 * kPointerSize) {
3454 free_start = DigestFreeStart(free_start, free_start_cell); 3518 free_start = DigestFreeStart(free_start, free_start_cell);
3455 if (block_address - free_start > 32 * kPointerSize) { 3519 if (block_address - free_start > 32 * kPointerSize) {
3456 // Now that we know the exact start of the free space it still looks 3520 // Now that we know the exact start of the free space it still looks
3457 // like we have a large enough free space to be worth bothering with. 3521 // like we have a large enough free space to be worth bothering with.
3458 // so now we need to find the start of the first live object at the 3522 // so now we need to find the start of the first live object at the
3459 // end of the free space. 3523 // end of the free space.
3460 free_end = StartOfLiveObject(block_address, cell); 3524 free_end = StartOfLiveObject(block_address, cell);
3461 freed_bytes += space->Free(free_start, 3525 if (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY) {
3462 static_cast<int>(free_end - free_start)); 3526 freed_bytes += space->Free(free_start,
3527 static_cast<int>(free_end - free_start));
3528 } else {
3529 freed_bytes += Free(free_list, free_start,
3530 static_cast<int>(free_end - free_start));
3531 }
3463 } 3532 }
3464 } 3533 }
3465 // Update our undigested record of where the current free area started. 3534 // Update our undigested record of where the current free area started.
3466 free_start = block_address; 3535 free_start = block_address;
3467 free_start_cell = cell; 3536 free_start_cell = cell;
3468 // Clear marking bits for current cell. 3537 // Clear marking bits for current cell.
3469 cells[cell_index] = 0; 3538 cells[cell_index] = 0;
3470 } 3539 }
3471 } 3540 }
3472 3541
3473 // Handle the free space at the end of the page. 3542 // Handle the free space at the end of the page.
3474 if (block_address - free_start > 32 * kPointerSize) { 3543 if (block_address - free_start > 32 * kPointerSize) {
3475 free_start = DigestFreeStart(free_start, free_start_cell); 3544 free_start = DigestFreeStart(free_start, free_start_cell);
3476 freed_bytes += space->Free(free_start, 3545 if (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY) {
3477 static_cast<int>(block_address - free_start)); 3546 freed_bytes += space->Free(free_start,
3547 static_cast<int>(block_address - free_start));
3548 } else {
3549 freed_bytes += Free(free_list, free_start,
3550 static_cast<int>(block_address - free_start));
3551 }
3478 } 3552 }
3479 3553
3480 p->ResetLiveBytes(); 3554 p->ResetLiveBytes();
3481 return freed_bytes; 3555 return freed_bytes;
3482 } 3556 }
3483 3557
3484 3558
3559 void MarkCompactCollector::SweepInParallel(PagedSpace* space,
3560 FreeList* private_free_list,
3561 FreeList* free_list) {
3562 PageIterator it(space);
3563 while (it.has_next()) {
3564 Page* p = it.next();
3565
3566 if (p->TryParallelSweeping()) {
3567 SweepConservatively<SWEEP_IN_PARALLEL>(space, private_free_list, p);
3568 free_list->Concatenate(private_free_list);
3569 }
3570 }
3571 }
3572
3573
3485 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 3574 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
3486 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 3575 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
3487 sweeper == LAZY_CONSERVATIVE); 3576 sweeper == LAZY_CONSERVATIVE);
3488
3489 space->ClearStats(); 3577 space->ClearStats();
3490 3578
3491 PageIterator it(space); 3579 PageIterator it(space);
3492 3580
3493 intptr_t freed_bytes = 0; 3581 intptr_t freed_bytes = 0;
3494 int pages_swept = 0; 3582 int pages_swept = 0;
3495 bool lazy_sweeping_active = false; 3583 bool lazy_sweeping_active = false;
3496 bool unused_page_present = false; 3584 bool unused_page_present = false;
3497 3585
3498 while (it.has_next()) { 3586 while (it.has_next()) {
3499 Page* p = it.next(); 3587 Page* p = it.next();
3500 3588
3589 ASSERT(p->parallel_sweeping() == 0);
3501 // Clear sweeping flags indicating that marking bits are still intact. 3590 // Clear sweeping flags indicating that marking bits are still intact.
3502 p->ClearSweptPrecisely(); 3591 p->ClearSweptPrecisely();
3503 p->ClearSweptConservatively(); 3592 p->ClearSweptConservatively();
3504 3593
3505 if (p->IsEvacuationCandidate()) { 3594 if (p->IsEvacuationCandidate()) {
3506 ASSERT(evacuation_candidates_.length() > 0); 3595 ASSERT(evacuation_candidates_.length() > 0);
3507 continue; 3596 continue;
3508 } 3597 }
3509 3598
3510 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 3599 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
(...skipping 25 matching lines...) Expand all
3536 space->IncreaseUnsweptFreeBytes(p); 3625 space->IncreaseUnsweptFreeBytes(p);
3537 continue; 3626 continue;
3538 } 3627 }
3539 3628
3540 switch (sweeper) { 3629 switch (sweeper) {
3541 case CONSERVATIVE: { 3630 case CONSERVATIVE: {
3542 if (FLAG_gc_verbose) { 3631 if (FLAG_gc_verbose) {
3543 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 3632 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
3544 reinterpret_cast<intptr_t>(p)); 3633 reinterpret_cast<intptr_t>(p));
3545 } 3634 }
3546 SweepConservatively(space, p); 3635 SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p);
3547 pages_swept++; 3636 pages_swept++;
3548 break; 3637 break;
3549 } 3638 }
3550 case LAZY_CONSERVATIVE: { 3639 case LAZY_CONSERVATIVE: {
3551 if (FLAG_gc_verbose) { 3640 if (FLAG_gc_verbose) {
3552 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively as needed.\n", 3641 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively as needed.\n",
3553 reinterpret_cast<intptr_t>(p)); 3642 reinterpret_cast<intptr_t>(p));
3554 } 3643 }
3555 freed_bytes += SweepConservatively(space, p); 3644 freed_bytes += SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p);
3556 pages_swept++; 3645 pages_swept++;
3557 space->SetPagesToSweep(p->next_page()); 3646 space->SetPagesToSweep(p->next_page());
3558 lazy_sweeping_active = true; 3647 lazy_sweeping_active = true;
3559 break; 3648 break;
3560 } 3649 }
3650 case PARALLEL_CONSERVATIVE: {
3651 if (FLAG_gc_verbose) {
3652 PrintF("Prepare conservatively parallel sweeping 0x%" V8PRIxPTR ".\n",
Michael Starzinger 2013/01/30 11:01:19 Let's rephrase this log line to "Sweeping 0x??? co
Hannes Payer (out of office) 2013/01/30 12:07:32 Done.
3653 reinterpret_cast<intptr_t>(p));
3654 }
3655 p->set_parallel_sweeping(1);
3656 break;
3657 }
3561 case PRECISE: { 3658 case PRECISE: {
3562 if (FLAG_gc_verbose) { 3659 if (FLAG_gc_verbose) {
3563 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n", 3660 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n",
3564 reinterpret_cast<intptr_t>(p)); 3661 reinterpret_cast<intptr_t>(p));
3565 } 3662 }
3566 if (space->identity() == CODE_SPACE) { 3663 if (space->identity() == CODE_SPACE) {
3567 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(space, p, NULL); 3664 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(space, p, NULL);
3568 } else { 3665 } else {
3569 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(space, p, NULL); 3666 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(space, p, NULL);
3570 } 3667 }
(...skipping 19 matching lines...) Expand all
3590 3687
3591 void MarkCompactCollector::SweepSpaces() { 3688 void MarkCompactCollector::SweepSpaces() {
3592 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); 3689 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
3593 #ifdef DEBUG 3690 #ifdef DEBUG
3594 state_ = SWEEP_SPACES; 3691 state_ = SWEEP_SPACES;
3595 #endif 3692 #endif
3596 SweeperType how_to_sweep = 3693 SweeperType how_to_sweep =
3597 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; 3694 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE;
3598 if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE; 3695 if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE;
3599 if (sweep_precisely_) how_to_sweep = PRECISE; 3696 if (sweep_precisely_) how_to_sweep = PRECISE;
3697 if (AreSweeperThreadsActivated()) how_to_sweep = PARALLEL_CONSERVATIVE;
3600 // Noncompacting collections simply sweep the spaces to clear the mark 3698 // Noncompacting collections simply sweep the spaces to clear the mark
3601 // bits and free the nonlive blocks (for old and map spaces). We sweep 3699 // bits and free the nonlive blocks (for old and map spaces). We sweep
3602 // the map space last because freeing non-live maps overwrites them and 3700 // the map space last because freeing non-live maps overwrites them and
3603 // the other spaces rely on possibly non-live maps to get the sizes for 3701 // the other spaces rely on possibly non-live maps to get the sizes for
3604 // non-live objects. 3702 // non-live objects.
3703
3605 SweepSpace(heap()->old_pointer_space(), how_to_sweep); 3704 SweepSpace(heap()->old_pointer_space(), how_to_sweep);
3606 SweepSpace(heap()->old_data_space(), how_to_sweep); 3705 SweepSpace(heap()->old_data_space(), how_to_sweep);
3607 3706
Michael Starzinger 2013/01/30 11:01:19 I think you have white-space on that empty line. S
Hannes Payer (out of office) 2013/01/30 12:07:32 Done.
3608 RemoveDeadInvalidatedCode(); 3707 RemoveDeadInvalidatedCode();
3609 SweepSpace(heap()->code_space(), PRECISE); 3708 SweepSpace(heap()->code_space(), PRECISE);
3610 3709
3611 SweepSpace(heap()->cell_space(), PRECISE); 3710 SweepSpace(heap()->cell_space(), PRECISE);
3612 3711
3613 EvacuateNewSpaceAndCandidates(); 3712 EvacuateNewSpaceAndCandidates();
3614 3713
3714 if (AreSweeperThreadsActivated()) {
3715 // The starting of the sweeper threads should be after SweepSpace
Michael Starzinger 2013/01/30 11:01:19 Let's turn this comment into a TODO().
Hannes Payer (out of office) 2013/01/30 12:07:32 Done.
3716 // old data space.
3717 StartSweeperThreads();
3718 if (FLAG_parallel_sweeping && !FLAG_concurrent_sweeping) {
3719 WaitUntilSweepingCompleted();
3720 }
3721 }
3722
3615 // ClearNonLiveTransitions depends on precise sweeping of map space to 3723 // ClearNonLiveTransitions depends on precise sweeping of map space to
3616 // detect whether unmarked map became dead in this collection or in one 3724 // detect whether unmarked map became dead in this collection or in one
3617 // of the previous ones. 3725 // of the previous ones.
3618 SweepSpace(heap()->map_space(), PRECISE); 3726 SweepSpace(heap()->map_space(), PRECISE);
3619 3727
3620 // Deallocate unmarked objects and clear marked bits for marked objects. 3728 // Deallocate unmarked objects and clear marked bits for marked objects.
3621 heap_->lo_space()->FreeUnmarkedObjects(); 3729 heap_->lo_space()->FreeUnmarkedObjects();
3622 } 3730 }
3623 3731
3624 3732
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
3812 while (buffer != NULL) { 3920 while (buffer != NULL) {
3813 SlotsBuffer* next_buffer = buffer->next(); 3921 SlotsBuffer* next_buffer = buffer->next();
3814 DeallocateBuffer(buffer); 3922 DeallocateBuffer(buffer);
3815 buffer = next_buffer; 3923 buffer = next_buffer;
3816 } 3924 }
3817 *buffer_address = NULL; 3925 *buffer_address = NULL;
3818 } 3926 }
3819 3927
3820 3928
3821 } } // namespace v8::internal 3929 } } // namespace v8::internal
OLDNEW
« src/mark-compact.h ('K') | « src/mark-compact.h ('k') | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698