110 }; |
110 }; |
111 |
111 |
112 |
112 |
113 class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure { |
113 class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure { |
114 private: |
114 private: |
115 size_t _num_processed; |
115 size_t _num_dirtied; |
|
116 G1CollectedHeap* _g1h; |
|
117 G1SATBCardTableLoggingModRefBS* _g1_bs; |
|
118 |
|
119 HeapRegion* region_for_card(jbyte* card_ptr) const { |
|
120 return _g1h->heap_region_containing(_g1_bs->addr_for(card_ptr)); |
|
121 } |
|
122 |
|
123 bool will_become_free(HeapRegion* hr) const { |
|
124 // A region will be freed by free_collection_set if the region is in the |
|
125 // collection set and has not had an evacuation failure. |
|
126 return _g1h->is_in_cset(hr) && !hr->evacuation_failed(); |
|
127 } |
116 |
128 |
117 public: |
129 public: |
118 RedirtyLoggedCardTableEntryClosure() : CardTableEntryClosure(), _num_processed(0) { } |
130 RedirtyLoggedCardTableEntryClosure(G1CollectedHeap* g1h) : CardTableEntryClosure(), |
|
131 _num_dirtied(0), _g1h(g1h), _g1_bs(g1h->g1_barrier_set()) { } |
119 |
132 |
120 bool do_card_ptr(jbyte* card_ptr, uint worker_i) { |
133 bool do_card_ptr(jbyte* card_ptr, uint worker_i) { |
121 *card_ptr = CardTableModRefBS::dirty_card_val(); |
134 HeapRegion* hr = region_for_card(card_ptr); |
122 _num_processed++; |
135 |
|
136 // Should only dirty cards in regions that won't be freed. |
|
137 if (!will_become_free(hr)) { |
|
138 *card_ptr = CardTableModRefBS::dirty_card_val(); |
|
139 _num_dirtied++; |
|
140 } |
|
141 |
123 return true; |
142 return true; |
124 } |
143 } |
125 |
144 |
126 size_t num_processed() const { return _num_processed; } |
145 size_t num_dirtied() const { return _num_dirtied; } |
127 }; |
146 }; |
128 |
147 |
129 |
148 |
130 void G1RegionMappingChangedListener::reset_from_card_cache(uint start_idx, size_t num_regions) { |
149 void G1RegionMappingChangedListener::reset_from_card_cache(uint start_idx, size_t num_regions) { |
131 HeapRegionRemSet::invalidate_from_card_cache(start_idx, num_regions); |
150 HeapRegionRemSet::invalidate_from_card_cache(start_idx, num_regions); |
4617 } |
4636 } |
4618 |
4637 |
4619 class G1RedirtyLoggedCardsTask : public AbstractGangTask { |
4638 class G1RedirtyLoggedCardsTask : public AbstractGangTask { |
4620 private: |
4639 private: |
4621 DirtyCardQueueSet* _queue; |
4640 DirtyCardQueueSet* _queue; |
|
4641 G1CollectedHeap* _g1h; |
4622 public: |
4642 public: |
4623 G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { } |
4643 G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue, G1CollectedHeap* g1h) : AbstractGangTask("Redirty Cards"), |
|
4644 _queue(queue), _g1h(g1h) { } |
4624 |
4645 |
4625 virtual void work(uint worker_id) { |
4646 virtual void work(uint worker_id) { |
4626 G1GCPhaseTimes* phase_times = G1CollectedHeap::heap()->g1_policy()->phase_times(); |
4647 G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times(); |
4627 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::RedirtyCards, worker_id); |
4648 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::RedirtyCards, worker_id); |
4628 |
4649 |
4629 RedirtyLoggedCardTableEntryClosure cl; |
4650 RedirtyLoggedCardTableEntryClosure cl(_g1h); |
4630 _queue->par_apply_closure_to_all_completed_buffers(&cl); |
4651 _queue->par_apply_closure_to_all_completed_buffers(&cl); |
4631 |
4652 |
4632 phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_processed()); |
4653 phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_dirtied()); |
4633 } |
4654 } |
4634 }; |
4655 }; |
4635 |
4656 |
4636 void G1CollectedHeap::redirty_logged_cards() { |
4657 void G1CollectedHeap::redirty_logged_cards() { |
4637 double redirty_logged_cards_start = os::elapsedTime(); |
4658 double redirty_logged_cards_start = os::elapsedTime(); |
4638 |
4659 |
4639 G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set()); |
4660 G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set(), this); |
4640 dirty_card_queue_set().reset_for_par_iteration(); |
4661 dirty_card_queue_set().reset_for_par_iteration(); |
4641 workers()->run_task(&redirty_task); |
4662 workers()->run_task(&redirty_task); |
4642 |
4663 |
4643 DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set(); |
4664 DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set(); |
4644 dcq.merge_bufferlists(&dirty_card_queue_set()); |
4665 dcq.merge_bufferlists(&dirty_card_queue_set()); |