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

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

Issue 7706004: Unify UpdateSlotsOnPage and SweepPrecisely. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Use enum instead of boolean to distinguish modes. 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 | no next file » | 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 2592 matching lines...) Expand 10 before | Expand all | Expand 10 after
2603 MapWord map_word = HeapObject::cast(obj)->map_word(); 2603 MapWord map_word = HeapObject::cast(obj)->map_word();
2604 if (map_word.IsForwardingAddress()) { 2604 if (map_word.IsForwardingAddress()) {
2605 *slot = map_word.ToForwardingAddress(); 2605 *slot = map_word.ToForwardingAddress();
2606 ASSERT(!MarkCompactCollector::IsOnEvacuationCandidate(*slot)); 2606 ASSERT(!MarkCompactCollector::IsOnEvacuationCandidate(*slot));
2607 } 2607 }
2608 } 2608 }
2609 } 2609 }
2610 } 2610 }
2611 2611
2612 2612
2613 static void UpdateSlotsOnPage(Page* p, ObjectVisitor* visitor) { 2613 enum SweepingMode {
2614 // TODO(gc) this is basically clone of SweepPrecisely 2614 SWEEP_ONLY,
2615 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 2615 SWEEP_AND_UPDATE_SLOTS
2616 };
2617
2618
2619 // Sweep a space precisely. After this has been done the space can
2620 // be iterated precisely, hitting only the live objects. Code space
2621 // is always swept precisely because we want to be able to iterate
2622 // over it. Map space is swept precisely, because it is not compacted.
2623 // Slots in live objects pointing into evacuation candidates are updated
2624 // if requested.
2625 static void SweepPrecisely(PagedSpace* space, Page* p, SweepingMode mode) {
2626 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
2616 MarkBit::CellType* cells = p->markbits()->cells(); 2627 MarkBit::CellType* cells = p->markbits()->cells();
2617 2628
2618 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); 2629 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
2619 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
2620 p->MarkSwept(); 2630 p->MarkSwept();
2621 2631
2622 int last_cell_index = 2632 int last_cell_index =
2623 Bitmap::IndexToCell( 2633 Bitmap::IndexToCell(
2624 Bitmap::CellAlignIndex( 2634 Bitmap::CellAlignIndex(
2625 p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); 2635 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
2626 2636
2627 int cell_index = Page::kFirstUsedCell; 2637 int cell_index = Page::kFirstUsedCell;
2628 Address free_start = p->ObjectAreaStart(); 2638 Address free_start = p->ObjectAreaStart();
2629 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 2639 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
(...skipping 10 matching lines...) Expand all
2640 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); 2650 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets);
2641 int live_index = 0; 2651 int live_index = 0;
2642 for ( ; live_objects != 0; live_objects--) { 2652 for ( ; live_objects != 0; live_objects--) {
2643 Address free_end = object_address + offsets[live_index++] * kPointerSize; 2653 Address free_end = object_address + offsets[live_index++] * kPointerSize;
2644 if (free_end != free_start) { 2654 if (free_end != free_start) {
2645 space->Free(free_start, static_cast<int>(free_end - free_start)); 2655 space->Free(free_start, static_cast<int>(free_end - free_start));
2646 } 2656 }
2647 HeapObject* live_object = HeapObject::FromAddress(free_end); 2657 HeapObject* live_object = HeapObject::FromAddress(free_end);
2648 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); 2658 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object)));
2649 int size = live_object->Size(); 2659 int size = live_object->Size();
2650 UpdateSlotsInRange(HeapObject::RawField(live_object, kPointerSize), 2660 if (mode == SWEEP_AND_UPDATE_SLOTS) {
2651 HeapObject::RawField(live_object, size)); 2661 UpdateSlotsInRange(HeapObject::RawField(live_object, kPointerSize),
2662 HeapObject::RawField(live_object, size));
2663 }
2652 free_start = free_end + size; 2664 free_start = free_end + size;
2653 } 2665 }
2654 } 2666 }
2655 if (free_start != p->ObjectAreaEnd()) { 2667 if (free_start != p->ObjectAreaEnd()) {
2656 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start)); 2668 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start));
2657 } 2669 }
2658 } 2670 }
2659 2671
2660 2672
2661 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { 2673 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2701 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); 2713 p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
2702 2714
2703 if (p->IsEvacuationCandidate()) { 2715 if (p->IsEvacuationCandidate()) {
2704 SlotsBuffer::UpdateSlotsRecordedIn(p->slots_buffer()); 2716 SlotsBuffer::UpdateSlotsRecordedIn(p->slots_buffer());
2705 if (FLAG_trace_fragmentation) { 2717 if (FLAG_trace_fragmentation) {
2706 PrintF(" page %p slots buffer: %d\n", 2718 PrintF(" page %p slots buffer: %d\n",
2707 reinterpret_cast<void*>(p), 2719 reinterpret_cast<void*>(p),
2708 SlotsBuffer::SizeOfChain(p->slots_buffer())); 2720 SlotsBuffer::SizeOfChain(p->slots_buffer()));
2709 } 2721 }
2710 } else { 2722 } else {
2711 UpdateSlotsOnPage(p, &updating_visitor); 2723 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
2724 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
2725 SweepPrecisely(space, p, SWEEP_AND_UPDATE_SLOTS);
2712 } 2726 }
2713 } 2727 }
2714 2728
2715 // Update pointers from cells. 2729 // Update pointers from cells.
2716 HeapObjectIterator cell_iterator(heap_->cell_space()); 2730 HeapObjectIterator cell_iterator(heap_->cell_space());
2717 for (HeapObject* cell = cell_iterator.Next(); 2731 for (HeapObject* cell = cell_iterator.Next();
2718 cell != NULL; 2732 cell != NULL;
2719 cell = cell_iterator.Next()) { 2733 cell = cell_iterator.Next()) {
2720 if (cell->IsJSGlobalPropertyCell()) { 2734 if (cell->IsJSGlobalPropertyCell()) {
2721 Address value_address = 2735 Address value_address =
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
3167 if (block_address - free_start > 32 * kPointerSize) { 3181 if (block_address - free_start > 32 * kPointerSize) {
3168 free_start = DigestFreeStart(free_start, free_start_cell); 3182 free_start = DigestFreeStart(free_start, free_start_cell);
3169 freed_bytes += space->Free(free_start, 3183 freed_bytes += space->Free(free_start,
3170 static_cast<int>(block_address - free_start)); 3184 static_cast<int>(block_address - free_start));
3171 } 3185 }
3172 3186
3173 return freed_bytes; 3187 return freed_bytes;
3174 } 3188 }
3175 3189
3176 3190
3177 // Sweep a space precisely. After this has been done the space can
3178 // be iterated precisely, hitting only the live objects. Code space
3179 // is always swept precisely because we want to be able to iterate
3180 // over it. Map space is swept precisely, because it is not compacted.
3181 static void SweepPrecisely(PagedSpace* space,
3182 Page* p) {
3183 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
3184 MarkBit::CellType* cells = p->markbits()->cells();
3185
3186 p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
3187
3188 int last_cell_index =
3189 Bitmap::IndexToCell(
3190 Bitmap::CellAlignIndex(
3191 p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
3192
3193 int cell_index = Page::kFirstUsedCell;
3194 Address free_start = p->ObjectAreaStart();
3195 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
3196 Address object_address = p->ObjectAreaStart();
3197 int offsets[16];
3198
3199 for (cell_index = Page::kFirstUsedCell;
3200 cell_index < last_cell_index;
3201 cell_index++, object_address += 32 * kPointerSize) {
3202 ASSERT((unsigned)cell_index ==
3203 Bitmap::IndexToCell(
3204 Bitmap::CellAlignIndex(
3205 p->AddressToMarkbitIndex(object_address))));
3206 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets);
3207 int live_index = 0;
3208 for ( ; live_objects != 0; live_objects--) {
3209 Address free_end = object_address + offsets[live_index++] * kPointerSize;
3210 if (free_end != free_start) {
3211 space->Free(free_start, static_cast<int>(free_end - free_start));
3212 }
3213 HeapObject* live_object = HeapObject::FromAddress(free_end);
3214 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object)));
3215 free_start = free_end + live_object->Size();
3216 }
3217 }
3218 if (free_start != p->ObjectAreaEnd()) {
3219 space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start));
3220 }
3221 }
3222
3223
3224 void MarkCompactCollector::SweepSpace(PagedSpace* space, 3191 void MarkCompactCollector::SweepSpace(PagedSpace* space,
3225 SweeperType sweeper) { 3192 SweeperType sweeper) {
3226 space->set_was_swept_conservatively(sweeper == CONSERVATIVE || 3193 space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
3227 sweeper == LAZY_CONSERVATIVE); 3194 sweeper == LAZY_CONSERVATIVE);
3228 3195
3229 space->ClearStats(); 3196 space->ClearStats();
3230 3197
3231 PageIterator it(space); 3198 PageIterator it(space);
3232 3199
3233 intptr_t freed_bytes = 0; 3200 intptr_t freed_bytes = 0;
(...skipping 21 matching lines...) Expand all
3255 Page* next_page = p->next_page(); 3222 Page* next_page = p->next_page();
3256 freed_bytes += SweepConservatively(space, p); 3223 freed_bytes += SweepConservatively(space, p);
3257 // TODO(gc): tweak the heuristic. 3224 // TODO(gc): tweak the heuristic.
3258 if (freed_bytes >= newspace_size && p != space->LastPage()) { 3225 if (freed_bytes >= newspace_size && p != space->LastPage()) {
3259 space->SetPagesToSweep(next_page, space->LastPage()); 3226 space->SetPagesToSweep(next_page, space->LastPage());
3260 return; 3227 return;
3261 } 3228 }
3262 break; 3229 break;
3263 } 3230 }
3264 case PRECISE: { 3231 case PRECISE: {
3265 SweepPrecisely(space, p); 3232 SweepPrecisely(space, p, SWEEP_ONLY);
3266 break; 3233 break;
3267 } 3234 }
3268 default: { 3235 default: {
3269 UNREACHABLE(); 3236 UNREACHABLE();
3270 } 3237 }
3271 } 3238 }
3272 } 3239 }
3273 3240
3274 // TODO(gc): set up allocation top and limit using the free list. 3241 // TODO(gc): set up allocation top and limit using the free list.
3275 } 3242 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
3427 while (buffer != NULL) { 3394 while (buffer != NULL) {
3428 SlotsBuffer* next_buffer = buffer->next(); 3395 SlotsBuffer* next_buffer = buffer->next();
3429 DeallocateBuffer(buffer); 3396 DeallocateBuffer(buffer);
3430 buffer = next_buffer; 3397 buffer = next_buffer;
3431 } 3398 }
3432 *buffer_address = NULL; 3399 *buffer_address = NULL;
3433 } 3400 }
3434 3401
3435 3402
3436 } } // namespace v8::internal 3403 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698