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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 while (it.has_next()) { | 286 while (it.has_next()) { |
287 Page* p = it.next(); | 287 Page* p = it.next(); |
288 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); | 288 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); |
289 } | 289 } |
290 } | 290 } |
291 | 291 |
292 | 292 |
293 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { | 293 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { |
294 heap_->store_buffer()->ClearInvalidStoreBufferEntries(); | 294 heap_->store_buffer()->ClearInvalidStoreBufferEntries(); |
295 | 295 |
296 RemoveDeoptimizedCodeSlots(); | |
297 | |
298 ClearInvalidSlotsBufferEntries(heap_->old_space()); | 296 ClearInvalidSlotsBufferEntries(heap_->old_space()); |
299 ClearInvalidSlotsBufferEntries(heap_->code_space()); | 297 ClearInvalidSlotsBufferEntries(heap_->code_space()); |
300 ClearInvalidSlotsBufferEntries(heap_->map_space()); | 298 ClearInvalidSlotsBufferEntries(heap_->map_space()); |
301 | 299 |
302 LargeObjectIterator it(heap_->lo_space()); | 300 LargeObjectIterator it(heap_->lo_space()); |
303 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 301 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
304 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); | 302 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
305 SlotsBuffer::RemoveInvalidSlots(heap_, chunk->slots_buffer()); | 303 SlotsBuffer::RemoveInvalidSlots(heap_, chunk->slots_buffer()); |
306 } | 304 } |
307 } | 305 } |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
762 if (compacting_) { | 760 if (compacting_) { |
763 int npages = evacuation_candidates_.length(); | 761 int npages = evacuation_candidates_.length(); |
764 for (int i = 0; i < npages; i++) { | 762 for (int i = 0; i < npages; i++) { |
765 Page* p = evacuation_candidates_[i]; | 763 Page* p = evacuation_candidates_[i]; |
766 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); | 764 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); |
767 p->ClearEvacuationCandidate(); | 765 p->ClearEvacuationCandidate(); |
768 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); | 766 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); |
769 } | 767 } |
770 compacting_ = false; | 768 compacting_ = false; |
771 evacuation_candidates_.Rewind(0); | 769 evacuation_candidates_.Rewind(0); |
772 invalidated_code_.Rewind(0); | |
773 } | 770 } |
774 DCHECK_EQ(0, evacuation_candidates_.length()); | 771 DCHECK_EQ(0, evacuation_candidates_.length()); |
775 } | 772 } |
776 | 773 |
777 | 774 |
778 void MarkCompactCollector::Prepare() { | 775 void MarkCompactCollector::Prepare() { |
779 was_marked_incrementally_ = heap()->incremental_marking()->IsMarking(); | 776 was_marked_incrementally_ = heap()->incremental_marking()->IsMarking(); |
780 | 777 |
781 #ifdef DEBUG | 778 #ifdef DEBUG |
782 DCHECK(state_ == IDLE); | 779 DCHECK(state_ == IDLE); |
(...skipping 2803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3586 | 3583 |
3587 void MarkCompactCollector::InvalidateCode(Code* code) { | 3584 void MarkCompactCollector::InvalidateCode(Code* code) { |
3588 if (heap_->incremental_marking()->IsCompacting() && | 3585 if (heap_->incremental_marking()->IsCompacting() && |
3589 !ShouldSkipEvacuationSlotRecording(code)) { | 3586 !ShouldSkipEvacuationSlotRecording(code)) { |
3590 DCHECK(compacting_); | 3587 DCHECK(compacting_); |
3591 | 3588 |
3592 // If the object is white than no slots were recorded on it yet. | 3589 // If the object is white than no slots were recorded on it yet. |
3593 MarkBit mark_bit = Marking::MarkBitFrom(code); | 3590 MarkBit mark_bit = Marking::MarkBitFrom(code); |
3594 if (Marking::IsWhite(mark_bit)) return; | 3591 if (Marking::IsWhite(mark_bit)) return; |
3595 | 3592 |
3596 invalidated_code_.Add(code); | 3593 // Ignore all slots that might have been recorded in the body of the |
3594 // deoptimized code object. Assumption: no slots will be recorded for | |
3595 // this object after invalidating it. | |
3596 RemoveObjectSlots(code->instruction_start(), | |
3597 code->address() + code->Size()); | |
3597 } | 3598 } |
3598 } | 3599 } |
3599 | 3600 |
3600 | 3601 |
3601 // Return true if the given code is deoptimized or will be deoptimized. | 3602 // Return true if the given code is deoptimized or will be deoptimized. |
3602 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { | 3603 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { |
3603 return code->is_optimized_code() && code->marked_for_deoptimization(); | 3604 return code->is_optimized_code() && code->marked_for_deoptimization(); |
3604 } | 3605 } |
3605 | 3606 |
3606 | 3607 |
3607 void MarkCompactCollector::RemoveDeoptimizedCodeSlots() { | |
3608 int length = invalidated_code_.length(); | |
3609 for (int i = 0; i < length; i++) { | |
3610 Code* code = invalidated_code_[i]; | |
3611 Page* p = Page::FromAddress(code->address()); | |
3612 if (!p->IsEvacuationCandidate() && | |
3613 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { | |
3614 // Ignore all slots that might have been recorded in the body of the | |
3615 // deoptimized code object. | |
3616 RemoveObjectSlots(code->instruction_start(), | |
3617 code->address() + code->Size()); | |
3618 } | |
3619 } | |
3620 } | |
3621 | |
3622 | |
3623 void MarkCompactCollector::RemoveDeadInvalidatedCode() { | |
3624 int length = invalidated_code_.length(); | |
3625 for (int i = 0; i < length; i++) { | |
3626 if (!IsMarked(invalidated_code_[i])) invalidated_code_[i] = NULL; | |
3627 } | |
3628 } | |
3629 | |
3630 | |
3631 void MarkCompactCollector::ProcessInvalidatedCode(ObjectVisitor* visitor) { | |
3632 int length = invalidated_code_.length(); | |
3633 for (int i = 0; i < length; i++) { | |
3634 Code* code = invalidated_code_[i]; | |
3635 if (code != NULL) { | |
3636 code->Iterate(visitor); | |
3637 } | |
3638 } | |
3639 invalidated_code_.Rewind(0); | |
3640 } | |
3641 | |
3642 | |
3643 void MarkCompactCollector::RemoveObjectSlots(Address start_slot, | 3608 void MarkCompactCollector::RemoveObjectSlots(Address start_slot, |
3644 Address end_slot) { | 3609 Address end_slot) { |
3645 // Remove entries by replacing them with an old-space slot containing a smi | 3610 // Remove entries by replacing them with an old-space slot containing a smi |
3646 // that is located in an unmovable page. | 3611 // that is located in an unmovable page. |
3647 int npages = evacuation_candidates_.length(); | 3612 int npages = evacuation_candidates_.length(); |
3648 for (int i = 0; i < npages; i++) { | 3613 for (int i = 0; i < npages; i++) { |
3649 Page* p = evacuation_candidates_[i]; | 3614 Page* p = evacuation_candidates_[i]; |
3650 DCHECK(p->IsEvacuationCandidate() || | 3615 if (!p->IsEvacuationCandidate() && |
Michael Starzinger
2015/08/04 07:45:57
As discussed offline: This change looks bogus, the
Hannes Payer (out of office)
2015/08/10 12:04:55
Done.
| |
3651 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); | 3616 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) { |
3652 if (p->IsEvacuationCandidate()) { | |
3653 SlotsBuffer::RemoveObjectSlots(heap_, p->slots_buffer(), start_slot, | 3617 SlotsBuffer::RemoveObjectSlots(heap_, p->slots_buffer(), start_slot, |
3654 end_slot); | 3618 end_slot); |
3655 } | 3619 } |
3656 } | 3620 } |
3657 } | 3621 } |
3658 | 3622 |
3659 | 3623 |
3660 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { | 3624 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { |
3661 Heap::RelocationLock relocation_lock(heap()); | 3625 Heap::RelocationLock relocation_lock(heap()); |
3662 | 3626 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3794 | 3758 |
3795 heap_->string_table()->Iterate(&updating_visitor); | 3759 heap_->string_table()->Iterate(&updating_visitor); |
3796 | 3760 |
3797 // Update pointers from external string table. | 3761 // Update pointers from external string table. |
3798 heap_->UpdateReferencesInExternalStringTable( | 3762 heap_->UpdateReferencesInExternalStringTable( |
3799 &UpdateReferenceInExternalStringTableEntry); | 3763 &UpdateReferenceInExternalStringTableEntry); |
3800 | 3764 |
3801 EvacuationWeakObjectRetainer evacuation_object_retainer; | 3765 EvacuationWeakObjectRetainer evacuation_object_retainer; |
3802 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); | 3766 heap()->ProcessAllWeakReferences(&evacuation_object_retainer); |
3803 | 3767 |
3804 // Visit invalidated code (we ignored all slots on it) and clear mark-bits | |
3805 // under it. | |
3806 ProcessInvalidatedCode(&updating_visitor); | |
3807 | |
3808 heap_->isolate()->inner_pointer_to_code_cache()->Flush(); | 3768 heap_->isolate()->inner_pointer_to_code_cache()->Flush(); |
3809 | 3769 |
3810 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); | 3770 slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); |
3811 DCHECK(migration_slots_buffer_ == NULL); | 3771 DCHECK(migration_slots_buffer_ == NULL); |
3812 | 3772 |
3813 // The hashing of weak_object_to_code_table is no longer valid. | 3773 // The hashing of weak_object_to_code_table is no longer valid. |
3814 heap()->weak_object_to_code_table()->Rehash( | 3774 heap()->weak_object_to_code_table()->Rehash( |
3815 heap()->isolate()->factory()->undefined_value()); | 3775 heap()->isolate()->factory()->undefined_value()); |
3816 } | 3776 } |
3817 | 3777 |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4427 GCTracer::Scope::MC_SWEEP_CODE); | 4387 GCTracer::Scope::MC_SWEEP_CODE); |
4428 SweepSpace(heap()->code_space(), CONCURRENT_SWEEPING); | 4388 SweepSpace(heap()->code_space(), CONCURRENT_SWEEPING); |
4429 } | 4389 } |
4430 | 4390 |
4431 sweeping_in_progress_ = true; | 4391 sweeping_in_progress_ = true; |
4432 if (heap()->concurrent_sweeping_enabled()) { | 4392 if (heap()->concurrent_sweeping_enabled()) { |
4433 StartSweeperThreads(); | 4393 StartSweeperThreads(); |
4434 } | 4394 } |
4435 } | 4395 } |
4436 | 4396 |
4437 RemoveDeadInvalidatedCode(); | |
4438 | |
4439 EvacuateNewSpaceAndCandidates(); | 4397 EvacuateNewSpaceAndCandidates(); |
4440 | 4398 |
4441 heap()->FreeDeadArrayBuffers(false); | 4399 heap()->FreeDeadArrayBuffers(false); |
4442 | 4400 |
4443 // ClearNonLiveReferences depends on precise sweeping of map space to | 4401 // ClearNonLiveReferences depends on precise sweeping of map space to |
4444 // detect whether unmarked map became dead in this collection or in one | 4402 // detect whether unmarked map became dead in this collection or in one |
4445 // of the previous ones. | 4403 // of the previous ones. |
4446 { | 4404 { |
4447 GCTracer::Scope sweep_scope(heap()->tracer(), | 4405 GCTracer::Scope sweep_scope(heap()->tracer(), |
4448 GCTracer::Scope::MC_SWEEP_MAP); | 4406 GCTracer::Scope::MC_SWEEP_MAP); |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4800 SlotsBuffer* buffer = *buffer_address; | 4758 SlotsBuffer* buffer = *buffer_address; |
4801 while (buffer != NULL) { | 4759 while (buffer != NULL) { |
4802 SlotsBuffer* next_buffer = buffer->next(); | 4760 SlotsBuffer* next_buffer = buffer->next(); |
4803 DeallocateBuffer(buffer); | 4761 DeallocateBuffer(buffer); |
4804 buffer = next_buffer; | 4762 buffer = next_buffer; |
4805 } | 4763 } |
4806 *buffer_address = NULL; | 4764 *buffer_address = NULL; |
4807 } | 4765 } |
4808 } // namespace internal | 4766 } // namespace internal |
4809 } // namespace v8 | 4767 } // namespace v8 |
OLD | NEW |