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 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2096 } | 2096 } |
2097 } | 2097 } |
2098 | 2098 |
2099 | 2099 |
2100 // Sweep the heap for overflowed objects, clear their overflow bits, and | 2100 // Sweep the heap for overflowed objects, clear their overflow bits, and |
2101 // push them on the marking stack. Stop early if the marking stack fills | 2101 // push them on the marking stack. Stop early if the marking stack fills |
2102 // before sweeping completes. If sweeping completes, there are no remaining | 2102 // before sweeping completes. If sweeping completes, there are no remaining |
2103 // overflowed objects in the heap so the overflow flag on the markings stack | 2103 // overflowed objects in the heap so the overflow flag on the markings stack |
2104 // is cleared. | 2104 // is cleared. |
2105 void MarkCompactCollector::RefillMarkingDeque() { | 2105 void MarkCompactCollector::RefillMarkingDeque() { |
| 2106 isolate()->CountUsage(v8::Isolate::UseCounterFeature::kMarkDequeOverflow); |
2106 DCHECK(marking_deque_.overflowed()); | 2107 DCHECK(marking_deque_.overflowed()); |
2107 | 2108 |
2108 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); | 2109 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); |
2109 if (marking_deque_.IsFull()) return; | 2110 if (marking_deque_.IsFull()) return; |
2110 | 2111 |
2111 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, | 2112 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, |
2112 heap()->old_pointer_space()); | 2113 heap()->old_pointer_space()); |
2113 if (marking_deque_.IsFull()) return; | 2114 if (marking_deque_.IsFull()) return; |
2114 | 2115 |
2115 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_data_space()); | 2116 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_data_space()); |
(...skipping 2541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4657 &slots_buffer_allocator_, target_page->slots_buffer_address(), | 4658 &slots_buffer_allocator_, target_page->slots_buffer_address(), |
4658 SlotTypeForRMode(rmode), rinfo->pc(), SlotsBuffer::FAIL_ON_OVERFLOW); | 4659 SlotTypeForRMode(rmode), rinfo->pc(), SlotsBuffer::FAIL_ON_OVERFLOW); |
4659 } | 4660 } |
4660 if (!success) { | 4661 if (!success) { |
4661 EvictEvacuationCandidate(target_page); | 4662 EvictEvacuationCandidate(target_page); |
4662 } | 4663 } |
4663 } | 4664 } |
4664 } | 4665 } |
4665 | 4666 |
4666 | 4667 |
| 4668 void MarkCompactCollector::EvictEvacuationCandidate(Page* page) { |
| 4669 if (FLAG_trace_fragmentation) { |
| 4670 PrintF("Page %p is too popular. Disabling evacuation.\n", |
| 4671 reinterpret_cast<void*>(page)); |
| 4672 } |
| 4673 |
| 4674 isolate()->CountUsage(v8::Isolate::UseCounterFeature::kSlotsBufferOverflow); |
| 4675 |
| 4676 // TODO(gc) If all evacuation candidates are too popular we |
| 4677 // should stop slots recording entirely. |
| 4678 page->ClearEvacuationCandidate(); |
| 4679 |
| 4680 // We were not collecting slots on this page that point |
| 4681 // to other evacuation candidates thus we have to |
| 4682 // rescan the page after evacuation to discover and update all |
| 4683 // pointers to evacuated objects. |
| 4684 if (page->owner()->identity() == OLD_DATA_SPACE) { |
| 4685 evacuation_candidates_.RemoveElement(page); |
| 4686 } else { |
| 4687 page->SetFlag(Page::RESCAN_ON_EVACUATION); |
| 4688 } |
| 4689 } |
| 4690 |
| 4691 |
4667 void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { | 4692 void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { |
4668 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); | 4693 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
4669 if (target_page->IsEvacuationCandidate() && | 4694 if (target_page->IsEvacuationCandidate() && |
4670 !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { | 4695 !ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) { |
4671 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, | 4696 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, |
4672 target_page->slots_buffer_address(), | 4697 target_page->slots_buffer_address(), |
4673 SlotsBuffer::CODE_ENTRY_SLOT, slot, | 4698 SlotsBuffer::CODE_ENTRY_SLOT, slot, |
4674 SlotsBuffer::FAIL_ON_OVERFLOW)) { | 4699 SlotsBuffer::FAIL_ON_OVERFLOW)) { |
4675 EvictEvacuationCandidate(target_page); | 4700 EvictEvacuationCandidate(target_page); |
4676 } | 4701 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4752 SlotsBuffer* buffer = *buffer_address; | 4777 SlotsBuffer* buffer = *buffer_address; |
4753 while (buffer != NULL) { | 4778 while (buffer != NULL) { |
4754 SlotsBuffer* next_buffer = buffer->next(); | 4779 SlotsBuffer* next_buffer = buffer->next(); |
4755 DeallocateBuffer(buffer); | 4780 DeallocateBuffer(buffer); |
4756 buffer = next_buffer; | 4781 buffer = next_buffer; |
4757 } | 4782 } |
4758 *buffer_address = NULL; | 4783 *buffer_address = NULL; |
4759 } | 4784 } |
4760 } | 4785 } |
4761 } // namespace v8::internal | 4786 } // namespace v8::internal |
OLD | NEW |