< prev index next >

src/share/vm/gc/g1/g1CollectedHeap.cpp

Print this page
rev 9312 : 8139424: SIGSEGV, Problematic frame: # V [libjvm.so+0xd0c0cc] void InstanceKlass::oop_oop_iterate_oop_maps_specialized<true,oopDesc*,MarkAndPushClosure>
Summary: The crash was caused by a faulty eager humongous reclaim. The reason for reclaiming a live obejct was that the call to cleanupHRRS was done after dirtying cards and clearing the remembered sets for the humongous object. This could lead to one or many cards being missed.
Reviewed-by:


3544       // re-evaluation of their remembered set entries during the following evacuation
3545       // phase.
3546       if (!r->rem_set()->is_empty()) {
3547         guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries),
3548                   "Found a not-small remembered set here. This is inconsistent with previous assumptions.");
3549         G1SATBCardTableLoggingModRefBS* bs = g1h->g1_barrier_set();
3550         HeapRegionRemSetIterator hrrs(r->rem_set());
3551         size_t card_index;
3552         while (hrrs.has_next(card_index)) {
3553           jbyte* card_ptr = (jbyte*)bs->byte_for_index(card_index);
3554           // The remembered set might contain references to already freed
3555           // regions. Filter out such entries to avoid failing card table
3556           // verification.
3557           if (g1h->is_in_closed_subset(bs->addr_for(card_ptr))) {
3558             if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
3559               *card_ptr = CardTableModRefBS::dirty_card_val();
3560               _dcq.enqueue(card_ptr);
3561             }
3562           }
3563         }



3564         r->rem_set()->clear_locked();
3565       }
3566       assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
3567     }
3568     _total_humongous++;
3569 
3570     return false;
3571   }
3572 
3573   size_t total_humongous() const { return _total_humongous; }
3574   size_t candidate_humongous() const { return _candidate_humongous; }
3575 
3576   void flush_rem_set_entries() { _dcq.flush(); }
3577 };
3578 
3579 void G1CollectedHeap::register_humongous_regions_with_cset() {
3580   if (!G1EagerReclaimHumongousObjects) {
3581     g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(0.0, 0, 0);
3582     return;
3583   }


3830         // This timing is only used by the ergonomics to handle our pause target.
3831         // It is unclear why this should not include the full pause. We will
3832         // investigate this in CR 7178365.
3833         //
3834         // Preserving the old comment here if that helps the investigation:
3835         //
3836         // The elapsed time induced by the start time below deliberately elides
3837         // the possible verification above.
3838         double sample_start_time_sec = os::elapsedTime();
3839 
3840         g1_policy()->record_collection_pause_start(sample_start_time_sec);
3841 
3842         if (collector_state()->during_initial_mark_pause()) {
3843           concurrent_mark()->checkpointRootsInitialPre();
3844         }
3845 
3846         double time_remaining_ms = g1_policy()->finalize_young_cset_part(target_pause_time_ms);
3847         g1_policy()->finalize_old_cset_part(time_remaining_ms);
3848 
3849         evacuation_info.set_collectionset_regions(g1_policy()->cset_region_length());





3850 
3851         register_humongous_regions_with_cset();
3852 
3853         assert(check_cset_fast_test(), "Inconsistency in the InCSetState table.");
3854 
3855         _cm->note_start_of_gc();
3856         // We call this after finalize_cset() to
3857         // ensure that the CSet has been finalized.
3858         _cm->verify_no_cset_oops();
3859 
3860         if (_hr_printer.is_active()) {
3861           HeapRegion* hr = g1_policy()->collection_set();
3862           while (hr != NULL) {
3863             _hr_printer.cset(hr);
3864             hr = hr->next_in_collection_set();
3865           }
3866         }
3867 
3868 #ifdef ASSERT
3869         VerifyCSetClosure cl;




3544       // re-evaluation of their remembered set entries during the following evacuation
3545       // phase.
3546       if (!r->rem_set()->is_empty()) {
3547         guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries),
3548                   "Found a not-small remembered set here. This is inconsistent with previous assumptions.");
3549         G1SATBCardTableLoggingModRefBS* bs = g1h->g1_barrier_set();
3550         HeapRegionRemSetIterator hrrs(r->rem_set());
3551         size_t card_index;
3552         while (hrrs.has_next(card_index)) {
3553           jbyte* card_ptr = (jbyte*)bs->byte_for_index(card_index);
3554           // The remembered set might contain references to already freed
3555           // regions. Filter out such entries to avoid failing card table
3556           // verification.
3557           if (g1h->is_in_closed_subset(bs->addr_for(card_ptr))) {
3558             if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
3559               *card_ptr = CardTableModRefBS::dirty_card_val();
3560               _dcq.enqueue(card_ptr);
3561             }
3562           }
3563         }
3564         guarantee(r->rem_set()->occupied() == hrrs.n_yielded(),
3565                   "All entries should have been handled, occupied: " SIZE_FORMAT " n_yielded: " SIZE_FORMAT,
3566                   r->rem_set()->occupied(), hrrs.n_yielded());
3567         r->rem_set()->clear_locked();
3568       }
3569       assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
3570     }
3571     _total_humongous++;
3572 
3573     return false;
3574   }
3575 
3576   size_t total_humongous() const { return _total_humongous; }
3577   size_t candidate_humongous() const { return _candidate_humongous; }
3578 
3579   void flush_rem_set_entries() { _dcq.flush(); }
3580 };
3581 
3582 void G1CollectedHeap::register_humongous_regions_with_cset() {
3583   if (!G1EagerReclaimHumongousObjects) {
3584     g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(0.0, 0, 0);
3585     return;
3586   }


3833         // This timing is only used by the ergonomics to handle our pause target.
3834         // It is unclear why this should not include the full pause. We will
3835         // investigate this in CR 7178365.
3836         //
3837         // Preserving the old comment here if that helps the investigation:
3838         //
3839         // The elapsed time induced by the start time below deliberately elides
3840         // the possible verification above.
3841         double sample_start_time_sec = os::elapsedTime();
3842 
3843         g1_policy()->record_collection_pause_start(sample_start_time_sec);
3844 
3845         if (collector_state()->during_initial_mark_pause()) {
3846           concurrent_mark()->checkpointRootsInitialPre();
3847         }
3848 
3849         double time_remaining_ms = g1_policy()->finalize_young_cset_part(target_pause_time_ms);
3850         g1_policy()->finalize_old_cset_part(time_remaining_ms);
3851 
3852         evacuation_info.set_collectionset_regions(g1_policy()->cset_region_length());
3853 
3854         // Make sure the remembered sets are up to date. This needs to be
3855         // done before register_humongous_regions_with_cset(), otherwise
3856         // we might miss some entries that needs to be handled.
3857         g1_rem_set()->cleanupHRRS();
3858 
3859         register_humongous_regions_with_cset();
3860 
3861         assert(check_cset_fast_test(), "Inconsistency in the InCSetState table.");
3862 
3863         _cm->note_start_of_gc();
3864         // We call this after finalize_cset() to
3865         // ensure that the CSet has been finalized.
3866         _cm->verify_no_cset_oops();
3867 
3868         if (_hr_printer.is_active()) {
3869           HeapRegion* hr = g1_policy()->collection_set();
3870           while (hr != NULL) {
3871             _hr_printer.cset(hr);
3872             hr = hr->next_in_collection_set();
3873           }
3874         }
3875 
3876 #ifdef ASSERT
3877         VerifyCSetClosure cl;


< prev index next >