# HG changeset patch # User ehelin # Date 1430306266 -7200 # Node ID bb8d0781175e231aa9b8d9f25a4513cb5b1029d6 # Parent ed475e8089ef43a11cc065b4b5aab4dd1f8df16f 8142402: G1 should not redirty cards in free regions Reviewed-by: mgerdin, tschatzl diff -r ed475e8089ef -r bb8d0781175e hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp --- 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);