OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 void MarkCompactCollector::CollectGarbage() { | 291 void MarkCompactCollector::CollectGarbage() { |
292 // Make sure that Prepare() has been called. The individual steps below will | 292 // Make sure that Prepare() has been called. The individual steps below will |
293 // update the state as they proceed. | 293 // update the state as they proceed. |
294 DCHECK(state_ == PREPARE_GC); | 294 DCHECK(state_ == PREPARE_GC); |
295 | 295 |
296 MarkLiveObjects(); | 296 MarkLiveObjects(); |
297 DCHECK(heap_->incremental_marking()->IsStopped()); | 297 DCHECK(heap_->incremental_marking()->IsStopped()); |
298 | 298 |
299 if (FLAG_collect_maps) ClearNonLiveReferences(); | 299 if (FLAG_collect_maps) ClearNonLiveReferences(); |
300 | 300 |
| 301 ProcessAndClearWeakCells(); |
| 302 |
301 ClearWeakCollections(); | 303 ClearWeakCollections(); |
302 | 304 |
| 305 heap_->set_encountered_weak_cells(Smi::FromInt(0)); |
| 306 |
303 #ifdef VERIFY_HEAP | 307 #ifdef VERIFY_HEAP |
304 if (FLAG_verify_heap) { | 308 if (FLAG_verify_heap) { |
305 VerifyMarking(heap_); | 309 VerifyMarking(heap_); |
306 } | 310 } |
307 #endif | 311 #endif |
308 | 312 |
309 SweepSpaces(); | 313 SweepSpaces(); |
310 | 314 |
311 #ifdef VERIFY_HEAP | 315 #ifdef VERIFY_HEAP |
312 if (heap()->weak_embedded_objects_verification_enabled()) { | 316 if (heap()->weak_embedded_objects_verification_enabled()) { |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 if (sweeping_in_progress()) { | 819 if (sweeping_in_progress()) { |
816 // Instead of waiting we could also abort the sweeper threads here. | 820 // Instead of waiting we could also abort the sweeper threads here. |
817 EnsureSweepingCompleted(); | 821 EnsureSweepingCompleted(); |
818 } | 822 } |
819 | 823 |
820 // Clear marking bits if incremental marking is aborted. | 824 // Clear marking bits if incremental marking is aborted. |
821 if (was_marked_incrementally_ && abort_incremental_marking_) { | 825 if (was_marked_incrementally_ && abort_incremental_marking_) { |
822 heap()->incremental_marking()->Abort(); | 826 heap()->incremental_marking()->Abort(); |
823 ClearMarkbits(); | 827 ClearMarkbits(); |
824 AbortWeakCollections(); | 828 AbortWeakCollections(); |
| 829 AbortWeakCells(); |
825 AbortCompaction(); | 830 AbortCompaction(); |
826 was_marked_incrementally_ = false; | 831 was_marked_incrementally_ = false; |
827 } | 832 } |
828 | 833 |
829 // Don't start compaction if we are in the middle of incremental | 834 // Don't start compaction if we are in the middle of incremental |
830 // marking cycle. We did not collect any slots. | 835 // marking cycle. We did not collect any slots. |
831 if (!FLAG_never_compact && !was_marked_incrementally_) { | 836 if (!FLAG_never_compact && !was_marked_incrementally_) { |
832 StartCompaction(NON_INCREMENTAL_COMPACTION); | 837 StartCompaction(NON_INCREMENTAL_COMPACTION); |
833 } | 838 } |
834 | 839 |
(...skipping 1892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2727 while (weak_collection_obj != Smi::FromInt(0)) { | 2732 while (weak_collection_obj != Smi::FromInt(0)) { |
2728 JSWeakCollection* weak_collection = | 2733 JSWeakCollection* weak_collection = |
2729 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); | 2734 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); |
2730 weak_collection_obj = weak_collection->next(); | 2735 weak_collection_obj = weak_collection->next(); |
2731 weak_collection->set_next(heap()->undefined_value()); | 2736 weak_collection->set_next(heap()->undefined_value()); |
2732 } | 2737 } |
2733 heap()->set_encountered_weak_collections(Smi::FromInt(0)); | 2738 heap()->set_encountered_weak_collections(Smi::FromInt(0)); |
2734 } | 2739 } |
2735 | 2740 |
2736 | 2741 |
| 2742 void MarkCompactCollector::ProcessAndClearWeakCells() { |
| 2743 HeapObject* undefined = heap()->undefined_value(); |
| 2744 Object* weak_cell_obj = heap()->encountered_weak_cells(); |
| 2745 while (weak_cell_obj != Smi::FromInt(0)) { |
| 2746 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); |
| 2747 HeapObject* value = weak_cell->value(); |
| 2748 if (!MarkCompactCollector::IsMarked(value)) { |
| 2749 weak_cell->clear(undefined); |
| 2750 } else { |
| 2751 Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); |
| 2752 heap()->mark_compact_collector()->RecordSlot(slot, slot, value); |
| 2753 } |
| 2754 weak_cell_obj = weak_cell->next(); |
| 2755 weak_cell->set_next(undefined, SKIP_WRITE_BARRIER); |
| 2756 } |
| 2757 heap()->set_encountered_weak_cells(Smi::FromInt(0)); |
| 2758 } |
| 2759 |
| 2760 |
| 2761 void MarkCompactCollector::AbortWeakCells() { |
| 2762 Object* undefined = heap()->undefined_value(); |
| 2763 Object* weak_cell_obj = heap()->encountered_weak_cells(); |
| 2764 while (weak_cell_obj != Smi::FromInt(0)) { |
| 2765 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); |
| 2766 weak_cell_obj = weak_cell->next(); |
| 2767 weak_cell->set_next(undefined, SKIP_WRITE_BARRIER); |
| 2768 } |
| 2769 heap()->set_encountered_weak_cells(Smi::FromInt(0)); |
| 2770 } |
| 2771 |
| 2772 |
2737 void MarkCompactCollector::RecordMigratedSlot(Object* value, Address slot) { | 2773 void MarkCompactCollector::RecordMigratedSlot(Object* value, Address slot) { |
2738 if (heap_->InNewSpace(value)) { | 2774 if (heap_->InNewSpace(value)) { |
2739 heap_->store_buffer()->Mark(slot); | 2775 heap_->store_buffer()->Mark(slot); |
2740 } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { | 2776 } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { |
2741 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, | 2777 SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, |
2742 reinterpret_cast<Object**>(slot), | 2778 reinterpret_cast<Object**>(slot), |
2743 SlotsBuffer::IGNORE_OVERFLOW); | 2779 SlotsBuffer::IGNORE_OVERFLOW); |
2744 } | 2780 } |
2745 } | 2781 } |
2746 | 2782 |
2747 | 2783 |
2748 // We scavange new space simultaneously with sweeping. This is done in two | 2784 // We scavenge new space simultaneously with sweeping. This is done in two |
2749 // passes. | 2785 // passes. |
2750 // | 2786 // |
2751 // The first pass migrates all alive objects from one semispace to another or | 2787 // The first pass migrates all alive objects from one semispace to another or |
2752 // promotes them to old space. Forwarding address is written directly into | 2788 // promotes them to old space. Forwarding address is written directly into |
2753 // first word of object without any encoding. If object is dead we write | 2789 // first word of object without any encoding. If object is dead we write |
2754 // NULL as a forwarding address. | 2790 // NULL as a forwarding address. |
2755 // | 2791 // |
2756 // The second pass updates pointers to new space in all spaces. It is possible | 2792 // The second pass updates pointers to new space in all spaces. It is possible |
2757 // to encounter pointers to dead new space objects during traversal of pointers | 2793 // to encounter pointers to dead new space objects during traversal of pointers |
2758 // to new space. We should clear them to avoid encountering them during next | 2794 // to new space. We should clear them to avoid encountering them during next |
(...skipping 1650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4409 SlotsBuffer* buffer = *buffer_address; | 4445 SlotsBuffer* buffer = *buffer_address; |
4410 while (buffer != NULL) { | 4446 while (buffer != NULL) { |
4411 SlotsBuffer* next_buffer = buffer->next(); | 4447 SlotsBuffer* next_buffer = buffer->next(); |
4412 DeallocateBuffer(buffer); | 4448 DeallocateBuffer(buffer); |
4413 buffer = next_buffer; | 4449 buffer = next_buffer; |
4414 } | 4450 } |
4415 *buffer_address = NULL; | 4451 *buffer_address = NULL; |
4416 } | 4452 } |
4417 } | 4453 } |
4418 } // namespace v8::internal | 4454 } // namespace v8::internal |
OLD | NEW |