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

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

Issue 7720024: Fix lazy sweeping for new marking bit clearing. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Fix lazy sweeping for new marking bit clearing. Created 9 years, 4 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 | « no previous file | 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2476 matching lines...) Expand 10 before | Expand all | Expand 10 after
2487 } 2487 }
2488 } 2488 }
2489 2489
2490 heap_->IncrementYoungSurvivorsCounter(survivors_size); 2490 heap_->IncrementYoungSurvivorsCounter(survivors_size);
2491 new_space->set_age_mark(new_space->top()); 2491 new_space->set_age_mark(new_space->top());
2492 } 2492 }
2493 2493
2494 2494
2495 void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) { 2495 void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) {
2496 AlwaysAllocateScope always_allocate; 2496 AlwaysAllocateScope always_allocate;
2497
2498 ASSERT(p->IsEvacuationCandidate() && !p->WasSwept());
2499
2500 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 2497 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
2501 2498 ASSERT(p->IsEvacuationCandidate() &&
2499 !p->WasSweptPrecisely() &&
Erik Corry 2011/08/25 09:19:48 I think it makes sense to have a bool WasSwept()
Michael Starzinger 2011/08/25 09:33:03 Done.
2500 !p->WasSweptConservatively());
2502 MarkBit::CellType* cells = p->markbits()->cells(); 2501 MarkBit::CellType* cells = p->markbits()->cells();
2502 p->MarkSweptPrecisely();
2503 2503
2504 int last_cell_index = 2504 int last_cell_index =
2505 Bitmap::IndexToCell( 2505 Bitmap::IndexToCell(
2506 Bitmap::CellAlignIndex( 2506 Bitmap::CellAlignIndex(
2507 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 2507 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
2508 2508
2509 int cell_index = Page::kFirstUsedCell; 2509 int cell_index = Page::kFirstUsedCell;
2510 Address cell_base = p->ObjectAreaStart(); 2510 Address cell_base = p->ObjectAreaStart();
2511 int offsets[16]; 2511 int offsets[16];
2512 2512
(...skipping 16 matching lines...) Expand all
2529 2529
2530 // This should never fail as we are in always allocate scope. 2530 // This should never fail as we are in always allocate scope.
2531 Object* target = space->AllocateRaw(size)->ToObjectUnchecked(); 2531 Object* target = space->AllocateRaw(size)->ToObjectUnchecked();
2532 2532
2533 MigrateObject(HeapObject::cast(target)->address(), 2533 MigrateObject(HeapObject::cast(target)->address(),
2534 object_addr, 2534 object_addr,
2535 size, 2535 size,
2536 space->identity()); 2536 space->identity());
2537 ASSERT(object->map_word().IsForwardingAddress()); 2537 ASSERT(object->map_word().IsForwardingAddress());
2538 } 2538 }
2539
2540 // Clear marking bits for current cell.
2541 cells[cell_index] = 0;
2539 } 2542 }
2540 } 2543 }
2541 2544
2542 2545
2543 void MarkCompactCollector::EvacuatePages() { 2546 void MarkCompactCollector::EvacuatePages() {
2544 int npages = evacuation_candidates_.length(); 2547 int npages = evacuation_candidates_.length();
2545 for (int i = 0; i < npages; i++) { 2548 for (int i = 0; i < npages; i++) {
2546 Page* p = evacuation_candidates_[i]; 2549 Page* p = evacuation_candidates_[i];
2547 ASSERT(p->IsEvacuationCandidate() || 2550 ASSERT(p->IsEvacuationCandidate() ||
2548 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 2551 p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2606 }; 2609 };
2607 2610
2608 2611
2609 // Sweep a space precisely. After this has been done the space can 2612 // Sweep a space precisely. After this has been done the space can
2610 // be iterated precisely, hitting only the live objects. Code space 2613 // be iterated precisely, hitting only the live objects. Code space
2611 // is always swept precisely because we want to be able to iterate 2614 // is always swept precisely because we want to be able to iterate
2612 // over it. Map space is swept precisely, because it is not compacted. 2615 // over it. Map space is swept precisely, because it is not compacted.
2613 // Slots in live objects pointing into evacuation candidates are updated 2616 // Slots in live objects pointing into evacuation candidates are updated
2614 // if requested. 2617 // if requested.
2615 static void SweepPrecisely(PagedSpace* space, Page* p, SweepingMode mode) { 2618 static void SweepPrecisely(PagedSpace* space, Page* p, SweepingMode mode) {
2616 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 2619 ASSERT(!p->IsEvacuationCandidate() &&
2617 ASSERT(!p->IsFlagSet(MemoryChunk::WAS_SWEPT_CONSERVATIVELY)); 2620 !p->WasSweptPrecisely() &&
2621 !p->WasSweptConservatively());
2618 MarkBit::CellType* cells = p->markbits()->cells(); 2622 MarkBit::CellType* cells = p->markbits()->cells();
2619 p->MarkSwept(); 2623 p->MarkSweptPrecisely();
2620 2624
2621 int last_cell_index = 2625 int last_cell_index =
2622 Bitmap::IndexToCell( 2626 Bitmap::IndexToCell(
2623 Bitmap::CellAlignIndex( 2627 Bitmap::CellAlignIndex(
2624 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 2628 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
2625 2629
2626 int cell_index = Page::kFirstUsedCell; 2630 int cell_index = Page::kFirstUsedCell;
2627 Address free_start = p->ObjectAreaStart(); 2631 Address free_start = p->ObjectAreaStart();
2628 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 2632 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
2629 Address object_address = p->ObjectAreaStart(); 2633 Address object_address = p->ObjectAreaStart();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 2708 p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
2705 2709
2706 if (p->IsEvacuationCandidate()) { 2710 if (p->IsEvacuationCandidate()) {
2707 SlotsBuffer::UpdateSlotsRecordedIn(p->slots_buffer()); 2711 SlotsBuffer::UpdateSlotsRecordedIn(p->slots_buffer());
2708 if (FLAG_trace_fragmentation) { 2712 if (FLAG_trace_fragmentation) {
2709 PrintF(" page %p slots buffer: %d\n", 2713 PrintF(" page %p slots buffer: %d\n",
2710 reinterpret_cast<void*>(p), 2714 reinterpret_cast<void*>(p),
2711 SlotsBuffer::SizeOfChain(p->slots_buffer())); 2715 SlotsBuffer::SizeOfChain(p->slots_buffer()));
2712 } 2716 }
2713 } else { 2717 } else {
2718 if (FLAG_gc_verbose) {
2719 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
2720 reinterpret_cast<intptr_t>(p));
2721 }
2714 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 2722 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
2715 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 2723 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
2716 SweepPrecisely(space, p, SWEEP_AND_UPDATE_SLOTS); 2724 SweepPrecisely(space, p, SWEEP_AND_UPDATE_SLOTS);
2717 } 2725 }
2718 } 2726 }
2719 2727
2720 // Update pointers from cells. 2728 // Update pointers from cells.
2721 HeapObjectIterator cell_iterator(heap_->cell_space()); 2729 HeapObjectIterator cell_iterator(heap_->cell_space());
2722 for (HeapObject* cell = cell_iterator.Next(); 2730 for (HeapObject* cell = cell_iterator.Next();
2723 cell != NULL; 2731 cell != NULL;
(...skipping 30 matching lines...) Expand all
2754 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); 2762 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_);
2755 ASSERT(migration_slots_buffer_ == NULL); 2763 ASSERT(migration_slots_buffer_ == NULL);
2756 for (int i = 0; i < npages; i++) { 2764 for (int i = 0; i < npages; i++) {
2757 Page* p = evacuation_candidates_[i]; 2765 Page* p = evacuation_candidates_[i];
2758 if (!p->IsEvacuationCandidate()) continue; 2766 if (!p->IsEvacuationCandidate()) continue;
2759 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 2767 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
2760 space->Free(p->ObjectAreaStart(), Page::kObjectAreaSize); 2768 space->Free(p->ObjectAreaStart(), Page::kObjectAreaSize);
2761 p->set_scan_on_scavenge(false); 2769 p->set_scan_on_scavenge(false);
2762 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); 2770 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address());
2763 p->ClearEvacuationCandidate(); 2771 p->ClearEvacuationCandidate();
2764 p->MarkSwept();
2765 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
2766 } 2772 }
2767 evacuation_candidates_.Rewind(0); 2773 evacuation_candidates_.Rewind(0);
2768 compacting_ = false; 2774 compacting_ = false;
2769 } 2775 }
2770 2776
2771 2777
2772 INLINE(static uint32_t SweepFree(PagedSpace* space, 2778 INLINE(static uint32_t SweepFree(PagedSpace* space,
2773 Page* p, 2779 Page* p,
2774 uint32_t free_start, 2780 uint32_t free_start,
2775 uint32_t region_end, 2781 uint32_t region_end,
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
3086 3092
3087 3093
3088 // Sweeps a space conservatively. After this has been done the larger free 3094 // Sweeps a space conservatively. After this has been done the larger free
3089 // spaces have been put on the free list and the smaller ones have been 3095 // spaces have been put on the free list and the smaller ones have been
3090 // ignored and left untouched. A free space is always either ignored or put 3096 // ignored and left untouched. A free space is always either ignored or put
3091 // on the free list, never split up into two parts. This is important 3097 // on the free list, never split up into two parts. This is important
3092 // because it means that any FreeSpace maps left actually describe a region of 3098 // because it means that any FreeSpace maps left actually describe a region of
3093 // memory that can be ignored when scanning. Dead objects other than free 3099 // memory that can be ignored when scanning. Dead objects other than free
3094 // spaces will not contain the free space map. 3100 // spaces will not contain the free space map.
3095 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { 3101 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) {
3096 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3102 ASSERT(!p->IsEvacuationCandidate() &&
3103 !p->WasSweptPrecisely() &&
3104 !p->WasSweptConservatively());
3097 MarkBit::CellType* cells = p->markbits()->cells(); 3105 MarkBit::CellType* cells = p->markbits()->cells();
3098 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); 3106 p->MarkSweptConservatively();
3099 3107
3100 int last_cell_index = 3108 int last_cell_index =
3101 Bitmap::IndexToCell( 3109 Bitmap::IndexToCell(
3102 Bitmap::CellAlignIndex( 3110 Bitmap::CellAlignIndex(
3103 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 3111 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
3104 3112
3105 int cell_index = Page::kFirstUsedCell; 3113 int cell_index = Page::kFirstUsedCell;
3106 intptr_t freed_bytes = 0; 3114 intptr_t freed_bytes = 0;
3107 3115
3108 // This is the start of the 32 word block that we are currently looking at. 3116 // This is the start of the 32 word block that we are currently looking at.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3182 SweeperType sweeper) { 3190 SweeperType sweeper) {
3183 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 3191 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
3184 sweeper == LAZY_CONSERVATIVE); 3192 sweeper == LAZY_CONSERVATIVE);
3185 3193
3186 space->ClearStats(); 3194 space->ClearStats();
3187 3195
3188 PageIterator it(space); 3196 PageIterator it(space);
3189 3197
3190 intptr_t freed_bytes = 0; 3198 intptr_t freed_bytes = 0;
3191 intptr_t newspace_size = space->heap()->new_space()->Size(); 3199 intptr_t newspace_size = space->heap()->new_space()->Size();
3200 bool lazy_sweeping_active = false;
3192 3201
3193 while (it.has_next()) { 3202 while (it.has_next()) {
3194 Page* p = it.next(); 3203 Page* p = it.next();
3195 3204
3205 // Clear sweeping flags indicating that marking bits are still intact.
3206 p->ClearSweptPrecisely();
3207 p->ClearSweptConservatively();
3208
3196 if (p->IsEvacuationCandidate()) { 3209 if (p->IsEvacuationCandidate()) {
3197 ASSERT(evacuation_candidates_.length() > 0); 3210 ASSERT(evacuation_candidates_.length() > 0);
3198 continue; 3211 continue;
3199 } 3212 }
3200 3213
3201 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 3214 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
3202 // Will be processed in EvacuateNewSpaceAndCandidates. 3215 // Will be processed in EvacuateNewSpaceAndCandidates.
3203 continue; 3216 continue;
3204 } 3217 }
3205 3218
3219 if (lazy_sweeping_active) {
3220 if (FLAG_gc_verbose) {
3221 PrintF("Sweeping 0x%" V8PRIxPTR " lazily postponed.\n",
3222 reinterpret_cast<intptr_t>(p));
3223 }
3224 continue;
3225 }
3226
3227 if (FLAG_gc_verbose) {
3228 PrintF("Sweeping 0x%" V8PRIxPTR " with sweeper %d.\n",
3229 reinterpret_cast<intptr_t>(p),
3230 sweeper);
3231 }
3232
3206 switch (sweeper) { 3233 switch (sweeper) {
3207 case CONSERVATIVE: { 3234 case CONSERVATIVE: {
3208 SweepConservatively(space, p); 3235 SweepConservatively(space, p);
3209 break; 3236 break;
3210 } 3237 }
3211 case LAZY_CONSERVATIVE: { 3238 case LAZY_CONSERVATIVE: {
3212 Page* next_page = p->next_page();
3213 freed_bytes += SweepConservatively(space, p); 3239 freed_bytes += SweepConservatively(space, p);
3214 if (freed_bytes >= newspace_size && p != space->LastPage()) { 3240 if (freed_bytes >= newspace_size && p != space->LastPage()) {
3215 space->SetPagesToSweep(next_page, space->LastPage()); 3241 space->SetPagesToSweep(p->next_page(), space->LastPage());
3216 return; 3242 lazy_sweeping_active = true;
3217 } 3243 }
3218 break; 3244 break;
3219 } 3245 }
3220 case PRECISE: { 3246 case PRECISE: {
3221 SweepPrecisely(space, p, SWEEP_ONLY); 3247 SweepPrecisely(space, p, SWEEP_ONLY);
3222 break; 3248 break;
3223 } 3249 }
3224 default: { 3250 default: {
3225 UNREACHABLE(); 3251 UNREACHABLE();
3226 } 3252 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3316 while (buffer != NULL) { 3342 while (buffer != NULL) {
3317 SlotsBuffer* next_buffer = buffer->next(); 3343 SlotsBuffer* next_buffer = buffer->next();
3318 DeallocateBuffer(buffer); 3344 DeallocateBuffer(buffer);
3319 buffer = next_buffer; 3345 buffer = next_buffer;
3320 } 3346 }
3321 *buffer_address = NULL; 3347 *buffer_address = NULL;
3322 } 3348 }
3323 3349
3324 3350
3325 } } // namespace v8::internal 3351 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698