25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP |
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP |
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP |
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_HPP |
27 |
27 |
28 #include "classfile/javaClasses.hpp" |
28 #include "classfile/javaClasses.hpp" |
29 #include "gc_implementation/g1/heapRegionSet.hpp" |
29 #include "gc_implementation/g1/heapRegionSet.hpp" |
|
30 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" |
30 #include "gc_implementation/shared/gcId.hpp" |
31 #include "gc_implementation/shared/gcId.hpp" |
31 #include "utilities/taskqueue.hpp" |
32 #include "utilities/taskqueue.hpp" |
32 |
33 |
33 class G1CollectedHeap; |
34 class G1CollectedHeap; |
|
35 class CMBitMap; |
34 class CMTask; |
36 class CMTask; |
35 typedef GenericTaskQueue<oop, mtGC> CMTaskQueue; |
37 typedef GenericTaskQueue<oop, mtGC> CMTaskQueue; |
36 typedef GenericTaskQueueSet<CMTaskQueue, mtGC> CMTaskQueueSet; |
38 typedef GenericTaskQueueSet<CMTaskQueue, mtGC> CMTaskQueueSet; |
37 |
39 |
38 // Closure used by CM during concurrent reference discovery |
40 // Closure used by CM during concurrent reference discovery |
113 } |
114 } |
114 |
115 |
115 void print_on_error(outputStream* st, const char* prefix) const; |
116 void print_on_error(outputStream* st, const char* prefix) const; |
116 |
117 |
117 // debugging |
118 // debugging |
118 NOT_PRODUCT(bool covers(ReservedSpace rs) const;) |
119 NOT_PRODUCT(bool covers(MemRegion rs) const;) |
119 }; |
120 }; |
120 |
121 |
|
122 class CMBitMapMappingChangedListener : public G1MappingChangedListener { |
|
123 private: |
|
124 CMBitMap* _bm; |
|
125 public: |
|
126 CMBitMapMappingChangedListener() : _bm(NULL) {} |
|
127 |
|
128 void set_bitmap(CMBitMap* bm) { _bm = bm; } |
|
129 |
|
130 virtual void on_commit(uint start_idx, size_t num_regions); |
|
131 }; |
|
132 |
121 class CMBitMap : public CMBitMapRO { |
133 class CMBitMap : public CMBitMapRO { |
|
134 private: |
|
135 CMBitMapMappingChangedListener _listener; |
122 |
136 |
123 public: |
137 public: |
124 // constructor |
138 static size_t compute_size(size_t heap_size); |
125 CMBitMap(int shifter) : |
139 // Returns the amount of bytes on the heap between two marks in the bitmap. |
126 CMBitMapRO(shifter) {} |
140 static size_t mark_distance(); |
127 |
141 |
128 // Allocates the back store for the marking bitmap |
142 CMBitMap() : CMBitMapRO(LogMinObjAlignment), _listener() { _listener.set_bitmap(this); } |
129 bool allocate(ReservedSpace heap_rs); |
143 |
130 |
144 // Initializes the underlying BitMap to cover the given area. |
131 // write marks |
145 void initialize(MemRegion heap, G1RegionToSpaceMapper* storage); |
132 void mark(HeapWord* addr) { |
146 |
133 assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize), |
147 // Write marks. |
134 "outside underlying space?"); |
148 inline void mark(HeapWord* addr); |
135 _bm.set_bit(heapWordToOffset(addr)); |
149 inline void clear(HeapWord* addr); |
136 } |
150 inline bool parMark(HeapWord* addr); |
137 void clear(HeapWord* addr) { |
151 inline bool parClear(HeapWord* addr); |
138 assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize), |
152 |
139 "outside underlying space?"); |
|
140 _bm.clear_bit(heapWordToOffset(addr)); |
|
141 } |
|
142 bool parMark(HeapWord* addr) { |
|
143 assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize), |
|
144 "outside underlying space?"); |
|
145 return _bm.par_set_bit(heapWordToOffset(addr)); |
|
146 } |
|
147 bool parClear(HeapWord* addr) { |
|
148 assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize), |
|
149 "outside underlying space?"); |
|
150 return _bm.par_clear_bit(heapWordToOffset(addr)); |
|
151 } |
|
152 void markRange(MemRegion mr); |
153 void markRange(MemRegion mr); |
153 void clearAll(); |
|
154 void clearRange(MemRegion mr); |
154 void clearRange(MemRegion mr); |
155 |
155 |
156 // Starting at the bit corresponding to "addr" (inclusive), find the next |
156 // Starting at the bit corresponding to "addr" (inclusive), find the next |
157 // "1" bit, if any. This bit starts some run of consecutive "1"'s; find |
157 // "1" bit, if any. This bit starts some run of consecutive "1"'s; find |
158 // the end of this run (stopping at "end_addr"). Return the MemRegion |
158 // the end of this run (stopping at "end_addr"). Return the MemRegion |
159 // covering from the start of the region corresponding to the first bit |
159 // covering from the start of the region corresponding to the first bit |
160 // of the run to the end of the region corresponding to the last bit of |
160 // of the run to the end of the region corresponding to the last bit of |
161 // the run. If there is no "1" bit at or after "addr", return an empty |
161 // the run. If there is no "1" bit at or after "addr", return an empty |
162 // MemRegion. |
162 // MemRegion. |
163 MemRegion getAndClearMarkedRegion(HeapWord* addr, HeapWord* end_addr); |
163 MemRegion getAndClearMarkedRegion(HeapWord* addr, HeapWord* end_addr); |
|
164 |
|
165 // Clear the whole mark bitmap. |
|
166 void clearAll(); |
164 }; |
167 }; |
165 |
168 |
166 // Represents a marking stack used by ConcurrentMarking in the G1 collector. |
169 // Represents a marking stack used by ConcurrentMarking in the G1 collector. |
167 class CMMarkStack VALUE_OBJ_CLASS_SPEC { |
170 class CMMarkStack VALUE_OBJ_CLASS_SPEC { |
168 VirtualSpace _virtual_space; // Underlying backing store for actual stack |
171 VirtualSpace _virtual_space; // Underlying backing store for actual stack |
678 // Attempts to steal an object from the task queues of other tasks |
681 // Attempts to steal an object from the task queues of other tasks |
679 bool try_stealing(uint worker_id, int* hash_seed, oop& obj) { |
682 bool try_stealing(uint worker_id, int* hash_seed, oop& obj) { |
680 return _task_queues->steal(worker_id, hash_seed, obj); |
683 return _task_queues->steal(worker_id, hash_seed, obj); |
681 } |
684 } |
682 |
685 |
683 ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs); |
686 ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev_bitmap_storage, G1RegionToSpaceMapper* next_bitmap_storage); |
684 ~ConcurrentMark(); |
687 ~ConcurrentMark(); |
685 |
688 |
686 ConcurrentMarkThread* cmThread() { return _cmThread; } |
689 ConcurrentMarkThread* cmThread() { return _cmThread; } |
687 |
690 |
688 CMBitMapRO* prevMarkBitMap() const { return _prevMarkBitMap; } |
691 CMBitMapRO* prevMarkBitMap() const { return _prevMarkBitMap; } |
734 VerifyOption vo, bool all) PRODUCT_RETURN; |
737 VerifyOption vo, bool all) PRODUCT_RETURN; |
735 |
738 |
736 // Clear the next marking bitmap (will be called concurrently). |
739 // Clear the next marking bitmap (will be called concurrently). |
737 void clearNextBitmap(); |
740 void clearNextBitmap(); |
738 |
741 |
739 // Return whether the next mark bitmap has no marks set. |
742 // Return whether the next mark bitmap has no marks set. To be used for assertions |
|
743 // only. Will not yield to pause requests. |
740 bool nextMarkBitmapIsClear(); |
744 bool nextMarkBitmapIsClear(); |
741 |
745 |
742 // These two do the work that needs to be done before and after the |
746 // These two do the work that needs to be done before and after the |
743 // initial root checkpoint. Since this checkpoint can be done at two |
747 // initial root checkpoint. Since this checkpoint can be done at two |
744 // different points (i.e. an explicit pause or piggy-backed on a |
748 // different points (i.e. an explicit pause or piggy-backed on a |
791 // is not in progress, it's a no-op. |
795 // is not in progress, it's a no-op. |
792 void verify_no_cset_oops(bool verify_stacks, |
796 void verify_no_cset_oops(bool verify_stacks, |
793 bool verify_enqueued_buffers, |
797 bool verify_enqueued_buffers, |
794 bool verify_thread_buffers, |
798 bool verify_thread_buffers, |
795 bool verify_fingers) PRODUCT_RETURN; |
799 bool verify_fingers) PRODUCT_RETURN; |
796 |
|
797 // It is called at the end of an evacuation pause during marking so |
|
798 // that CM is notified of where the new end of the heap is. It |
|
799 // doesn't do anything if concurrent_marking_in_progress() is false, |
|
800 // unless the force parameter is true. |
|
801 void update_heap_boundaries(MemRegion bounds, bool force = false); |
|
802 |
800 |
803 bool isMarked(oop p) const { |
801 bool isMarked(oop p) const { |
804 assert(p != NULL && p->is_oop(), "expected an oop"); |
802 assert(p != NULL && p->is_oop(), "expected an oop"); |
805 HeapWord* addr = (HeapWord*)p; |
803 HeapWord* addr = (HeapWord*)p; |
806 assert(addr >= _nextMarkBitMap->startWord() || |
804 assert(addr >= _nextMarkBitMap->startWord() || |