Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: src/heap/mark-compact.h

Issue 2828323004: [heap] Refactor MC and introduce MarkCompactCollectorBase (Closed)
Patch Set: More refactoring Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/mark-compact.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef V8_HEAP_MARK_COMPACT_H_ 5 #ifndef V8_HEAP_MARK_COMPACT_H_
6 #define V8_HEAP_MARK_COMPACT_H_ 6 #define V8_HEAP_MARK_COMPACT_H_
7 7
8 #include <deque> 8 #include <deque>
9 9
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
11 #include "src/base/platform/condition-variable.h" 11 #include "src/base/platform/condition-variable.h"
12 #include "src/cancelable-task.h" 12 #include "src/cancelable-task.h"
13 #include "src/heap/marking.h" 13 #include "src/heap/marking.h"
14 #include "src/heap/spaces.h" 14 #include "src/heap/spaces.h"
15 #include "src/heap/store-buffer.h" 15 #include "src/heap/store-buffer.h"
16 16
17 namespace v8 { 17 namespace v8 {
18 namespace internal { 18 namespace internal {
19 19
20 // Callback function, returns whether an object is alive. The heap size
21 // of the object is returned in size. It optionally updates the offset
22 // to the first live object in the page (only used for old and map objects).
23 typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset);
24
25 // Callback function to mark an object in a given heap.
26 typedef void (*MarkObjectFunction)(Heap* heap, HeapObject* object);
27
28 // Forward declarations. 20 // Forward declarations.
29 class CodeFlusher; 21 class CodeFlusher;
30 class HeapObjectVisitor; 22 class HeapObjectVisitor;
31 class MarkCompactCollector; 23 class MarkCompactCollector;
32 class MinorMarkCompactCollector; 24 class MinorMarkCompactCollector;
33 class MarkingVisitor; 25 class MarkingVisitor;
26 class ThreadLocalTop;
34 27
35 class ObjectMarking : public AllStatic { 28 class ObjectMarking : public AllStatic {
36 public: 29 public:
37 V8_INLINE static MarkBit MarkBitFrom(HeapObject* obj, 30 V8_INLINE static MarkBit MarkBitFrom(HeapObject* obj,
38 const MarkingState& state) { 31 const MarkingState& state) {
39 const Address address = obj->address(); 32 const Address address = obj->address();
40 const MemoryChunk* p = MemoryChunk::FromAddress(address); 33 const MemoryChunk* p = MemoryChunk::FromAddress(address);
41 return state.bitmap()->MarkBitFromIndex(p->AddressToMarkbitIndex(address)); 34 return state.bitmap()->MarkBitFromIndex(p->AddressToMarkbitIndex(address));
42 } 35 }
43 36
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 SharedFunctionInfo* next_candidate); 296 SharedFunctionInfo* next_candidate);
304 static inline void ClearNextCandidate(SharedFunctionInfo* candidate); 297 static inline void ClearNextCandidate(SharedFunctionInfo* candidate);
305 298
306 Isolate* isolate_; 299 Isolate* isolate_;
307 JSFunction* jsfunction_candidates_head_; 300 JSFunction* jsfunction_candidates_head_;
308 SharedFunctionInfo* shared_function_info_candidates_head_; 301 SharedFunctionInfo* shared_function_info_candidates_head_;
309 302
310 DISALLOW_COPY_AND_ASSIGN(CodeFlusher); 303 DISALLOW_COPY_AND_ASSIGN(CodeFlusher);
311 }; 304 };
312 305
313
314 // Defined in isolate.h.
315 class ThreadLocalTop;
316
317 class MarkBitCellIterator BASE_EMBEDDED { 306 class MarkBitCellIterator BASE_EMBEDDED {
318 public: 307 public:
319 MarkBitCellIterator(MemoryChunk* chunk, MarkingState state) : chunk_(chunk) { 308 MarkBitCellIterator(MemoryChunk* chunk, MarkingState state) : chunk_(chunk) {
320 last_cell_index_ = Bitmap::IndexToCell(Bitmap::CellAlignIndex( 309 last_cell_index_ = Bitmap::IndexToCell(Bitmap::CellAlignIndex(
321 chunk_->AddressToMarkbitIndex(chunk_->area_end()))); 310 chunk_->AddressToMarkbitIndex(chunk_->area_end())));
322 cell_base_ = chunk_->area_start(); 311 cell_base_ = chunk_->area_start();
323 cell_index_ = Bitmap::IndexToCell( 312 cell_index_ = Bitmap::IndexToCell(
324 Bitmap::CellAlignIndex(chunk_->AddressToMarkbitIndex(cell_base_))); 313 Bitmap::CellAlignIndex(chunk_->AddressToMarkbitIndex(cell_base_)));
325 cells_ = state.bitmap()->cells(); 314 cells_ = state.bitmap()->cells();
326 } 315 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 template <class Visitor> 404 template <class Visitor>
416 bool VisitBlackObjects(MemoryChunk* chunk, const MarkingState& state, 405 bool VisitBlackObjects(MemoryChunk* chunk, const MarkingState& state,
417 Visitor* visitor, IterationMode iteration_mode); 406 Visitor* visitor, IterationMode iteration_mode);
418 407
419 private: 408 private:
420 void RecomputeLiveBytes(MemoryChunk* chunk, const MarkingState& state); 409 void RecomputeLiveBytes(MemoryChunk* chunk, const MarkingState& state);
421 }; 410 };
422 411
423 enum PageEvacuationMode { NEW_TO_NEW, NEW_TO_OLD }; 412 enum PageEvacuationMode { NEW_TO_NEW, NEW_TO_OLD };
424 413
425 class MinorMarkCompactCollector { 414 // Base class for minor and full MC collectors.
415 class MarkCompactCollectorBase {
416 public:
417 virtual ~MarkCompactCollectorBase() {}
418 virtual void SetUp() = 0;
419 virtual void TearDown() = 0;
420 virtual void CollectGarbage() = 0;
421
422 inline Heap* heap() const { return heap_; }
423 inline Isolate* isolate() { return heap()->isolate(); }
424
425 protected:
426 explicit MarkCompactCollectorBase(Heap* heap) : heap_(heap) {}
427
428 virtual void MarkLiveObjects() = 0;
429
430 // The number of parallel compaction tasks, including the main thread.
431 int NumberOfParallelCompactionTasks(int pages, intptr_t live_bytes);
432
433 Heap* heap_;
434 };
435
436 // Collector for young-generation only.
437 class MinorMarkCompactCollector final : public MarkCompactCollectorBase {
426 public: 438 public:
427 explicit MinorMarkCompactCollector(Heap* heap) 439 explicit MinorMarkCompactCollector(Heap* heap)
428 : heap_(heap), marking_deque_(heap) {} 440 : MarkCompactCollectorBase(heap), marking_deque_(heap) {}
429 441
430 void SetUp(); 442 void SetUp() override;
431 void TearDown(); 443 void TearDown() override;
432 444 void CollectGarbage() override;
433 void CollectGarbage();
434
435 inline Heap* heap() const { return heap_; }
436 445
437 private: 446 private:
438 class RootMarkingVisitor; 447 class RootMarkingVisitor;
439 448
440 inline Isolate* isolate() { return heap()->isolate(); }
441 inline MarkingDeque* marking_deque() { return &marking_deque_; } 449 inline MarkingDeque* marking_deque() { return &marking_deque_; }
442 450
443 V8_INLINE void MarkObject(HeapObject* obj); 451 V8_INLINE void MarkObject(HeapObject* obj);
444 V8_INLINE void PushBlack(HeapObject* obj); 452 V8_INLINE void PushBlack(HeapObject* obj);
445 453
446 SlotCallbackResult CheckAndMarkObject(Heap* heap, Address slot_address); 454 SlotCallbackResult CheckAndMarkObject(Heap* heap, Address slot_address);
447 void MarkLiveObjects(); 455 void MarkLiveObjects() override;
448 void ProcessMarkingDeque(); 456 void ProcessMarkingDeque();
449 void EmptyMarkingDeque(); 457 void EmptyMarkingDeque();
450 458
451 Heap* heap_;
452 MarkingDeque marking_deque_; 459 MarkingDeque marking_deque_;
453 460
454 friend class StaticYoungGenerationMarkingVisitor; 461 friend class StaticYoungGenerationMarkingVisitor;
455 }; 462 };
456 463
457 // ------------------------------------------------------------------------- 464 // Collector for young and old generation.
458 // Mark-Compact collector 465 class MarkCompactCollector final : public MarkCompactCollectorBase {
459 class MarkCompactCollector {
460 public: 466 public:
461 class RootMarkingVisitor; 467 class RootMarkingVisitor;
462 468
463 class Sweeper { 469 class Sweeper {
464 public: 470 public:
465 class SweeperTask; 471 class SweeperTask;
466 472
467 enum FreeListRebuildingMode { REBUILD_FREE_LIST, IGNORE_FREE_LIST }; 473 enum FreeListRebuildingMode { REBUILD_FREE_LIST, IGNORE_FREE_LIST };
468 enum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE }; 474 enum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE };
469 enum ClearOldToNewSlotsMode { 475 enum ClearOldToNewSlotsMode {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 base::AtomicNumber<intptr_t> num_sweeping_tasks_; 542 base::AtomicNumber<intptr_t> num_sweeping_tasks_;
537 }; 543 };
538 544
539 enum IterationMode { 545 enum IterationMode {
540 kKeepMarking, 546 kKeepMarking,
541 kClearMarkbits, 547 kClearMarkbits,
542 }; 548 };
543 549
544 static void Initialize(); 550 static void Initialize();
545 551
546 static SlotCallbackResult CheckAndMarkObject(Heap* heap, 552 void SetUp() override;
547 Address slot_address); 553 void TearDown() override;
548 554 // Performs a global garbage collection.
549 void SetUp(); 555 void CollectGarbage() override;
550
551 void TearDown();
552 556
553 void CollectEvacuationCandidates(PagedSpace* space); 557 void CollectEvacuationCandidates(PagedSpace* space);
554 558
555 void AddEvacuationCandidate(Page* p); 559 void AddEvacuationCandidate(Page* p);
556 560
557 // Prepares for GC by resetting relocation info in old and map spaces and 561 // Prepares for GC by resetting relocation info in old and map spaces and
558 // choosing spaces to compact. 562 // choosing spaces to compact.
559 void Prepare(); 563 void Prepare();
560 564
561 // Performs a global garbage collection.
562 void CollectGarbage();
563
564 bool StartCompaction(); 565 bool StartCompaction();
565 566
566 void AbortCompaction(); 567 void AbortCompaction();
567 568
568 // Determine type of object and emit deletion log event. 569 // Determine type of object and emit deletion log event.
569 static void ReportDeleteIfNeeded(HeapObject* obj, Isolate* isolate); 570 static void ReportDeleteIfNeeded(HeapObject* obj, Isolate* isolate);
570 571
571 // Distinguishable invalid map encodings (for single word and multiple words) 572 // Distinguishable invalid map encodings (for single word and multiple words)
572 // that indicate free regions. 573 // that indicate free regions.
573 static const uint32_t kSingleFreeEncoding = 0; 574 static const uint32_t kSingleFreeEncoding = 0;
574 static const uint32_t kMultiFreeEncoding = 1; 575 static const uint32_t kMultiFreeEncoding = 1;
575 576
576 inline Heap* heap() const { return heap_; }
577 inline Isolate* isolate() const; 577 inline Isolate* isolate() const;
578 578
579 CodeFlusher* code_flusher() { return code_flusher_; } 579 CodeFlusher* code_flusher() { return code_flusher_; }
580 inline bool is_code_flushing_enabled() const { return code_flusher_ != NULL; } 580 inline bool is_code_flushing_enabled() const { return code_flusher_ != NULL; }
581 581
582 INLINE(static bool ShouldSkipEvacuationSlotRecording(Object* host)) { 582 INLINE(static bool ShouldSkipEvacuationSlotRecording(Object* host)) {
583 return Page::FromAddress(reinterpret_cast<Address>(host)) 583 return Page::FromAddress(reinterpret_cast<Address>(host))
584 ->ShouldSkipEvacuationSlotRecording(); 584 ->ShouldSkipEvacuationSlotRecording();
585 } 585 }
586 586
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 int* target_fragmentation_percent, 652 int* target_fragmentation_percent,
653 size_t* max_evacuated_bytes); 653 size_t* max_evacuated_bytes);
654 654
655 void VisitAllObjects(HeapObjectVisitor* visitor); 655 void VisitAllObjects(HeapObjectVisitor* visitor);
656 656
657 void RecordObjectStats(); 657 void RecordObjectStats();
658 658
659 // Finishes GC, performs heap verification if enabled. 659 // Finishes GC, performs heap verification if enabled.
660 void Finish(); 660 void Finish();
661 661
662 // -----------------------------------------------------------------------
663 // Phase 1: Marking live objects.
664 //
665 // Before: The heap has been prepared for garbage collection by
666 // MarkCompactCollector::Prepare() and is otherwise in its
667 // normal state.
668 //
669 // After: Live objects are marked and non-live objects are unmarked.
670
671 friend class CodeMarkingVisitor;
672 friend class IncrementalMarkingMarkingVisitor;
673 friend class MarkCompactMarkingVisitor;
674 friend class MarkingVisitor;
675 friend class RecordMigratedSlotVisitor;
676 friend class SharedFunctionInfoMarkingVisitor;
677 friend class StaticYoungGenerationMarkingVisitor;
678
679 // Mark code objects that are active on the stack to prevent them 662 // Mark code objects that are active on the stack to prevent them
680 // from being flushed. 663 // from being flushed.
681 void PrepareThreadForCodeFlushing(Isolate* isolate, ThreadLocalTop* top); 664 void PrepareThreadForCodeFlushing(Isolate* isolate, ThreadLocalTop* top);
682 665
683 void PrepareForCodeFlushing(); 666 void PrepareForCodeFlushing();
684 667
685 // Marking operations for objects reachable from roots. 668 // Marking operations for objects reachable from roots.
686 void MarkLiveObjects(); 669 void MarkLiveObjects() override;
687 670
688 // Pushes a black object onto the marking stack and accounts for live bytes. 671 // Pushes a black object onto the marking stack and accounts for live bytes.
689 // Note that this assumes live bytes have not yet been counted. 672 // Note that this assumes live bytes have not yet been counted.
690 V8_INLINE void PushBlack(HeapObject* obj); 673 V8_INLINE void PushBlack(HeapObject* obj);
691 674
692 // Unshifts a black object into the marking stack and accounts for live bytes. 675 // Unshifts a black object into the marking stack and accounts for live bytes.
693 // Note that this assumes lives bytes have already been counted. 676 // Note that this assumes lives bytes have already been counted.
694 V8_INLINE void UnshiftBlack(HeapObject* obj); 677 V8_INLINE void UnshiftBlack(HeapObject* obj);
695 678
696 // Marks the object black and pushes it on the marking stack. 679 // Marks the object black and pushes it on the marking stack.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 769
787 // Starts sweeping of spaces by contributing on the main thread and setting 770 // Starts sweeping of spaces by contributing on the main thread and setting
788 // up other pages for sweeping. Does not start sweeper tasks. 771 // up other pages for sweeping. Does not start sweeper tasks.
789 void StartSweepSpaces(); 772 void StartSweepSpaces();
790 void StartSweepSpace(PagedSpace* space); 773 void StartSweepSpace(PagedSpace* space);
791 774
792 void EvacuatePrologue(); 775 void EvacuatePrologue();
793 void EvacuateEpilogue(); 776 void EvacuateEpilogue();
794 void EvacuatePagesInParallel(); 777 void EvacuatePagesInParallel();
795 778
796 // The number of parallel compaction tasks, including the main thread.
797 int NumberOfParallelCompactionTasks(int pages, intptr_t live_bytes);
798
799 void EvacuateNewSpaceAndCandidates(); 779 void EvacuateNewSpaceAndCandidates();
800 780
801 void UpdatePointersAfterEvacuation(); 781 void UpdatePointersAfterEvacuation();
802 782
803 void ReleaseEvacuationCandidates(); 783 void ReleaseEvacuationCandidates();
804 784
805
806 #ifdef DEBUG
807 friend class MarkObjectVisitor;
808 static void VisitObject(HeapObject* obj);
809
810 friend class UnmarkObjectVisitor;
811 static void UnmarkObject(HeapObject* obj);
812 #endif
813
814 Heap* heap_;
815
816 base::Semaphore page_parallel_job_semaphore_; 785 base::Semaphore page_parallel_job_semaphore_;
817 786
818 #ifdef DEBUG 787 #ifdef DEBUG
819 enum CollectorState { 788 enum CollectorState {
820 IDLE, 789 IDLE,
821 PREPARE_GC, 790 PREPARE_GC,
822 MARK_LIVE_OBJECTS, 791 MARK_LIVE_OBJECTS,
823 SWEEP_SPACES, 792 SWEEP_SPACES,
824 ENCODE_FORWARDING_ADDRESSES, 793 ENCODE_FORWARDING_ADDRESSES,
825 UPDATE_POINTERS, 794 UPDATE_POINTERS,
(...skipping 21 matching lines...) Expand all
847 CodeFlusher* code_flusher_; 816 CodeFlusher* code_flusher_;
848 817
849 // Candidates for pages that should be evacuated. 818 // Candidates for pages that should be evacuated.
850 List<Page*> evacuation_candidates_; 819 List<Page*> evacuation_candidates_;
851 // Pages that are actually processed during evacuation. 820 // Pages that are actually processed during evacuation.
852 List<Page*> old_space_evacuation_pages_; 821 List<Page*> old_space_evacuation_pages_;
853 List<Page*> new_space_evacuation_pages_; 822 List<Page*> new_space_evacuation_pages_;
854 823
855 Sweeper sweeper_; 824 Sweeper sweeper_;
856 825
826 friend class CodeMarkingVisitor;
857 friend class Heap; 827 friend class Heap;
828 friend class IncrementalMarkingMarkingVisitor;
829 friend class MarkCompactMarkingVisitor;
830 friend class MarkingVisitor;
831 friend class RecordMigratedSlotVisitor;
832 friend class SharedFunctionInfoMarkingVisitor;
833 friend class StaticYoungGenerationMarkingVisitor;
858 friend class StoreBuffer; 834 friend class StoreBuffer;
859 }; 835 };
860 836
861
862 class EvacuationScope BASE_EMBEDDED { 837 class EvacuationScope BASE_EMBEDDED {
863 public: 838 public:
864 explicit EvacuationScope(MarkCompactCollector* collector) 839 explicit EvacuationScope(MarkCompactCollector* collector)
865 : collector_(collector) { 840 : collector_(collector) {
866 collector_->set_evacuation(true); 841 collector_->set_evacuation(true);
867 } 842 }
868 843
869 ~EvacuationScope() { collector_->set_evacuation(false); } 844 ~EvacuationScope() { collector_->set_evacuation(false); }
870 845
871 private: 846 private:
872 MarkCompactCollector* collector_; 847 MarkCompactCollector* collector_;
873 }; 848 };
874 849
875 V8_EXPORT_PRIVATE const char* AllocationSpaceName(AllocationSpace space);
876 } // namespace internal 850 } // namespace internal
877 } // namespace v8 851 } // namespace v8
878 852
879 #endif // V8_HEAP_MARK_COMPACT_H_ 853 #endif // V8_HEAP_MARK_COMPACT_H_
OLDNEW
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/mark-compact.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698