| 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     DCHECK(p->IsEvacuationCandidate() || | 
| 3651            p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); | 3616            p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); | 
| 3652     if (p->IsEvacuationCandidate()) { | 3617     if (p->IsEvacuationCandidate()) { | 
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3794 | 3759 | 
| 3795   heap_->string_table()->Iterate(&updating_visitor); | 3760   heap_->string_table()->Iterate(&updating_visitor); | 
| 3796 | 3761 | 
| 3797   // Update pointers from external string table. | 3762   // Update pointers from external string table. | 
| 3798   heap_->UpdateReferencesInExternalStringTable( | 3763   heap_->UpdateReferencesInExternalStringTable( | 
| 3799       &UpdateReferenceInExternalStringTableEntry); | 3764       &UpdateReferenceInExternalStringTableEntry); | 
| 3800 | 3765 | 
| 3801   EvacuationWeakObjectRetainer evacuation_object_retainer; | 3766   EvacuationWeakObjectRetainer evacuation_object_retainer; | 
| 3802   heap()->ProcessAllWeakReferences(&evacuation_object_retainer); | 3767   heap()->ProcessAllWeakReferences(&evacuation_object_retainer); | 
| 3803 | 3768 | 
| 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(); | 3769   heap_->isolate()->inner_pointer_to_code_cache()->Flush(); | 
| 3809 | 3770 | 
| 3810   slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); | 3771   slots_buffer_allocator_.DeallocateChain(&migration_slots_buffer_); | 
| 3811   DCHECK(migration_slots_buffer_ == NULL); | 3772   DCHECK(migration_slots_buffer_ == NULL); | 
| 3812 | 3773 | 
| 3813   // The hashing of weak_object_to_code_table is no longer valid. | 3774   // The hashing of weak_object_to_code_table is no longer valid. | 
| 3814   heap()->weak_object_to_code_table()->Rehash( | 3775   heap()->weak_object_to_code_table()->Rehash( | 
| 3815       heap()->isolate()->factory()->undefined_value()); | 3776       heap()->isolate()->factory()->undefined_value()); | 
| 3816 } | 3777 } | 
| 3817 | 3778 | 
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4427                                   GCTracer::Scope::MC_SWEEP_CODE); | 4388                                   GCTracer::Scope::MC_SWEEP_CODE); | 
| 4428       SweepSpace(heap()->code_space(), CONCURRENT_SWEEPING); | 4389       SweepSpace(heap()->code_space(), CONCURRENT_SWEEPING); | 
| 4429     } | 4390     } | 
| 4430 | 4391 | 
| 4431     sweeping_in_progress_ = true; | 4392     sweeping_in_progress_ = true; | 
| 4432     if (heap()->concurrent_sweeping_enabled()) { | 4393     if (heap()->concurrent_sweeping_enabled()) { | 
| 4433       StartSweeperThreads(); | 4394       StartSweeperThreads(); | 
| 4434     } | 4395     } | 
| 4435   } | 4396   } | 
| 4436 | 4397 | 
| 4437   RemoveDeadInvalidatedCode(); |  | 
| 4438 |  | 
| 4439   EvacuateNewSpaceAndCandidates(); | 4398   EvacuateNewSpaceAndCandidates(); | 
| 4440 | 4399 | 
| 4441   heap()->FreeDeadArrayBuffers(false); | 4400   heap()->FreeDeadArrayBuffers(false); | 
| 4442 | 4401 | 
| 4443   // ClearNonLiveReferences depends on precise sweeping of map space to | 4402   // ClearNonLiveReferences depends on precise sweeping of map space to | 
| 4444   // detect whether unmarked map became dead in this collection or in one | 4403   // detect whether unmarked map became dead in this collection or in one | 
| 4445   // of the previous ones. | 4404   // of the previous ones. | 
| 4446   { | 4405   { | 
| 4447     GCTracer::Scope sweep_scope(heap()->tracer(), | 4406     GCTracer::Scope sweep_scope(heap()->tracer(), | 
| 4448                                 GCTracer::Scope::MC_SWEEP_MAP); | 4407                                 GCTracer::Scope::MC_SWEEP_MAP); | 
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4800   SlotsBuffer* buffer = *buffer_address; | 4759   SlotsBuffer* buffer = *buffer_address; | 
| 4801   while (buffer != NULL) { | 4760   while (buffer != NULL) { | 
| 4802     SlotsBuffer* next_buffer = buffer->next(); | 4761     SlotsBuffer* next_buffer = buffer->next(); | 
| 4803     DeallocateBuffer(buffer); | 4762     DeallocateBuffer(buffer); | 
| 4804     buffer = next_buffer; | 4763     buffer = next_buffer; | 
| 4805   } | 4764   } | 
| 4806   *buffer_address = NULL; | 4765   *buffer_address = NULL; | 
| 4807 } | 4766 } | 
| 4808 }  // namespace internal | 4767 }  // namespace internal | 
| 4809 }  // namespace v8 | 4768 }  // namespace v8 | 
| OLD | NEW | 
|---|