OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
553 void MarkCompactCollector::WaitUntilSweepingCompleted() { | 553 void MarkCompactCollector::WaitUntilSweepingCompleted() { |
554 ASSERT(sweeping_pending_ == true); | 554 ASSERT(sweeping_pending_ == true); |
555 for (int i = 0; i < FLAG_sweeper_threads; i++) { | 555 for (int i = 0; i < FLAG_sweeper_threads; i++) { |
556 heap()->isolate()->sweeper_threads()[i]->WaitForSweeperThread(); | 556 heap()->isolate()->sweeper_threads()[i]->WaitForSweeperThread(); |
557 } | 557 } |
558 sweeping_pending_ = false; | 558 sweeping_pending_ = false; |
559 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_DATA_SPACE)); | 559 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_DATA_SPACE)); |
560 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_POINTER_SPACE)); | 560 StealMemoryFromSweeperThreads(heap()->paged_space(OLD_POINTER_SPACE)); |
561 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); | 561 heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); |
562 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); | 562 heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes(); |
563 heap()->FreeQueuedChunks(); | |
Michael Starzinger
2013/03/08 12:52:06
There shouldn't be any queued chunks at this point
Hannes Payer (out of office)
2013/03/08 14:02:30
Done.
| |
563 } | 564 } |
564 | 565 |
565 | 566 |
566 intptr_t MarkCompactCollector:: | 567 intptr_t MarkCompactCollector:: |
567 StealMemoryFromSweeperThreads(PagedSpace* space) { | 568 StealMemoryFromSweeperThreads(PagedSpace* space) { |
568 intptr_t freed_bytes = 0; | 569 intptr_t freed_bytes = 0; |
569 for (int i = 0; i < FLAG_sweeper_threads; i++) { | 570 for (int i = 0; i < FLAG_sweeper_threads; i++) { |
570 freed_bytes += heap()->isolate()->sweeper_threads()[i]->StealMemory(space); | 571 freed_bytes += heap()->isolate()->sweeper_threads()[i]->StealMemory(space); |
571 } | 572 } |
572 space->AddToAccountingStats(freed_bytes); | 573 space->AddToAccountingStats(freed_bytes); |
573 space->DecrementUnsweptFreeBytes(freed_bytes); | 574 space->DecrementUnsweptFreeBytes(freed_bytes); |
574 return freed_bytes; | 575 return freed_bytes; |
575 } | 576 } |
576 | 577 |
577 | 578 |
578 bool MarkCompactCollector::AreSweeperThreadsActivated() { | 579 bool MarkCompactCollector::AreSweeperThreadsActivated() { |
579 return heap()->isolate()->sweeper_threads() != NULL; | 580 return heap()->isolate()->sweeper_threads() != NULL; |
580 } | 581 } |
581 | 582 |
582 | 583 |
583 bool MarkCompactCollector::IsConcurrentSweepingInProgress() { | 584 bool MarkCompactCollector::IsConcurrentSweepingInProgress() { |
584 return sweeping_pending_; | 585 return sweeping_pending_; |
585 } | 586 } |
586 | 587 |
587 | 588 |
588 void MarkCompactCollector::FinalizeSweeping() { | |
589 ASSERT(sweeping_pending_ == false); | |
590 ReleaseEvacuationCandidates(); | |
591 heap()->FreeQueuedChunks(); | |
592 } | |
593 | |
594 | |
595 void MarkCompactCollector::MarkInParallel() { | 589 void MarkCompactCollector::MarkInParallel() { |
596 for (int i = 0; i < FLAG_marking_threads; i++) { | 590 for (int i = 0; i < FLAG_marking_threads; i++) { |
597 heap()->isolate()->marking_threads()[i]->StartMarking(); | 591 heap()->isolate()->marking_threads()[i]->StartMarking(); |
598 } | 592 } |
599 } | 593 } |
600 | 594 |
601 | 595 |
602 void MarkCompactCollector::WaitUntilMarkingCompleted() { | 596 void MarkCompactCollector::WaitUntilMarkingCompleted() { |
603 for (int i = 0; i < FLAG_marking_threads; i++) { | 597 for (int i = 0; i < FLAG_marking_threads; i++) { |
604 heap()->isolate()->marking_threads()[i]->WaitForMarkingThread(); | 598 heap()->isolate()->marking_threads()[i]->WaitForMarkingThread(); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
904 #ifdef DEBUG | 898 #ifdef DEBUG |
905 ASSERT(state_ == IDLE); | 899 ASSERT(state_ == IDLE); |
906 state_ = PREPARE_GC; | 900 state_ = PREPARE_GC; |
907 #endif | 901 #endif |
908 | 902 |
909 ASSERT(!FLAG_never_compact || !FLAG_always_compact); | 903 ASSERT(!FLAG_never_compact || !FLAG_always_compact); |
910 | 904 |
911 if (IsConcurrentSweepingInProgress()) { | 905 if (IsConcurrentSweepingInProgress()) { |
912 // Instead of waiting we could also abort the sweeper threads here. | 906 // Instead of waiting we could also abort the sweeper threads here. |
913 WaitUntilSweepingCompleted(); | 907 WaitUntilSweepingCompleted(); |
914 FinalizeSweeping(); | |
915 } | 908 } |
916 | 909 |
917 // Clear marking bits if incremental marking is aborted. | 910 // Clear marking bits if incremental marking is aborted. |
918 if (was_marked_incrementally_ && abort_incremental_marking_) { | 911 if (was_marked_incrementally_ && abort_incremental_marking_) { |
919 heap()->incremental_marking()->Abort(); | 912 heap()->incremental_marking()->Abort(); |
920 ClearMarkbits(); | 913 ClearMarkbits(); |
921 AbortCompaction(); | 914 AbortCompaction(); |
922 was_marked_incrementally_ = false; | 915 was_marked_incrementally_ = false; |
923 } | 916 } |
924 | 917 |
(...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2842 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { | 2835 if (static_cast<PagedSpace*>(p->owner())->CanExpand()) { |
2843 EvacuateLiveObjectsFromPage(p); | 2836 EvacuateLiveObjectsFromPage(p); |
2844 } else { | 2837 } else { |
2845 // Without room for expansion evacuation is not guaranteed to succeed. | 2838 // Without room for expansion evacuation is not guaranteed to succeed. |
2846 // Pessimistically abandon unevacuated pages. | 2839 // Pessimistically abandon unevacuated pages. |
2847 for (int j = i; j < npages; j++) { | 2840 for (int j = i; j < npages; j++) { |
2848 Page* page = evacuation_candidates_[j]; | 2841 Page* page = evacuation_candidates_[j]; |
2849 slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address()); | 2842 slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address()); |
2850 page->ClearEvacuationCandidate(); | 2843 page->ClearEvacuationCandidate(); |
2851 page->SetFlag(Page::RESCAN_ON_EVACUATION); | 2844 page->SetFlag(Page::RESCAN_ON_EVACUATION); |
2845 page->InsertAfter(static_cast<PagedSpace*>(page->owner())->anchor()); | |
2852 } | 2846 } |
2853 return; | 2847 return; |
2854 } | 2848 } |
2855 } | 2849 } |
2856 } | 2850 } |
2857 } | 2851 } |
2858 | 2852 |
2859 | 2853 |
2860 class EvacuationWeakObjectRetainer : public WeakObjectRetainer { | 2854 class EvacuationWeakObjectRetainer : public WeakObjectRetainer { |
2861 public: | 2855 public: |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3319 p->set_scan_on_scavenge(false); | 3313 p->set_scan_on_scavenge(false); |
3320 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); | 3314 slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address()); |
3321 p->ResetLiveBytes(); | 3315 p->ResetLiveBytes(); |
3322 space->ReleasePage(p); | 3316 space->ReleasePage(p); |
3323 } | 3317 } |
3324 evacuation_candidates_.Rewind(0); | 3318 evacuation_candidates_.Rewind(0); |
3325 compacting_ = false; | 3319 compacting_ = false; |
3326 } | 3320 } |
3327 | 3321 |
3328 | 3322 |
3323 void MarkCompactCollector::UnlinkEvacuationCandidates() { | |
Michael Starzinger
2013/03/08 12:52:06
Can we move that to above the ReleaseEvacuationCan
Hannes Payer (out of office)
2013/03/08 14:02:30
Done.
| |
3324 int npages = evacuation_candidates_.length(); | |
3325 for (int i = 0; i < npages; i++) { | |
3326 Page* p = evacuation_candidates_[i]; | |
3327 if (!p->IsEvacuationCandidate()) continue; | |
3328 p->Unlink(); | |
3329 p->ClearSweptPrecisely(); | |
3330 p->ClearSweptConservatively(); | |
3331 } | |
3332 } | |
3333 | |
3334 | |
3329 static const int kStartTableEntriesPerLine = 5; | 3335 static const int kStartTableEntriesPerLine = 5; |
3330 static const int kStartTableLines = 171; | 3336 static const int kStartTableLines = 171; |
3331 static const int kStartTableInvalidLine = 127; | 3337 static const int kStartTableInvalidLine = 127; |
3332 static const int kStartTableUnusedEntry = 126; | 3338 static const int kStartTableUnusedEntry = 126; |
3333 | 3339 |
3334 #define _ kStartTableUnusedEntry | 3340 #define _ kStartTableUnusedEntry |
3335 #define X kStartTableInvalidLine | 3341 #define X kStartTableInvalidLine |
3336 // Mark-bit to object start offset table. | 3342 // Mark-bit to object start offset table. |
3337 // | 3343 // |
3338 // The line is indexed by the mark bits in a byte. The first number on | 3344 // The line is indexed by the mark bits in a byte. The first number on |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3892 if (sweep_precisely_) how_to_sweep = PRECISE; | 3898 if (sweep_precisely_) how_to_sweep = PRECISE; |
3893 // Noncompacting collections simply sweep the spaces to clear the mark | 3899 // Noncompacting collections simply sweep the spaces to clear the mark |
3894 // bits and free the nonlive blocks (for old and map spaces). We sweep | 3900 // bits and free the nonlive blocks (for old and map spaces). We sweep |
3895 // the map space last because freeing non-live maps overwrites them and | 3901 // the map space last because freeing non-live maps overwrites them and |
3896 // the other spaces rely on possibly non-live maps to get the sizes for | 3902 // the other spaces rely on possibly non-live maps to get the sizes for |
3897 // non-live objects. | 3903 // non-live objects. |
3898 SequentialSweepingScope scope(this); | 3904 SequentialSweepingScope scope(this); |
3899 SweepSpace(heap()->old_pointer_space(), how_to_sweep); | 3905 SweepSpace(heap()->old_pointer_space(), how_to_sweep); |
3900 SweepSpace(heap()->old_data_space(), how_to_sweep); | 3906 SweepSpace(heap()->old_data_space(), how_to_sweep); |
3901 | 3907 |
3908 UnlinkEvacuationCandidates(); | |
Michael Starzinger
2013/03/08 12:52:06
Add a short comment about why this needs to be don
Hannes Payer (out of office)
2013/03/08 14:02:30
Done.
| |
3909 | |
3902 if (how_to_sweep == PARALLEL_CONSERVATIVE || | 3910 if (how_to_sweep == PARALLEL_CONSERVATIVE || |
3903 how_to_sweep == CONCURRENT_CONSERVATIVE) { | 3911 how_to_sweep == CONCURRENT_CONSERVATIVE) { |
3904 // TODO(hpayer): fix race with concurrent sweeper | 3912 // TODO(hpayer): fix race with concurrent sweeper |
3905 StartSweeperThreads(); | 3913 StartSweeperThreads(); |
3906 } | 3914 } |
3907 | 3915 |
3908 if (how_to_sweep == PARALLEL_CONSERVATIVE) { | 3916 if (how_to_sweep == PARALLEL_CONSERVATIVE) { |
3909 WaitUntilSweepingCompleted(); | 3917 WaitUntilSweepingCompleted(); |
3910 } | 3918 } |
3911 | 3919 |
3912 RemoveDeadInvalidatedCode(); | 3920 RemoveDeadInvalidatedCode(); |
3913 SweepSpace(heap()->code_space(), PRECISE); | 3921 SweepSpace(heap()->code_space(), PRECISE); |
3914 | 3922 |
3915 SweepSpace(heap()->cell_space(), PRECISE); | 3923 SweepSpace(heap()->cell_space(), PRECISE); |
3916 | 3924 |
3917 EvacuateNewSpaceAndCandidates(); | 3925 EvacuateNewSpaceAndCandidates(); |
3918 | 3926 |
3919 // ClearNonLiveTransitions depends on precise sweeping of map space to | 3927 // ClearNonLiveTransitions depends on precise sweeping of map space to |
3920 // detect whether unmarked map became dead in this collection or in one | 3928 // detect whether unmarked map became dead in this collection or in one |
3921 // of the previous ones. | 3929 // of the previous ones. |
3922 SweepSpace(heap()->map_space(), PRECISE); | 3930 SweepSpace(heap()->map_space(), PRECISE); |
3923 | 3931 |
3924 // Deallocate unmarked objects and clear marked bits for marked objects. | 3932 // Deallocate unmarked objects and clear marked bits for marked objects. |
3925 heap_->lo_space()->FreeUnmarkedObjects(); | 3933 heap_->lo_space()->FreeUnmarkedObjects(); |
3926 | 3934 |
3927 if (how_to_sweep != CONCURRENT_CONSERVATIVE) { | 3935 ReleaseEvacuationCandidates(); |
Michael Starzinger
2013/03/08 12:52:06
The right place to call FreeQueuedChunks would be
Hannes Payer (out of office)
2013/03/08 14:02:30
Done.
| |
3928 FinalizeSweeping(); | |
3929 } | |
3930 } | 3936 } |
3931 | 3937 |
3932 | 3938 |
3933 void MarkCompactCollector::EnableCodeFlushing(bool enable) { | 3939 void MarkCompactCollector::EnableCodeFlushing(bool enable) { |
3934 #ifdef ENABLE_DEBUGGER_SUPPORT | 3940 #ifdef ENABLE_DEBUGGER_SUPPORT |
3935 if (heap()->isolate()->debug()->IsLoaded() || | 3941 if (heap()->isolate()->debug()->IsLoaded() || |
3936 heap()->isolate()->debug()->has_break_points()) { | 3942 heap()->isolate()->debug()->has_break_points()) { |
3937 enable = false; | 3943 enable = false; |
3938 } | 3944 } |
3939 #endif | 3945 #endif |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4120 while (buffer != NULL) { | 4126 while (buffer != NULL) { |
4121 SlotsBuffer* next_buffer = buffer->next(); | 4127 SlotsBuffer* next_buffer = buffer->next(); |
4122 DeallocateBuffer(buffer); | 4128 DeallocateBuffer(buffer); |
4123 buffer = next_buffer; | 4129 buffer = next_buffer; |
4124 } | 4130 } |
4125 *buffer_address = NULL; | 4131 *buffer_address = NULL; |
4126 } | 4132 } |
4127 | 4133 |
4128 | 4134 |
4129 } } // namespace v8::internal | 4135 } } // namespace v8::internal |
OLD | NEW |