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

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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 487 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
488 MarkBit mark_bit = Marking::MarkBitFrom(obj); 488 MarkBit mark_bit = Marking::MarkBitFrom(obj);
489 mark_bit.Clear(); 489 mark_bit.Clear();
490 mark_bit.Next().Clear(); 490 mark_bit.Next().Clear();
491 Page::FromAddress(obj->address())->ResetProgressBar(); 491 Page::FromAddress(obj->address())->ResetProgressBar();
492 Page::FromAddress(obj->address())->ResetLiveBytes(); 492 Page::FromAddress(obj->address())->ResetLiveBytes();
493 } 493 }
494 } 494 }
495 495
496 496
497 void MarkCompactCollector::StartSweeperThreads(SweeperType sweeper_type) {
498 SweeperThread::set_sweeping_pending(true);
499 for (int i = 0; i < FLAG_sweeper_threads; i++) {
500 heap()->isolate()->sweeper_threads()[i]->StartSweeping(sweeper_type);
501 }
502 }
503
504
505 void MarkCompactCollector::WaitUntilSweepingCompleted() {
506 if (SweeperThread::sweeping_pending()) {
507 for (int i = 0; i < FLAG_sweeper_threads; i++) {
508 heap()->isolate()->sweeper_threads()[i]->WaitForSweeperThread();
509 }
510 SweeperThread::set_sweeping_pending(false);
511 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_DATA_SPACE));
512 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_POINTER_SPACE));
513 heap()->FreeQueuedChunks();
514 }
515 }
516
517
518 intptr_t MarkCompactCollector::
519 StealMemoryFromSweeperThreads(PagedSpace* space) {
520 intptr_t freed_bytes = 0;
521 for (int i = 0; i < FLAG_sweeper_threads; i++) {
522 freed_bytes += heap()->isolate()->sweeper_threads()[i]->StealMemory(space);
523 }
524 return freed_bytes;
525 }
526
527
528 bool MarkCompactCollector::AreSweeperThreadsActivated() {
529 return heap()->isolate()->sweeper_threads() != NULL;
530 }
531
532
497 bool Marking::TransferMark(Address old_start, Address new_start) { 533 bool Marking::TransferMark(Address old_start, Address new_start) {
498 // This is only used when resizing an object. 534 // This is only used when resizing an object.
499 ASSERT(MemoryChunk::FromAddress(old_start) == 535 ASSERT(MemoryChunk::FromAddress(old_start) ==
500 MemoryChunk::FromAddress(new_start)); 536 MemoryChunk::FromAddress(new_start));
501 537
502 // If the mark doesn't move, we don't check the color of the object. 538 // 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 539 // 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. 540 // size, so the adjustment to the live data count will be zero anyway.
505 if (old_start == new_start) return false; 541 if (old_start == new_start) return false;
506 542
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 // variable. 825 // variable.
790 tracer_ = tracer; 826 tracer_ = tracer;
791 827
792 #ifdef DEBUG 828 #ifdef DEBUG
793 ASSERT(state_ == IDLE); 829 ASSERT(state_ == IDLE);
794 state_ = PREPARE_GC; 830 state_ = PREPARE_GC;
795 #endif 831 #endif
796 832
797 ASSERT(!FLAG_never_compact || !FLAG_always_compact); 833 ASSERT(!FLAG_never_compact || !FLAG_always_compact);
798 834
835 if (AreSweeperThreadsActivated() && FLAG_concurrent_sweeping) {
Michael Starzinger 2013/01/28 16:30:18 Needs a comment that for now we wait, but it might
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
836 WaitUntilSweepingCompleted();
837 }
838
799 // Clear marking bits if incremental marking is aborted. 839 // Clear marking bits if incremental marking is aborted.
800 if (was_marked_incrementally_ && abort_incremental_marking_) { 840 if (was_marked_incrementally_ && abort_incremental_marking_) {
801 heap()->incremental_marking()->Abort(); 841 heap()->incremental_marking()->Abort();
802 ClearMarkbits(); 842 ClearMarkbits();
803 AbortCompaction(); 843 AbortCompaction();
804 was_marked_incrementally_ = false; 844 was_marked_incrementally_ = false;
805 } 845 }
806 846
807 // Don't start compaction if we are in the middle of incremental 847 // Don't start compaction if we are in the middle of incremental
808 // marking cycle. We did not collect any slots. 848 // marking cycle. We did not collect any slots.
(...skipping 1912 matching lines...) Expand 10 before | Expand all | Expand 10 after
2721 2761
2722 2762
2723 // Sweep a space precisely. After this has been done the space can 2763 // Sweep a space precisely. After this has been done the space can
2724 // be iterated precisely, hitting only the live objects. Code space 2764 // be iterated precisely, hitting only the live objects. Code space
2725 // is always swept precisely because we want to be able to iterate 2765 // is always swept precisely because we want to be able to iterate
2726 // over it. Map space is swept precisely, because it is not compacted. 2766 // over it. Map space is swept precisely, because it is not compacted.
2727 // Slots in live objects pointing into evacuation candidates are updated 2767 // Slots in live objects pointing into evacuation candidates are updated
2728 // if requested. 2768 // if requested.
2729 template<SweepingMode sweeping_mode, SkipListRebuildingMode skip_list_mode> 2769 template<SweepingMode sweeping_mode, SkipListRebuildingMode skip_list_mode>
2730 static void SweepPrecisely(PagedSpace* space, 2770 static void SweepPrecisely(PagedSpace* space,
2771 FreeList* free_list,
Michael Starzinger 2013/01/28 16:30:18 No need to pass the free-list, will not be called
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
2731 Page* p, 2772 Page* p,
2732 ObjectVisitor* v) { 2773 ObjectVisitor* v) {
2733 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 2774 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
2734 ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST, 2775 ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST,
2735 space->identity() == CODE_SPACE); 2776 space->identity() == CODE_SPACE);
2736 ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); 2777 ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST));
2737 2778
2738 MarkBit::CellType* cells = p->markbits()->cells(); 2779 MarkBit::CellType* cells = p->markbits()->cells();
2739 p->MarkSweptPrecisely(); 2780 p->MarkSweptPrecisely();
2740 2781
(...skipping 23 matching lines...) Expand all
2764 cell_index++, object_address += 32 * kPointerSize) { 2805 cell_index++, object_address += 32 * kPointerSize) {
2765 ASSERT((unsigned)cell_index == 2806 ASSERT((unsigned)cell_index ==
2766 Bitmap::IndexToCell( 2807 Bitmap::IndexToCell(
2767 Bitmap::CellAlignIndex( 2808 Bitmap::CellAlignIndex(
2768 p->AddressToMarkbitIndex(object_address)))); 2809 p->AddressToMarkbitIndex(object_address))));
2769 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); 2810 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets);
2770 int live_index = 0; 2811 int live_index = 0;
2771 for ( ; live_objects != 0; live_objects--) { 2812 for ( ; live_objects != 0; live_objects--) {
2772 Address free_end = object_address + offsets[live_index++] * kPointerSize; 2813 Address free_end = object_address + offsets[live_index++] * kPointerSize;
2773 if (free_end != free_start) { 2814 if (free_end != free_start) {
2774 space->Free(free_start, static_cast<int>(free_end - free_start)); 2815 MarkCompactCollector::Free(space, free_list, free_start,
2816 static_cast<int>(free_end - free_start));
2775 } 2817 }
2776 HeapObject* live_object = HeapObject::FromAddress(free_end); 2818 HeapObject* live_object = HeapObject::FromAddress(free_end);
2777 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 2819 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object)));
2778 Map* map = live_object->map(); 2820 Map* map = live_object->map();
2779 int size = live_object->SizeFromMap(map); 2821 int size = live_object->SizeFromMap(map);
2780 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { 2822 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) {
2781 live_object->IterateBody(map->instance_type(), size, v); 2823 live_object->IterateBody(map->instance_type(), size, v);
2782 } 2824 }
2783 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { 2825 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) {
2784 int new_region_start = 2826 int new_region_start =
2785 SkipList::RegionNumber(free_end); 2827 SkipList::RegionNumber(free_end);
2786 int new_region_end = 2828 int new_region_end =
2787 SkipList::RegionNumber(free_end + size - kPointerSize); 2829 SkipList::RegionNumber(free_end + size - kPointerSize);
2788 if (new_region_start != curr_region || 2830 if (new_region_start != curr_region ||
2789 new_region_end != curr_region) { 2831 new_region_end != curr_region) {
2790 skip_list->AddObject(free_end, size); 2832 skip_list->AddObject(free_end, size);
2791 curr_region = new_region_end; 2833 curr_region = new_region_end;
2792 } 2834 }
2793 } 2835 }
2794 free_start = free_end + size; 2836 free_start = free_end + size;
2795 } 2837 }
2796 // Clear marking bits for current cell. 2838 // Clear marking bits for current cell.
2797 cells[cell_index] = 0; 2839 cells[cell_index] = 0;
2798 } 2840 }
2799 if (free_start != p->area_end()) { 2841 if (free_start != p->area_end()) {
2800 space->Free(free_start, static_cast<int>(p->area_end() - free_start)); 2842 MarkCompactCollector::Free(space, free_list, free_start,
2843 static_cast<int>(p->area_end() - free_start));
2801 } 2844 }
2802 p->ResetLiveBytes(); 2845 p->ResetLiveBytes();
2803 } 2846 }
2804 2847
2805 2848
2806 static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) { 2849 static bool SetMarkBitsUnderInvalidatedCode(Code* code, bool value) {
2807 Page* p = Page::FromAddress(code->address()); 2850 Page* p = Page::FromAddress(code->address());
2808 2851
2809 if (p->IsEvacuationCandidate() || 2852 if (p->IsEvacuationCandidate() ||
2810 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 2853 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 } else { 3063 } else {
3021 if (FLAG_gc_verbose) { 3064 if (FLAG_gc_verbose) {
3022 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 3065 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
3023 reinterpret_cast<intptr_t>(p)); 3066 reinterpret_cast<intptr_t>(p));
3024 } 3067 }
3025 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3068 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3026 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 3069 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3027 3070
3028 switch (space->identity()) { 3071 switch (space->identity()) {
3029 case OLD_DATA_SPACE: 3072 case OLD_DATA_SPACE:
3030 SweepConservatively(space, p); 3073 SweepConservatively(space, space->free_list(), p);
Michael Starzinger 2013/01/28 16:30:18 This call-path leads to a mismatch in the accounti
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3031 break; 3074 break;
3032 case OLD_POINTER_SPACE: 3075 case OLD_POINTER_SPACE:
3033 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>( 3076 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, IGNORE_SKIP_LIST>(
3034 space, p, &updating_visitor); 3077 space, space->free_list(), p, &updating_visitor);
3035 break; 3078 break;
3036 case CODE_SPACE: 3079 case CODE_SPACE:
3037 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>( 3080 SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, REBUILD_SKIP_LIST>(
3038 space, p, &updating_visitor); 3081 space, space->free_list(), p, &updating_visitor);
3039 break; 3082 break;
3040 default: 3083 default:
3041 UNREACHABLE(); 3084 UNREACHABLE();
3042 break; 3085 break;
3043 } 3086 }
3044 } 3087 }
3045 } 3088 }
3046 } 3089 }
3047 3090
3048 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_UPDATE_MISC_POINTERS); 3091 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_UPDATE_MISC_POINTERS);
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
3376 } 3419 }
3377 uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1; 3420 uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1;
3378 ASSERT((first_set_bit & cell) == first_set_bit); 3421 ASSERT((first_set_bit & cell) == first_set_bit);
3379 int live_objects = MarkWordToObjectStarts(first_set_bit, offsets); 3422 int live_objects = MarkWordToObjectStarts(first_set_bit, offsets);
3380 ASSERT(live_objects == 1); 3423 ASSERT(live_objects == 1);
3381 USE(live_objects); 3424 USE(live_objects);
3382 return block_address + offsets[0] * kPointerSize; 3425 return block_address + offsets[0] * kPointerSize;
3383 } 3426 }
3384 3427
3385 3428
3429 intptr_t MarkCompactCollector::Free(PagedSpace* space,
Michael Starzinger 2013/01/28 16:30:18 Make this a static helper ... this should never ev
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3430 FreeList* free_list,
3431 Address start,
3432 int size) {
3433 if (space->heap()->mark_compact_collector()->AreSweeperThreadsActivated()) {
3434 intptr_t wasted = free_list->Free(start, size);
3435 return size - wasted;
3436 } else {
3437 return space->Free(start, size);
3438 }
3439 }
3440
3441
3386 // Sweeps a space conservatively. After this has been done the larger free 3442 // 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 3443 // 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 3444 // 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 3445 // 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 3446 // 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 3447 // memory that can be ignored when scanning. Dead objects other than free
3392 // spaces will not contain the free space map. 3448 // spaces will not contain the free space map.
3393 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { 3449 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
Michael Starzinger 2013/01/28 16:30:18 There are basically two different sweepers at work
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3450 FreeList* free_list,
3451 Page* p) {
3394 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3452 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
3395 MarkBit::CellType* cells = p->markbits()->cells(); 3453 MarkBit::CellType* cells = p->markbits()->cells();
3396 p->MarkSweptConservatively(); 3454 p->MarkSweptConservatively();
3397 3455
3398 int last_cell_index = 3456 int last_cell_index =
3399 Bitmap::IndexToCell( 3457 Bitmap::IndexToCell(
3400 Bitmap::CellAlignIndex( 3458 Bitmap::CellAlignIndex(
3401 p->AddressToMarkbitIndex(p->area_end()))); 3459 p->AddressToMarkbitIndex(p->area_end())));
3402 3460
3403 int cell_index = 3461 int cell_index =
3404 Bitmap::IndexToCell( 3462 Bitmap::IndexToCell(
3405 Bitmap::CellAlignIndex( 3463 Bitmap::CellAlignIndex(
3406 p->AddressToMarkbitIndex(p->area_start()))); 3464 p->AddressToMarkbitIndex(p->area_start())));
3407 3465
3408 intptr_t freed_bytes = 0; 3466 intptr_t freed_bytes = 0;
3409 3467
3410 // This is the start of the 32 word block that we are currently looking at. 3468 // This is the start of the 32 word block that we are currently looking at.
3411 Address block_address = p->area_start(); 3469 Address block_address = p->area_start();
3412 3470
3413 // Skip over all the dead objects at the start of the page and mark them free. 3471 // Skip over all the dead objects at the start of the page and mark them free.
3414 for (; 3472 for (;
3415 cell_index < last_cell_index; 3473 cell_index < last_cell_index;
3416 cell_index++, block_address += 32 * kPointerSize) { 3474 cell_index++, block_address += 32 * kPointerSize) {
3417 if (cells[cell_index] != 0) break; 3475 if (cells[cell_index] != 0) break;
3418 } 3476 }
3419 size_t size = block_address - p->area_start(); 3477 size_t size = block_address - p->area_start();
3420 if (cell_index == last_cell_index) { 3478 if (cell_index == last_cell_index) {
3421 freed_bytes += static_cast<int>(space->Free(p->area_start(), 3479 freed_bytes += Free(space, free_list, p->area_start(),
3422 static_cast<int>(size))); 3480 static_cast<int>(size));
3423 ASSERT_EQ(0, p->LiveBytes()); 3481 ASSERT_EQ(0, p->LiveBytes());
3424 return freed_bytes; 3482 return freed_bytes;
3425 } 3483 }
3426 // Grow the size of the start-of-page free space a little to get up to the 3484 // Grow the size of the start-of-page free space a little to get up to the
3427 // first live object. 3485 // first live object.
3428 Address free_end = StartOfLiveObject(block_address, cells[cell_index]); 3486 Address free_end = StartOfLiveObject(block_address, cells[cell_index]);
3429 // Free the first free space. 3487 // Free the first free space.
3430 size = free_end - p->area_start(); 3488 size = free_end - p->area_start();
3431 freed_bytes += space->Free(p->area_start(), 3489 freed_bytes += Free(space, free_list, p->area_start(),
3432 static_cast<int>(size)); 3490 static_cast<int>(size));
3433 // The start of the current free area is represented in undigested form by 3491 // 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 3492 // 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 3493 // 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 3494 // 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 3495 // 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. 3496 // first word in the marking bit map that indicates a live object.
3439 Address free_start = block_address; 3497 Address free_start = block_address;
3440 uint32_t free_start_cell = cells[cell_index]; 3498 uint32_t free_start_cell = cells[cell_index];
3441 3499
3442 for ( ; 3500 for ( ;
3443 cell_index < last_cell_index; 3501 cell_index < last_cell_index;
3444 cell_index++, block_address += 32 * kPointerSize) { 3502 cell_index++, block_address += 32 * kPointerSize) {
3445 ASSERT((unsigned)cell_index == 3503 ASSERT((unsigned)cell_index ==
3446 Bitmap::IndexToCell( 3504 Bitmap::IndexToCell(
3447 Bitmap::CellAlignIndex( 3505 Bitmap::CellAlignIndex(
3448 p->AddressToMarkbitIndex(block_address)))); 3506 p->AddressToMarkbitIndex(block_address))));
3449 uint32_t cell = cells[cell_index]; 3507 uint32_t cell = cells[cell_index];
3450 if (cell != 0) { 3508 if (cell != 0) {
3451 // We have a live object. Check approximately whether it is more than 32 3509 // We have a live object. Check approximately whether it is more than 32
3452 // words since the last live object. 3510 // words since the last live object.
3453 if (block_address - free_start > 32 * kPointerSize) { 3511 if (block_address - free_start > 32 * kPointerSize) {
3454 free_start = DigestFreeStart(free_start, free_start_cell); 3512 free_start = DigestFreeStart(free_start, free_start_cell);
3455 if (block_address - free_start > 32 * kPointerSize) { 3513 if (block_address - free_start > 32 * kPointerSize) {
3456 // Now that we know the exact start of the free space it still looks 3514 // 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. 3515 // 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 3516 // so now we need to find the start of the first live object at the
3459 // end of the free space. 3517 // end of the free space.
3460 free_end = StartOfLiveObject(block_address, cell); 3518 free_end = StartOfLiveObject(block_address, cell);
3461 freed_bytes += space->Free(free_start, 3519 freed_bytes += Free(space, free_list, free_start,
Michael Starzinger 2013/01/28 16:30:18 This looks like it will tank non-parallel sweeping
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3462 static_cast<int>(free_end - free_start)); 3520 static_cast<int>(free_end - free_start));
3463 } 3521 }
3464 } 3522 }
3465 // Update our undigested record of where the current free area started. 3523 // Update our undigested record of where the current free area started.
3466 free_start = block_address; 3524 free_start = block_address;
3467 free_start_cell = cell; 3525 free_start_cell = cell;
3468 // Clear marking bits for current cell. 3526 // Clear marking bits for current cell.
3469 cells[cell_index] = 0; 3527 cells[cell_index] = 0;
3470 } 3528 }
3471 } 3529 }
3472 3530
3473 // Handle the free space at the end of the page. 3531 // Handle the free space at the end of the page.
3474 if (block_address - free_start > 32 * kPointerSize) { 3532 if (block_address - free_start > 32 * kPointerSize) {
3475 free_start = DigestFreeStart(free_start, free_start_cell); 3533 free_start = DigestFreeStart(free_start, free_start_cell);
3476 freed_bytes += space->Free(free_start, 3534 freed_bytes += Free(space, free_list, free_start,
3477 static_cast<int>(block_address - free_start)); 3535 static_cast<int>(block_address - free_start));
3478 } 3536 }
3479 3537
3480 p->ResetLiveBytes(); 3538 p->ResetLiveBytes();
3481 return freed_bytes; 3539 return freed_bytes;
3482 } 3540 }
3483 3541
3484 3542
3543 void MarkCompactCollector::PrepareParallelSweeping(PagedSpace* space) {
Michael Starzinger 2013/01/28 16:30:18 Please merge all of this into SweepSpace() and int
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3544 bool unused_page_present = false;
3545
3546 space->set_was_swept_conservatively(true);
3547
3548 space->ClearStats();
3549
3550 PageIterator it(space);
3551 while (it.has_next()) {
3552 Page* p = it.next();
3553
3554 // Clear sweeping flags indicating that marking bits are still intact.
3555 p->ClearSweptPrecisely();
3556 p->ClearSweptConservatively();
3557 p->set_parallel_sweeping(0);
3558
3559 if (p->IsEvacuationCandidate()) {
3560 ASSERT(evacuation_candidates_.length() > 0);
3561 continue;
3562 }
3563
3564 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
3565 // Will be processed in EvacuateNewSpaceAndCandidates.
3566 continue;
3567 }
3568
3569 // One unused page is kept, all further are released before sweeping them.
3570 if (p->LiveBytes() == 0) {
3571 if (unused_page_present) {
3572 if (FLAG_gc_verbose) {
3573 PrintF("Sweeping 0x%" V8PRIxPTR " released page.\n",
3574 reinterpret_cast<intptr_t>(p));
3575 }
3576 // Adjust unswept free bytes because releasing a page expects said
3577 // counter to be accurate for unswept pages.
3578 space->IncreaseUnsweptFreeBytes(p);
3579 space->ReleasePage(p);
3580 continue;
3581 }
3582 unused_page_present = true;
3583 }
3584 }
3585 }
3586
3587
3588 void MarkCompactCollector::SweepInParallel(PagedSpace* space,
3589 SweeperType sweeper_type,
3590 FreeList* private_free_list,
3591 FreeList* free_list) {
3592 PageIterator it(space);
3593 while (it.has_next()) {
3594 Page* p = it.next();
3595
3596 if (p->IsEvacuationCandidate()) {
3597 ASSERT(evacuation_candidates_.length() > 0);
3598 continue;
Michael Starzinger 2013/01/28 16:30:18 In concurrent mode we have a race here, because th
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3599 }
3600
3601 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
3602 // Will be processed in EvacuateNewSpaceAndCandidates.
3603 continue;
3604 }
3605
3606 if (p->TryParallelSweeping()) {
3607 if (sweeper_type == CONSERVATIVE || sweeper_type == LAZY_CONSERVATIVE) {
Michael Starzinger 2013/01/28 16:30:18 This logic is no longer needed, we always sweep co
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3608 SweepConservatively(space, private_free_list, p);
3609 } else {
3610 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(
3611 space, private_free_list, p, NULL);
3612 }
3613 free_list->Concatenate(private_free_list);
3614 }
3615 }
3616 }
3617
3618
3485 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { 3619 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
3486 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 3620 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
3487 sweeper == LAZY_CONSERVATIVE); 3621 sweeper == LAZY_CONSERVATIVE);
3488 3622 ASSERT(!(space->identity() == OLD_DATA_SPACE &&
3623 FLAG_parallel_sweeping &&
3624 FLAG_concurrent_sweeping));
3625 ASSERT(!(space->identity() == OLD_POINTER_SPACE &&
3626 FLAG_parallel_sweeping &&
3627 FLAG_concurrent_sweeping));
Michael Starzinger 2013/01/28 16:30:18 These assertions are bogus, they will always be fa
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3489 space->ClearStats(); 3628 space->ClearStats();
3490 3629
3491 PageIterator it(space); 3630 PageIterator it(space);
3492 3631
3493 intptr_t freed_bytes = 0; 3632 intptr_t freed_bytes = 0;
3494 int pages_swept = 0; 3633 int pages_swept = 0;
3495 bool lazy_sweeping_active = false; 3634 bool lazy_sweeping_active = false;
3496 bool unused_page_present = false; 3635 bool unused_page_present = false;
3497 3636
3498 while (it.has_next()) { 3637 while (it.has_next()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3536 space->IncreaseUnsweptFreeBytes(p); 3675 space->IncreaseUnsweptFreeBytes(p);
3537 continue; 3676 continue;
3538 } 3677 }
3539 3678
3540 switch (sweeper) { 3679 switch (sweeper) {
3541 case CONSERVATIVE: { 3680 case CONSERVATIVE: {
3542 if (FLAG_gc_verbose) { 3681 if (FLAG_gc_verbose) {
3543 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", 3682 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
3544 reinterpret_cast<intptr_t>(p)); 3683 reinterpret_cast<intptr_t>(p));
3545 } 3684 }
3546 SweepConservatively(space, p); 3685 SweepConservatively(space, space->free_list(), p);
3547 pages_swept++; 3686 pages_swept++;
3548 break; 3687 break;
3549 } 3688 }
3550 case LAZY_CONSERVATIVE: { 3689 case LAZY_CONSERVATIVE: {
3551 if (FLAG_gc_verbose) { 3690 if (FLAG_gc_verbose) {
3552 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively as needed.\n", 3691 PrintF("Sweeping 0x%" V8PRIxPTR " conservatively as needed.\n",
3553 reinterpret_cast<intptr_t>(p)); 3692 reinterpret_cast<intptr_t>(p));
3554 } 3693 }
3555 freed_bytes += SweepConservatively(space, p); 3694 freed_bytes += SweepConservatively(space, space->free_list(), p);
3556 pages_swept++; 3695 pages_swept++;
3557 space->SetPagesToSweep(p->next_page()); 3696 space->SetPagesToSweep(p->next_page());
3558 lazy_sweeping_active = true; 3697 lazy_sweeping_active = true;
3559 break; 3698 break;
3560 } 3699 }
3561 case PRECISE: { 3700 case PRECISE: {
3562 if (FLAG_gc_verbose) { 3701 if (FLAG_gc_verbose) {
3563 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n", 3702 PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n",
3564 reinterpret_cast<intptr_t>(p)); 3703 reinterpret_cast<intptr_t>(p));
3565 } 3704 }
3566 if (space->identity() == CODE_SPACE) { 3705 if (space->identity() == CODE_SPACE) {
3567 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(space, p, NULL); 3706 SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST>(
3707 space, space->free_list(), p, NULL);
3568 } else { 3708 } else {
3569 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(space, p, NULL); 3709 SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST>(
3710 space, space->free_list(), p, NULL);
3570 } 3711 }
3571 pages_swept++; 3712 pages_swept++;
3572 break; 3713 break;
3573 } 3714 }
3574 default: { 3715 default: {
3575 UNREACHABLE(); 3716 UNREACHABLE();
3576 } 3717 }
3577 } 3718 }
3578 } 3719 }
3579 3720
(...skipping 15 matching lines...) Expand all
3595 #endif 3736 #endif
3596 SweeperType how_to_sweep = 3737 SweeperType how_to_sweep =
3597 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE; 3738 FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE;
3598 if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE; 3739 if (FLAG_expose_gc) how_to_sweep = CONSERVATIVE;
3599 if (sweep_precisely_) how_to_sweep = PRECISE; 3740 if (sweep_precisely_) how_to_sweep = PRECISE;
3600 // Noncompacting collections simply sweep the spaces to clear the mark 3741 // Noncompacting collections simply sweep the spaces to clear the mark
3601 // bits and free the nonlive blocks (for old and map spaces). We sweep 3742 // 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 3743 // 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 3744 // the other spaces rely on possibly non-live maps to get the sizes for
3604 // non-live objects. 3745 // non-live objects.
3605 SweepSpace(heap()->old_pointer_space(), how_to_sweep); 3746
3606 SweepSpace(heap()->old_data_space(), how_to_sweep); 3747 if (AreSweeperThreadsActivated()) {
3748 PrepareParallelSweeping(heap()->old_pointer_space());
Michael Starzinger 2013/01/28 16:30:18 See the comment in PrepareParallelSweeping about t
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3749 PrepareParallelSweeping(heap()->old_data_space());
3750 StartSweeperThreads(how_to_sweep);
Michael Starzinger 2013/01/28 16:30:18 Move the StartSweeperThreads to below EvacuateNewS
Hannes Payer (out of office) 2013/01/30 10:11:27 Done.
3751 if (FLAG_parallel_sweeping && !FLAG_concurrent_sweeping) {
3752 WaitUntilSweepingCompleted();
3753 }
3754 } else {
3755 SweepSpace(heap()->old_pointer_space(), how_to_sweep);
3756 SweepSpace(heap()->old_data_space(), how_to_sweep);
3757 }
3607 3758
3608 RemoveDeadInvalidatedCode(); 3759 RemoveDeadInvalidatedCode();
3609 SweepSpace(heap()->code_space(), PRECISE); 3760 SweepSpace(heap()->code_space(), PRECISE);
3610 3761
3611 SweepSpace(heap()->cell_space(), PRECISE); 3762 SweepSpace(heap()->cell_space(), PRECISE);
3612 3763
3613 EvacuateNewSpaceAndCandidates(); 3764 EvacuateNewSpaceAndCandidates();
3614 3765
3615 // ClearNonLiveTransitions depends on precise sweeping of map space to 3766 // ClearNonLiveTransitions depends on precise sweeping of map space to
3616 // detect whether unmarked map became dead in this collection or in one 3767 // detect whether unmarked map became dead in this collection or in one
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
3812 while (buffer != NULL) { 3963 while (buffer != NULL) {
3813 SlotsBuffer* next_buffer = buffer->next(); 3964 SlotsBuffer* next_buffer = buffer->next();
3814 DeallocateBuffer(buffer); 3965 DeallocateBuffer(buffer);
3815 buffer = next_buffer; 3966 buffer = next_buffer;
3816 } 3967 }
3817 *buffer_address = NULL; 3968 *buffer_address = NULL;
3818 } 3969 }
3819 3970
3820 3971
3821 } } // namespace v8::internal 3972 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698