8142402: G1 should not redirty cards in free regions
Reviewed-by: mgerdin, tschatzl
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Sun Nov 29 10:00:31 2015 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Apr 29 13:17:46 2015 +0200
@@ -112,18 +112,37 @@
class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure {
private:
- size_t _num_processed;
+ size_t _num_dirtied;
+ G1CollectedHeap* _g1h;
+ G1SATBCardTableLoggingModRefBS* _g1_bs;
+
+ HeapRegion* region_for_card(jbyte* card_ptr) const {
+ return _g1h->heap_region_containing(_g1_bs->addr_for(card_ptr));
+ }
+
+ bool will_become_free(HeapRegion* hr) const {
+ // A region will be freed by free_collection_set if the region is in the
+ // collection set and has not had an evacuation failure.
+ return _g1h->is_in_cset(hr) && !hr->evacuation_failed();
+ }
public:
- RedirtyLoggedCardTableEntryClosure() : CardTableEntryClosure(), _num_processed(0) { }
+ RedirtyLoggedCardTableEntryClosure(G1CollectedHeap* g1h) : CardTableEntryClosure(),
+ _num_dirtied(0), _g1h(g1h), _g1_bs(g1h->g1_barrier_set()) { }
bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
- *card_ptr = CardTableModRefBS::dirty_card_val();
- _num_processed++;
+ HeapRegion* hr = region_for_card(card_ptr);
+
+ // Should only dirty cards in regions that won't be freed.
+ if (!will_become_free(hr)) {
+ *card_ptr = CardTableModRefBS::dirty_card_val();
+ _num_dirtied++;
+ }
+
return true;
}
- size_t num_processed() const { return _num_processed; }
+ size_t num_dirtied() const { return _num_dirtied; }
};
@@ -4619,24 +4638,26 @@
class G1RedirtyLoggedCardsTask : public AbstractGangTask {
private:
DirtyCardQueueSet* _queue;
+ G1CollectedHeap* _g1h;
public:
- G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { }
+ G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue, G1CollectedHeap* g1h) : AbstractGangTask("Redirty Cards"),
+ _queue(queue), _g1h(g1h) { }
virtual void work(uint worker_id) {
- G1GCPhaseTimes* phase_times = G1CollectedHeap::heap()->g1_policy()->phase_times();
+ G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::RedirtyCards, worker_id);
- RedirtyLoggedCardTableEntryClosure cl;
+ RedirtyLoggedCardTableEntryClosure cl(_g1h);
_queue->par_apply_closure_to_all_completed_buffers(&cl);
- phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_processed());
+ phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_dirtied());
}
};
void G1CollectedHeap::redirty_logged_cards() {
double redirty_logged_cards_start = os::elapsedTime();
- G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set());
+ G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set(), this);
dirty_card_queue_set().reset_for_par_iteration();
workers()->run_task(&redirty_task);