| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |