25 #ifndef SHARE_GC_G1_G1PARSCANTHREADSTATE_HPP |
25 #ifndef SHARE_GC_G1_G1PARSCANTHREADSTATE_HPP |
26 #define SHARE_GC_G1_G1PARSCANTHREADSTATE_HPP |
26 #define SHARE_GC_G1_G1PARSCANTHREADSTATE_HPP |
27 |
27 |
28 #include "gc/g1/g1CardTable.hpp" |
28 #include "gc/g1/g1CardTable.hpp" |
29 #include "gc/g1/g1CollectedHeap.hpp" |
29 #include "gc/g1/g1CollectedHeap.hpp" |
30 #include "gc/g1/g1DirtyCardQueue.hpp" |
30 #include "gc/g1/g1RedirtyCardsQueue.hpp" |
31 #include "gc/g1/g1OopClosures.hpp" |
31 #include "gc/g1/g1OopClosures.hpp" |
32 #include "gc/g1/g1Policy.hpp" |
32 #include "gc/g1/g1Policy.hpp" |
33 #include "gc/g1/g1RemSet.hpp" |
33 #include "gc/g1/g1RemSet.hpp" |
34 #include "gc/g1/heapRegionRemSet.hpp" |
34 #include "gc/g1/heapRegionRemSet.hpp" |
35 #include "gc/shared/ageTable.hpp" |
35 #include "gc/shared/ageTable.hpp" |
44 class outputStream; |
44 class outputStream; |
45 |
45 |
46 class G1ParScanThreadState : public CHeapObj<mtGC> { |
46 class G1ParScanThreadState : public CHeapObj<mtGC> { |
47 G1CollectedHeap* _g1h; |
47 G1CollectedHeap* _g1h; |
48 RefToScanQueue* _refs; |
48 RefToScanQueue* _refs; |
49 G1DirtyCardQueue _dcq; |
49 G1RedirtyCardsQueue _rdcq; |
50 G1CardTable* _ct; |
50 G1CardTable* _ct; |
51 G1EvacuationRootClosures* _closures; |
51 G1EvacuationRootClosures* _closures; |
52 |
52 |
53 G1PLABAllocator* _plab_allocator; |
53 G1PLABAllocator* _plab_allocator; |
54 |
54 |
57 // Local tenuring threshold. |
57 // Local tenuring threshold. |
58 uint _tenuring_threshold; |
58 uint _tenuring_threshold; |
59 G1ScanEvacuatedObjClosure _scanner; |
59 G1ScanEvacuatedObjClosure _scanner; |
60 |
60 |
61 uint _worker_id; |
61 uint _worker_id; |
|
62 |
|
63 // Remember the last enqueued card to avoid enqueuing the same card over and over; |
|
64 // since we only ever scan a card once, this is sufficient. |
|
65 size_t _last_enqueued_card; |
62 |
66 |
63 // Upper and lower threshold to start and end work queue draining. |
67 // Upper and lower threshold to start and end work queue draining. |
64 uint const _stack_trim_upper_threshold; |
68 uint const _stack_trim_upper_threshold; |
65 uint const _stack_trim_lower_threshold; |
69 uint const _stack_trim_lower_threshold; |
66 |
70 |
75 // available for allocation. |
79 // available for allocation. |
76 bool _old_gen_is_full; |
80 bool _old_gen_is_full; |
77 |
81 |
78 #define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t)) |
82 #define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t)) |
79 |
83 |
80 G1DirtyCardQueue& dirty_card_queue() { return _dcq; } |
84 G1RedirtyCardsQueue& redirty_cards_queue() { return _rdcq; } |
81 G1CardTable* ct() { return _ct; } |
85 G1CardTable* ct() { return _ct; } |
82 |
86 |
83 G1HeapRegionAttr dest(G1HeapRegionAttr original) const { |
87 G1HeapRegionAttr dest(G1HeapRegionAttr original) const { |
84 assert(original.is_valid(), |
88 assert(original.is_valid(), |
85 "Original region attr invalid: %s", original.get_type_str()); |
89 "Original region attr invalid: %s", original.get_type_str()); |
91 size_t _num_optional_regions; |
95 size_t _num_optional_regions; |
92 G1OopStarChunkedList* _oops_into_optional_regions; |
96 G1OopStarChunkedList* _oops_into_optional_regions; |
93 |
97 |
94 public: |
98 public: |
95 G1ParScanThreadState(G1CollectedHeap* g1h, |
99 G1ParScanThreadState(G1CollectedHeap* g1h, |
|
100 G1RedirtyCardsQueueSet* rdcqs, |
96 uint worker_id, |
101 uint worker_id, |
97 size_t young_cset_length, |
102 size_t young_cset_length, |
98 size_t optional_cset_length); |
103 size_t optional_cset_length); |
99 virtual ~G1ParScanThreadState(); |
104 virtual ~G1ParScanThreadState(); |
100 |
105 |
126 if (!region_attr.needs_remset_update()) { |
131 if (!region_attr.needs_remset_update()) { |
127 return; |
132 return; |
128 } |
133 } |
129 size_t card_index = ct()->index_for(p); |
134 size_t card_index = ct()->index_for(p); |
130 // If the card hasn't been added to the buffer, do it. |
135 // If the card hasn't been added to the buffer, do it. |
131 if (ct()->mark_card_deferred(card_index)) { |
136 if (_last_enqueued_card != card_index) { |
132 dirty_card_queue().enqueue(ct()->byte_for_index(card_index)); |
137 redirty_cards_queue().enqueue(ct()->byte_for_index(card_index)); |
|
138 _last_enqueued_card = card_index; |
133 } |
139 } |
134 } |
140 } |
135 |
141 |
136 G1EvacuationRootClosures* closures() { return _closures; } |
142 G1EvacuationRootClosures* closures() { return _closures; } |
137 uint worker_id() { return _worker_id; } |
143 uint worker_id() { return _worker_id; } |
138 |
144 |
139 size_t lab_waste_words() const; |
145 size_t lab_waste_words() const; |
140 size_t lab_undo_waste_words() const; |
146 size_t lab_undo_waste_words() const; |
141 |
|
142 size_t* surviving_young_words() { |
|
143 // We add one to hide entry 0 which accumulates surviving words for |
|
144 // age -1 regions (i.e. non-young ones) |
|
145 return _surviving_young_words + 1; |
|
146 } |
|
147 |
147 |
148 void flush(size_t* surviving_young_words); |
148 void flush(size_t* surviving_young_words); |
149 |
149 |
150 private: |
150 private: |
151 #define G1_PARTIAL_ARRAY_MASK 0x2 |
151 #define G1_PARTIAL_ARRAY_MASK 0x2 |
196 HeapWord* allocate_in_next_plab(G1HeapRegionAttr const region_attr, |
196 HeapWord* allocate_in_next_plab(G1HeapRegionAttr const region_attr, |
197 G1HeapRegionAttr* dest, |
197 G1HeapRegionAttr* dest, |
198 size_t word_sz, |
198 size_t word_sz, |
199 bool previous_plab_refill_failed); |
199 bool previous_plab_refill_failed); |
200 |
200 |
201 inline G1HeapRegionAttr next_region_attr(G1HeapRegionAttr const region_attr, markOop const m, uint& age); |
201 inline G1HeapRegionAttr next_region_attr(G1HeapRegionAttr const region_attr, markWord const m, uint& age); |
202 |
202 |
203 void report_promotion_event(G1HeapRegionAttr const dest_attr, |
203 void report_promotion_event(G1HeapRegionAttr const dest_attr, |
204 oop const old, size_t word_sz, uint age, |
204 oop const old, size_t word_sz, uint age, |
205 HeapWord * const obj_ptr) const; |
205 HeapWord * const obj_ptr) const; |
206 |
206 |
207 inline bool needs_partial_trimming() const; |
207 inline bool needs_partial_trimming() const; |
208 inline bool is_partially_trimmed() const; |
208 inline bool is_partially_trimmed() const; |
209 |
209 |
210 inline void trim_queue_to_threshold(uint threshold); |
210 inline void trim_queue_to_threshold(uint threshold); |
211 public: |
211 public: |
212 oop copy_to_survivor_space(G1HeapRegionAttr const region_attr, oop const obj, markOop const old_mark); |
212 oop copy_to_survivor_space(G1HeapRegionAttr const region_attr, oop const obj, markWord const old_mark); |
213 |
213 |
214 void trim_queue(); |
214 void trim_queue(); |
215 void trim_queue_partially(); |
215 void trim_queue_partially(); |
216 |
216 |
217 Tickspan trim_ticks() const; |
217 Tickspan trim_ticks() const; |
218 void reset_trim_ticks(); |
218 void reset_trim_ticks(); |
219 |
219 |
220 inline void steal_and_trim_queue(RefToScanQueueSet *task_queues); |
220 inline void steal_and_trim_queue(RefToScanQueueSet *task_queues); |
221 |
221 |
222 // An attempt to evacuate "obj" has failed; take necessary steps. |
222 // An attempt to evacuate "obj" has failed; take necessary steps. |
223 oop handle_evacuation_failure_par(oop obj, markOop m); |
223 oop handle_evacuation_failure_par(oop obj, markWord m); |
224 |
224 |
225 template <typename T> |
225 template <typename T> |
226 inline void remember_root_into_optional_region(T* p); |
226 inline void remember_root_into_optional_region(T* p); |
227 template <typename T> |
227 template <typename T> |
228 inline void remember_reference_into_optional_region(T* p); |
228 inline void remember_reference_into_optional_region(T* p); |
230 inline G1OopStarChunkedList* oops_into_optional_region(const HeapRegion* hr); |
230 inline G1OopStarChunkedList* oops_into_optional_region(const HeapRegion* hr); |
231 }; |
231 }; |
232 |
232 |
233 class G1ParScanThreadStateSet : public StackObj { |
233 class G1ParScanThreadStateSet : public StackObj { |
234 G1CollectedHeap* _g1h; |
234 G1CollectedHeap* _g1h; |
|
235 G1RedirtyCardsQueueSet* _rdcqs; |
235 G1ParScanThreadState** _states; |
236 G1ParScanThreadState** _states; |
236 size_t* _surviving_young_words_total; |
237 size_t* _surviving_young_words_total; |
237 size_t _young_cset_length; |
238 size_t _young_cset_length; |
238 size_t _optional_cset_length; |
239 size_t _optional_cset_length; |
239 uint _n_workers; |
240 uint _n_workers; |
240 bool _flushed; |
241 bool _flushed; |
241 |
242 |
242 public: |
243 public: |
243 G1ParScanThreadStateSet(G1CollectedHeap* g1h, |
244 G1ParScanThreadStateSet(G1CollectedHeap* g1h, |
|
245 G1RedirtyCardsQueueSet* rdcqs, |
244 uint n_workers, |
246 uint n_workers, |
245 size_t young_cset_length, |
247 size_t young_cset_length, |
246 size_t optional_cset_length); |
248 size_t optional_cset_length); |
247 ~G1ParScanThreadStateSet(); |
249 ~G1ParScanThreadStateSet(); |
248 |
250 |