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

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: Addressed review by Erik Corry. 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 2497 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
2498 ASSERT(p->IsEvacuationCandidate() && !p->WasSwept()); 2498 ASSERT(p->IsEvacuationCandidate() && !p->WasSwept());
2499
2500 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
2501
2502 MarkBit::CellType* cells = p->markbits()->cells(); 2499 MarkBit::CellType* cells = p->markbits()->cells();
2500 p->MarkSweptPrecisely();
2503 2501
2504 int last_cell_index = 2502 int last_cell_index =
2505 Bitmap::IndexToCell( 2503 Bitmap::IndexToCell(
2506 Bitmap::CellAlignIndex( 2504 Bitmap::CellAlignIndex(
2507 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 2505 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
2508 2506
2509 int cell_index = Page::kFirstUsedCell; 2507 int cell_index = Page::kFirstUsedCell;
2510 Address cell_base = p->ObjectAreaStart(); 2508 Address cell_base = p->ObjectAreaStart();
2511 int offsets[16]; 2509 int offsets[16];
2512 2510
(...skipping 16 matching lines...) Expand all
2529 2527
2530 // This should never fail as we are in always allocate scope. 2528 // This should never fail as we are in always allocate scope.
2531 Object* target = space->AllocateRaw(size)->ToObjectUnchecked(); 2529 Object* target = space->AllocateRaw(size)->ToObjectUnchecked();
2532 2530
2533 MigrateObject(HeapObject::cast(target)->address(), 2531 MigrateObject(HeapObject::cast(target)->address(),
2534 object_addr, 2532 object_addr,
2535 size, 2533 size,
2536 space->identity()); 2534 space->identity());
2537 ASSERT(object->map_word().IsForwardingAddress()); 2535 ASSERT(object->map_word().IsForwardingAddress());
2538 } 2536 }
2537
2538 // Clear marking bits for current cell.
2539 cells[cell_index] = 0;
2539 } 2540 }
2540 } 2541 }
2541 2542
2542 2543
2543 void MarkCompactCollector::EvacuatePages() { 2544 void MarkCompactCollector::EvacuatePages() {
2544 int npages = evacuation_candidates_.length(); 2545 int npages = evacuation_candidates_.length();
2545 for (int i = 0; i < npages; i++) { 2546 for (int i = 0; i < npages; i++) {
2546 Page* p = evacuation_candidates_[i]; 2547 Page* p = evacuation_candidates_[i];
2547 ASSERT(p->IsEvacuationCandidate() || 2548 ASSERT(p->IsEvacuationCandidate() ||
2548 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 2549 p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 2608
2608 2609
2609 // Sweep a space precisely. After this has been done the space can 2610 // Sweep a space precisely. After this has been done the space can
2610 // be iterated precisely, hitting only the live objects. Code space 2611 // be iterated precisely, hitting only the live objects. Code space
2611 // is always swept precisely because we want to be able to iterate 2612 // 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. 2613 // over it. Map space is swept precisely, because it is not compacted.
2613 // Slots in live objects pointing into evacuation candidates are updated 2614 // Slots in live objects pointing into evacuation candidates are updated
2614 // if requested. 2615 // if requested.
2615 static void SweepPrecisely(PagedSpace* space, Page* p, SweepingMode mode) { 2616 static void SweepPrecisely(PagedSpace* space, Page* p, SweepingMode mode) {
2616 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 2617 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
2617 ASSERT(!p->IsFlagSet(MemoryChunk::WAS_SWEPT_CONSERVATIVELY));
2618 MarkBit::CellType* cells = p->markbits()->cells(); 2618 MarkBit::CellType* cells = p->markbits()->cells();
2619 p->MarkSwept(); 2619 p->MarkSweptPrecisely();
2620 2620
2621 int last_cell_index = 2621 int last_cell_index =
2622 Bitmap::IndexToCell( 2622 Bitmap::IndexToCell(
2623 Bitmap::CellAlignIndex( 2623 Bitmap::CellAlignIndex(
2624 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 2624 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
2625 2625
2626 int cell_index = Page::kFirstUsedCell; 2626 int cell_index = Page::kFirstUsedCell;
2627 Address free_start = p->ObjectAreaStart(); 2627 Address free_start = p->ObjectAreaStart();
2628 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 2628 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
2629 Address object_address = p->ObjectAreaStart(); 2629 Address object_address = p->ObjectAreaStart();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 2704 p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
2705 2705
2706 if (p->IsEvacuationCandidate()) { 2706 if (p->IsEvacuationCandidate()) {
2707 SlotsBuffer::UpdateSlotsRecordedIn(p->slots_buffer()); 2707 SlotsBuffer::UpdateSlotsRecordedIn(p->slots_buffer());
2708 if (FLAG_trace_fragmentation) { 2708 if (FLAG_trace_fragmentation) {
2709 PrintF(" page %p slots buffer: %d\n", 2709 PrintF(" page %p slots buffer: %d\n",
2710 reinterpret_cast<void*>(p), 2710 reinterpret_cast<void*>(p),
2711 SlotsBuffer::SizeOfChain(p->slots_buffer())); 2711 SlotsBuffer::SizeOfChain(p->slots_buffer()));
2712 } 2712 }
2713 } else { 2713 } else {
2714 if (FLAG_gc_verbose) {
2715 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
2716 reinterpret_cast<intptr_t>(p));
2717 }
2714 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 2718 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
2715 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 2719 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
2716 SweepPrecisely(space, p, SWEEP_AND_UPDATE_SLOTS); 2720 SweepPrecisely(space, p, SWEEP_AND_UPDATE_SLOTS);
2717 } 2721 }
2718 } 2722 }
2719 2723
2720 // Update pointers from cells. 2724 // Update pointers from cells.
2721 HeapObjectIterator cell_iterator(heap_->cell_space()); 2725 HeapObjectIterator cell_iterator(heap_->cell_space());
2722 for (HeapObject* cell = cell_iterator.Next(); 2726 for (HeapObject* cell = cell_iterator.Next();
2723 cell != NULL; 2727 cell != NULL;
(...skipping 30 matching lines...) Expand all
2754 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); 2758 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_);
2755 ASSERT(migration_slots_buffer_ == NULL); 2759 ASSERT(migration_slots_buffer_ == NULL);
2756 for (int i = 0; i < npages; i++) { 2760 for (int i = 0; i < npages; i++) {
2757 Page* p = evacuation_candidates_[i]; 2761 Page* p = evacuation_candidates_[i];
2758 if (!p->IsEvacuationCandidate()) continue; 2762 if (!p->IsEvacuationCandidate()) continue;
2759 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 2763 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
2760 space->Free(p->ObjectAreaStart(), Page::kObjectAreaSize); 2764 space->Free(p->ObjectAreaStart(), Page::kObjectAreaSize);
2761 p->set_scan_on_scavenge(false); 2765 p->set_scan_on_scavenge(false);
2762 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); 2766 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address());
2763 p->ClearEvacuationCandidate(); 2767 p->ClearEvacuationCandidate();
2764 p->MarkSwept();
2765 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
2766 } 2768 }
2767 evacuation_candidates_.Rewind(0); 2769 evacuation_candidates_.Rewind(0);
2768 compacting_ = false; 2770 compacting_ = false;
2769 } 2771 }
2770 2772
2771 2773
2772 INLINE(static uint32_t SweepFree(PagedSpace* space, 2774 INLINE(static uint32_t SweepFree(PagedSpace* space,
2773 Page* p, 2775 Page* p,
2774 uint32_t free_start, 2776 uint32_t free_start,
2775 uint32_t region_end, 2777 uint32_t region_end,
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
3088 // Sweeps a space conservatively. After this has been done the larger free 3090 // 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 3091 // 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 3092 // 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 3093 // 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 3094 // 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 3095 // memory that can be ignored when scanning. Dead objects other than free
3094 // spaces will not contain the free space map. 3096 // spaces will not contain the free space map.
3095 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) { 3097 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) {
3096 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); 3098 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
3097 MarkBit::CellType* cells = p->markbits()->cells(); 3099 MarkBit::CellType* cells = p->markbits()->cells();
3098 p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); 3100 p->MarkSweptConservatively();
3099 3101
3100 int last_cell_index = 3102 int last_cell_index =
3101 Bitmap::IndexToCell( 3103 Bitmap::IndexToCell(
3102 Bitmap::CellAlignIndex( 3104 Bitmap::CellAlignIndex(
3103 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 3105 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
3104 3106
3105 int cell_index = Page::kFirstUsedCell; 3107 int cell_index = Page::kFirstUsedCell;
3106 intptr_t freed_bytes = 0; 3108 intptr_t freed_bytes = 0;
3107 3109
3108 // This is the start of the 32 word block that we are currently looking at. 3110 // 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) { 3184 SweeperType sweeper) {
3183 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 3185 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
3184 sweeper == LAZY_CONSERVATIVE); 3186 sweeper == LAZY_CONSERVATIVE);
3185 3187
3186 space->ClearStats(); 3188 space->ClearStats();
3187 3189
3188 PageIterator it(space); 3190 PageIterator it(space);
3189 3191
3190 intptr_t freed_bytes = 0; 3192 intptr_t freed_bytes = 0;
3191 intptr_t newspace_size = space->heap()->new_space()->Size(); 3193 intptr_t newspace_size = space->heap()->new_space()->Size();
3194 bool lazy_sweeping_active = false;
3192 3195
3193 while (it.has_next()) { 3196 while (it.has_next()) {
3194 Page* p = it.next(); 3197 Page* p = it.next();
3195 3198
3199 // Clear sweeping flags indicating that marking bits are still intact.
3200 p->ClearSweptPrecisely();
3201 p->ClearSweptConservatively();
3202
3196 if (p->IsEvacuationCandidate()) { 3203 if (p->IsEvacuationCandidate()) {
3197 ASSERT(evacuation_candidates_.length() > 0); 3204 ASSERT(evacuation_candidates_.length() > 0);
3198 continue; 3205 continue;
3199 } 3206 }
3200 3207
3201 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { 3208 if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
3202 // Will be processed in EvacuateNewSpaceAndCandidates. 3209 // Will be processed in EvacuateNewSpaceAndCandidates.
3203 continue; 3210 continue;
3204 } 3211 }
3205 3212
3213 if (lazy_sweeping_active) {
3214 if (FLAG_gc_verbose) {
3215 PrintF("Sweeping 0x%" V8PRIxPTR " lazily postponed.\n",
3216 reinterpret_cast<intptr_t>(p));
3217 }
3218 continue;
3219 }
3220
3221 if (FLAG_gc_verbose) {
3222 PrintF("Sweeping 0x%" V8PRIxPTR " with sweeper %d.\n",
3223 reinterpret_cast<intptr_t>(p),
3224 sweeper);
3225 }
3226
3206 switch (sweeper) { 3227 switch (sweeper) {
3207 case CONSERVATIVE: { 3228 case CONSERVATIVE: {
3208 SweepConservatively(space, p); 3229 SweepConservatively(space, p);
3209 break; 3230 break;
3210 } 3231 }
3211 case LAZY_CONSERVATIVE: { 3232 case LAZY_CONSERVATIVE: {
3212 Page* next_page = p->next_page();
3213 freed_bytes += SweepConservatively(space, p); 3233 freed_bytes += SweepConservatively(space, p);
3214 if (freed_bytes >= newspace_size && p != space->LastPage()) { 3234 if (freed_bytes >= newspace_size && p != space->LastPage()) {
3215 space->SetPagesToSweep(next_page, space->LastPage()); 3235 space->SetPagesToSweep(p->next_page(), space->LastPage());
3216 return; 3236 lazy_sweeping_active = true;
3217 } 3237 }
3218 break; 3238 break;
3219 } 3239 }
3220 case PRECISE: { 3240 case PRECISE: {
3221 SweepPrecisely(space, p, SWEEP_ONLY); 3241 SweepPrecisely(space, p, SWEEP_ONLY);
3222 break; 3242 break;
3223 } 3243 }
3224 default: { 3244 default: {
3225 UNREACHABLE(); 3245 UNREACHABLE();
3226 } 3246 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3316 while (buffer != NULL) { 3336 while (buffer != NULL) {
3317 SlotsBuffer* next_buffer = buffer->next(); 3337 SlotsBuffer* next_buffer = buffer->next();
3318 DeallocateBuffer(buffer); 3338 DeallocateBuffer(buffer);
3319 buffer = next_buffer; 3339 buffer = next_buffer;
3320 } 3340 }
3321 *buffer_address = NULL; 3341 *buffer_address = NULL;
3322 } 3342 }
3323 3343
3324 3344
3325 } } // namespace v8::internal 3345 } } // 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