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 24 matching lines...) Expand all Loading... |
35 namespace internal { | 35 namespace internal { |
36 | 36 |
37 // Callback function, returns whether an object is alive. The heap size | 37 // Callback function, returns whether an object is alive. The heap size |
38 // of the object is returned in size. It optionally updates the offset | 38 // of the object is returned in size. It optionally updates the offset |
39 // to the first live object in the page (only used for old and map objects). | 39 // to the first live object in the page (only used for old and map objects). |
40 typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset); | 40 typedef bool (*IsAliveFunction)(HeapObject* obj, int* size, int* offset); |
41 | 41 |
42 // Forward declarations. | 42 // Forward declarations. |
43 class CodeFlusher; | 43 class CodeFlusher; |
44 class GCTracer; | 44 class GCTracer; |
| 45 class MarkCompactCollector; |
45 class MarkingVisitor; | 46 class MarkingVisitor; |
46 class RootMarkingVisitor; | 47 class RootMarkingVisitor; |
47 | 48 |
48 | 49 |
49 class Marking { | 50 class Marking { |
50 public: | 51 public: |
51 explicit Marking(Heap* heap) | 52 explicit Marking(Heap* heap) |
52 : heap_(heap) { | 53 : heap_(heap) { |
53 } | 54 } |
54 | 55 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 } | 160 } |
160 return is_black; | 161 return is_black; |
161 } | 162 } |
162 | 163 |
163 private: | 164 private: |
164 Heap* heap_; | 165 Heap* heap_; |
165 }; | 166 }; |
166 | 167 |
167 // ---------------------------------------------------------------------------- | 168 // ---------------------------------------------------------------------------- |
168 // Marking deque for tracing live objects. | 169 // Marking deque for tracing live objects. |
169 | |
170 class MarkingDeque { | 170 class MarkingDeque { |
171 public: | 171 public: |
172 MarkingDeque() | 172 MarkingDeque() |
173 : array_(NULL), top_(0), bottom_(0), mask_(0), overflowed_(false) { } | 173 : array_(NULL), top_(0), bottom_(0), mask_(0), overflowed_(false) { } |
174 | 174 |
175 void Initialize(Address low, Address high) { | 175 void Initialize(Address low, Address high) { |
176 HeapObject** obj_low = reinterpret_cast<HeapObject**>(low); | 176 HeapObject** obj_low = reinterpret_cast<HeapObject**>(low); |
177 HeapObject** obj_high = reinterpret_cast<HeapObject**>(high); | 177 HeapObject** obj_high = reinterpret_cast<HeapObject**>(high); |
178 array_ = obj_low; | 178 array_ = obj_low; |
179 mask_ = RoundDownToPowerOf2(static_cast<int>(obj_high - obj_low)) - 1; | 179 mask_ = RoundDownToPowerOf2(static_cast<int>(obj_high - obj_low)) - 1; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 private: | 376 private: |
377 static const int kChainLengthThreshold = 15; | 377 static const int kChainLengthThreshold = 15; |
378 | 378 |
379 intptr_t idx_; | 379 intptr_t idx_; |
380 intptr_t chain_length_; | 380 intptr_t chain_length_; |
381 SlotsBuffer* next_; | 381 SlotsBuffer* next_; |
382 ObjectSlot slots_[kNumberOfElements]; | 382 ObjectSlot slots_[kNumberOfElements]; |
383 }; | 383 }; |
384 | 384 |
385 | 385 |
| 386 // ------------------------------------------------------------------------- |
| 387 // Marker shared between incremental and non-incremental marking |
| 388 template<class BaseMarker> class Marker { |
| 389 public: |
| 390 Marker(BaseMarker* base_marker, MarkCompactCollector* mark_compact_collector) |
| 391 : base_marker_(base_marker), |
| 392 mark_compact_collector_(mark_compact_collector) {} |
| 393 |
| 394 // Mark pointers in a Map and its DescriptorArray together, possibly |
| 395 // treating transitions or back pointers weak. |
| 396 void MarkMapContents(Map* map); |
| 397 void MarkDescriptorArray(DescriptorArray* descriptors); |
| 398 void MarkAccessorPairSlot(AccessorPair* accessors, int offset); |
| 399 |
| 400 private: |
| 401 BaseMarker* base_marker() { |
| 402 return base_marker_; |
| 403 } |
| 404 |
| 405 MarkCompactCollector* mark_compact_collector() { |
| 406 return mark_compact_collector_; |
| 407 } |
| 408 |
| 409 BaseMarker* base_marker_; |
| 410 MarkCompactCollector* mark_compact_collector_; |
| 411 }; |
| 412 |
| 413 |
386 // Defined in isolate.h. | 414 // Defined in isolate.h. |
387 class ThreadLocalTop; | 415 class ThreadLocalTop; |
388 | 416 |
389 | 417 |
390 // ------------------------------------------------------------------------- | 418 // ------------------------------------------------------------------------- |
391 // Mark-Compact collector | 419 // Mark-Compact collector |
392 class MarkCompactCollector { | 420 class MarkCompactCollector { |
393 public: | 421 public: |
394 // Type of functions to compute forwarding addresses of objects in | 422 // Type of functions to compute forwarding addresses of objects in |
395 // compacted spaces. Given an object and its size, return a (non-failure) | 423 // compacted spaces. Given an object and its size, return a (non-failure) |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 bool reduce_memory_footprint_; | 605 bool reduce_memory_footprint_; |
578 | 606 |
579 bool abort_incremental_marking_; | 607 bool abort_incremental_marking_; |
580 | 608 |
581 // True if we are collecting slots to perform evacuation from evacuation | 609 // True if we are collecting slots to perform evacuation from evacuation |
582 // candidates. | 610 // candidates. |
583 bool compacting_; | 611 bool compacting_; |
584 | 612 |
585 bool was_marked_incrementally_; | 613 bool was_marked_incrementally_; |
586 | 614 |
587 bool collect_maps_; | |
588 | |
589 bool flush_monomorphic_ics_; | 615 bool flush_monomorphic_ics_; |
590 | 616 |
591 // A pointer to the current stack-allocated GC tracer object during a full | 617 // A pointer to the current stack-allocated GC tracer object during a full |
592 // collection (NULL before and after). | 618 // collection (NULL before and after). |
593 GCTracer* tracer_; | 619 GCTracer* tracer_; |
594 | 620 |
595 SlotsBufferAllocator slots_buffer_allocator_; | 621 SlotsBufferAllocator slots_buffer_allocator_; |
596 | 622 |
597 SlotsBuffer* migration_slots_buffer_; | 623 SlotsBuffer* migration_slots_buffer_; |
598 | 624 |
599 // Finishes GC, performs heap verification if enabled. | 625 // Finishes GC, performs heap verification if enabled. |
600 void Finish(); | 626 void Finish(); |
601 | 627 |
602 // ----------------------------------------------------------------------- | 628 // ----------------------------------------------------------------------- |
603 // Phase 1: Marking live objects. | 629 // Phase 1: Marking live objects. |
604 // | 630 // |
605 // Before: The heap has been prepared for garbage collection by | 631 // Before: The heap has been prepared for garbage collection by |
606 // MarkCompactCollector::Prepare() and is otherwise in its | 632 // MarkCompactCollector::Prepare() and is otherwise in its |
607 // normal state. | 633 // normal state. |
608 // | 634 // |
609 // After: Live objects are marked and non-live objects are unmarked. | 635 // After: Live objects are marked and non-live objects are unmarked. |
610 | 636 |
611 | |
612 friend class RootMarkingVisitor; | 637 friend class RootMarkingVisitor; |
613 friend class MarkingVisitor; | 638 friend class MarkingVisitor; |
614 friend class StaticMarkingVisitor; | 639 friend class StaticMarkingVisitor; |
615 friend class CodeMarkingVisitor; | 640 friend class CodeMarkingVisitor; |
616 friend class SharedFunctionInfoMarkingVisitor; | 641 friend class SharedFunctionInfoMarkingVisitor; |
| 642 friend class Marker<IncrementalMarking>; |
| 643 friend class Marker<MarkCompactCollector>; |
617 | 644 |
618 // Mark non-optimize code for functions inlined into the given optimized | 645 // Mark non-optimize code for functions inlined into the given optimized |
619 // code. This will prevent it from being flushed. | 646 // code. This will prevent it from being flushed. |
620 void MarkInlinedFunctionsCode(Code* code); | 647 void MarkInlinedFunctionsCode(Code* code); |
621 | 648 |
622 // Mark code objects that are active on the stack to prevent them | 649 // Mark code objects that are active on the stack to prevent them |
623 // from being flushed. | 650 // from being flushed. |
624 void PrepareThreadForCodeFlushing(Isolate* isolate, ThreadLocalTop* top); | 651 void PrepareThreadForCodeFlushing(Isolate* isolate, ThreadLocalTop* top); |
625 | 652 |
626 void PrepareForCodeFlushing(); | 653 void PrepareForCodeFlushing(); |
627 | 654 |
628 // Marking operations for objects reachable from roots. | 655 // Marking operations for objects reachable from roots. |
629 void MarkLiveObjects(); | 656 void MarkLiveObjects(); |
630 | 657 |
631 void AfterMarking(); | 658 void AfterMarking(); |
632 | 659 |
633 // Marks the object black and pushes it on the marking stack. | 660 // Marks the object black and pushes it on the marking stack. |
634 // This is for non-incremental marking. | 661 // Returns true if object needed marking and false otherwise. |
| 662 // This is for non-incremental marking only. |
| 663 INLINE(bool MarkObjectAndPush(HeapObject* obj)); |
| 664 |
| 665 // Marks the object black and pushes it on the marking stack. |
| 666 // This is for non-incremental marking only. |
635 INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit)); | 667 INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit)); |
636 | 668 |
637 INLINE(bool MarkObjectWithoutPush(HeapObject* object)); | 669 // Marks the object black without pushing it on the marking stack. |
638 INLINE(void MarkObjectAndPush(HeapObject* value)); | 670 // Returns true if object needed marking and false otherwise. |
| 671 // This is for non-incremental marking only. |
| 672 INLINE(bool MarkObjectWithoutPush(HeapObject* obj)); |
639 | 673 |
640 // Marks the object black. This is for non-incremental marking. | 674 // Marks the object black assuming that it is not yet marked. |
| 675 // This is for non-incremental marking only. |
641 INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit)); | 676 INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit)); |
642 | 677 |
643 void ProcessNewlyMarkedObject(HeapObject* obj); | 678 void ProcessNewlyMarkedObject(HeapObject* obj); |
644 | 679 |
645 // Mark a Map and its DescriptorArray together, skipping transitions. | |
646 void MarkMapContents(Map* map); | |
647 void MarkAccessorPairSlot(HeapObject* accessors, int offset); | |
648 void MarkDescriptorArray(DescriptorArray* descriptors); | |
649 | |
650 // Mark the heap roots and all objects reachable from them. | 680 // Mark the heap roots and all objects reachable from them. |
651 void MarkRoots(RootMarkingVisitor* visitor); | 681 void MarkRoots(RootMarkingVisitor* visitor); |
652 | 682 |
653 // Mark the symbol table specially. References to symbols from the | 683 // Mark the symbol table specially. References to symbols from the |
654 // symbol table are weak. | 684 // symbol table are weak. |
655 void MarkSymbolTable(); | 685 void MarkSymbolTable(); |
656 | 686 |
657 // Mark objects in object groups that have at least one object in the | 687 // Mark objects in object groups that have at least one object in the |
658 // group marked. | 688 // group marked. |
659 void MarkObjectGroups(); | 689 void MarkObjectGroups(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 static void VisitObject(HeapObject* obj); | 772 static void VisitObject(HeapObject* obj); |
743 | 773 |
744 friend class UnmarkObjectVisitor; | 774 friend class UnmarkObjectVisitor; |
745 static void UnmarkObject(HeapObject* obj); | 775 static void UnmarkObject(HeapObject* obj); |
746 #endif | 776 #endif |
747 | 777 |
748 Heap* heap_; | 778 Heap* heap_; |
749 MarkingDeque marking_deque_; | 779 MarkingDeque marking_deque_; |
750 CodeFlusher* code_flusher_; | 780 CodeFlusher* code_flusher_; |
751 Object* encountered_weak_maps_; | 781 Object* encountered_weak_maps_; |
| 782 Marker<MarkCompactCollector> marker_; |
752 | 783 |
753 List<Page*> evacuation_candidates_; | 784 List<Page*> evacuation_candidates_; |
754 List<Code*> invalidated_code_; | 785 List<Code*> invalidated_code_; |
755 | 786 |
756 friend class Heap; | 787 friend class Heap; |
757 }; | 788 }; |
758 | 789 |
759 | 790 |
760 const char* AllocationSpaceName(AllocationSpace space); | 791 const char* AllocationSpaceName(AllocationSpace space); |
761 | 792 |
762 } } // namespace v8::internal | 793 } } // namespace v8::internal |
763 | 794 |
764 #endif // V8_MARK_COMPACT_H_ | 795 #endif // V8_MARK_COMPACT_H_ |
OLD | NEW |