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

Print this page
rev 5920 : 8035406: Improve data structure for Code Cache remembered sets
Summary: Change the code cache remembered sets data structure from a GrowableArray to a chunked list of nmethods. This makes the data structure more amenable to parallelization, and decreases freeing time.
Reviewed-by:


5887     G1STWIsAliveClosure is_alive(this);
5888     G1KeepAliveClosure keep_alive(this);
5889     JNIHandles::weak_oops_do(&is_alive, &keep_alive);
5890   }
5891 
5892   release_gc_alloc_regions(n_workers, evacuation_info);
5893   g1_rem_set()->cleanup_after_oops_into_collection_set_do();
5894 
5895   // Reset and re-enable the hot card cache.
5896   // Note the counts for the cards in the regions in the
5897   // collection set are reset when the collection set is freed.
5898   hot_card_cache->reset_hot_cache();
5899   hot_card_cache->set_use_cache(true);
5900 
5901   // Migrate the strong code roots attached to each region in
5902   // the collection set. Ideally we would like to do this
5903   // after we have finished the scanning/evacuation of the
5904   // strong code roots for a particular heap region.
5905   migrate_strong_code_roots();
5906 


5907   if (g1_policy()->during_initial_mark_pause()) {
5908     // Reset the claim values set during marking the strong code roots
5909     reset_heap_region_claim_values();
5910   }
5911 
5912   finalize_for_evac_failure();
5913 
5914   if (evacuation_failed()) {
5915     remove_self_forwarding_pointers();
5916 
5917     // Reset the G1EvacuationFailureALot counters and flags
5918     // Note: the values are reset only when an actual
5919     // evacuation failure occurs.
5920     NOT_PRODUCT(reset_evacuation_should_fail();)
5921   }
5922 
5923   // Enqueue any remaining references remaining on the STW
5924   // reference processor's discovered lists. We need to do
5925   // this after the card table is cleaned (and verified) as
5926   // the act of enqueueing entries on to the pending list


6791 
6792 class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure {
6793 public:
6794   bool doHeapRegion(HeapRegion *hr) {
6795     assert(!hr->isHumongous(),
6796            err_msg("humongous region "HR_FORMAT" should not have been added to collection set",
6797                    HR_FORMAT_PARAMS(hr)));
6798     hr->migrate_strong_code_roots();
6799     return false;
6800   }
6801 };
6802 
6803 void G1CollectedHeap::migrate_strong_code_roots() {
6804   MigrateCodeRootsHeapRegionClosure cl;
6805   double migrate_start = os::elapsedTime();
6806   collection_set_iterate(&cl);
6807   double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0;
6808   g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms);
6809 }
6810 







6811 // Mark all the code roots that point into regions *not* in the
6812 // collection set.
6813 //
6814 // Note we do not want to use a "marking" CodeBlobToOopClosure while
6815 // walking the the code roots lists of regions not in the collection
6816 // set. Suppose we have an nmethod (M) that points to objects in two
6817 // separate regions - one in the collection set (R1) and one not (R2).
6818 // Using a "marking" CodeBlobToOopClosure here would result in "marking"
6819 // nmethod M when walking the code roots for R1. When we come to scan
6820 // the code roots for R2, we would see that M is already marked and it
6821 // would be skipped and the objects in R2 that are referenced from M
6822 // would not be evacuated.
6823 
6824 class MarkStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
6825 
6826   class MarkStrongCodeRootOopClosure: public OopClosure {
6827     ConcurrentMark* _cm;
6828     HeapRegion* _hr;
6829     uint _worker_id;
6830 


6861     if (nm != NULL) {
6862       nm->oops_do(&_oop_cl);
6863     }
6864   }
6865 };
6866 
6867 class MarkStrongCodeRootsHRClosure: public HeapRegionClosure {
6868   G1CollectedHeap* _g1h;
6869   uint _worker_id;
6870 
6871 public:
6872   MarkStrongCodeRootsHRClosure(G1CollectedHeap* g1h, uint worker_id) :
6873     _g1h(g1h), _worker_id(worker_id) {}
6874 
6875   bool doHeapRegion(HeapRegion *hr) {
6876     HeapRegionRemSet* hrrs = hr->rem_set();
6877     if (hr->continuesHumongous()) {
6878       // Code roots should never be attached to a continuation of a humongous region
6879       assert(hrrs->strong_code_roots_list_length() == 0,
6880              err_msg("code roots should never be attached to continuations of humongous region "HR_FORMAT
6881                      " starting at "HR_FORMAT", but has "INT32_FORMAT,
6882                      HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()),
6883                      hrrs->strong_code_roots_list_length()));
6884       return false;
6885     }
6886 
6887     if (hr->in_collection_set()) {
6888       // Don't mark code roots into regions in the collection set here.
6889       // They will be marked when we scan them.
6890       return false;
6891     }
6892 
6893     MarkStrongCodeRootCodeBlobClosure cb_cl(_g1h->concurrent_mark(), hr, _worker_id);
6894     hr->strong_code_roots_do(&cb_cl);
6895     return false;
6896   }
6897 };
6898 
6899 void G1CollectedHeap::mark_strong_code_roots(uint worker_id) {
6900   MarkStrongCodeRootsHRClosure cl(this, worker_id);
6901   if (G1CollectedHeap::use_parallel_gc_threads()) {




5887     G1STWIsAliveClosure is_alive(this);
5888     G1KeepAliveClosure keep_alive(this);
5889     JNIHandles::weak_oops_do(&is_alive, &keep_alive);
5890   }
5891 
5892   release_gc_alloc_regions(n_workers, evacuation_info);
5893   g1_rem_set()->cleanup_after_oops_into_collection_set_do();
5894 
5895   // Reset and re-enable the hot card cache.
5896   // Note the counts for the cards in the regions in the
5897   // collection set are reset when the collection set is freed.
5898   hot_card_cache->reset_hot_cache();
5899   hot_card_cache->set_use_cache(true);
5900 
5901   // Migrate the strong code roots attached to each region in
5902   // the collection set. Ideally we would like to do this
5903   // after we have finished the scanning/evacuation of the
5904   // strong code roots for a particular heap region.
5905   migrate_strong_code_roots();
5906 
5907   purge_code_root_memory();
5908 
5909   if (g1_policy()->during_initial_mark_pause()) {
5910     // Reset the claim values set during marking the strong code roots
5911     reset_heap_region_claim_values();
5912   }
5913 
5914   finalize_for_evac_failure();
5915 
5916   if (evacuation_failed()) {
5917     remove_self_forwarding_pointers();
5918 
5919     // Reset the G1EvacuationFailureALot counters and flags
5920     // Note: the values are reset only when an actual
5921     // evacuation failure occurs.
5922     NOT_PRODUCT(reset_evacuation_should_fail();)
5923   }
5924 
5925   // Enqueue any remaining references remaining on the STW
5926   // reference processor's discovered lists. We need to do
5927   // this after the card table is cleaned (and verified) as
5928   // the act of enqueueing entries on to the pending list


6793 
6794 class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure {
6795 public:
6796   bool doHeapRegion(HeapRegion *hr) {
6797     assert(!hr->isHumongous(),
6798            err_msg("humongous region "HR_FORMAT" should not have been added to collection set",
6799                    HR_FORMAT_PARAMS(hr)));
6800     hr->migrate_strong_code_roots();
6801     return false;
6802   }
6803 };
6804 
6805 void G1CollectedHeap::migrate_strong_code_roots() {
6806   MigrateCodeRootsHeapRegionClosure cl;
6807   double migrate_start = os::elapsedTime();
6808   collection_set_iterate(&cl);
6809   double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0;
6810   g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms);
6811 }
6812 
6813 void G1CollectedHeap::purge_code_root_memory() {
6814   double purge_start = os::elapsedTime();
6815   G1CodeRootSet::purge_chunks(G1CodeRootsChunkCacheKeepRatio);
6816   double purge_time_ms = (os::elapsedTime() - purge_start) * 1000.0;
6817   g1_policy()->phase_times()->record_strong_code_root_purge_time(purge_time_ms);
6818 }
6819 
6820 // Mark all the code roots that point into regions *not* in the
6821 // collection set.
6822 //
6823 // Note we do not want to use a "marking" CodeBlobToOopClosure while
6824 // walking the the code roots lists of regions not in the collection
6825 // set. Suppose we have an nmethod (M) that points to objects in two
6826 // separate regions - one in the collection set (R1) and one not (R2).
6827 // Using a "marking" CodeBlobToOopClosure here would result in "marking"
6828 // nmethod M when walking the code roots for R1. When we come to scan
6829 // the code roots for R2, we would see that M is already marked and it
6830 // would be skipped and the objects in R2 that are referenced from M
6831 // would not be evacuated.
6832 
6833 class MarkStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
6834 
6835   class MarkStrongCodeRootOopClosure: public OopClosure {
6836     ConcurrentMark* _cm;
6837     HeapRegion* _hr;
6838     uint _worker_id;
6839 


6870     if (nm != NULL) {
6871       nm->oops_do(&_oop_cl);
6872     }
6873   }
6874 };
6875 
6876 class MarkStrongCodeRootsHRClosure: public HeapRegionClosure {
6877   G1CollectedHeap* _g1h;
6878   uint _worker_id;
6879 
6880 public:
6881   MarkStrongCodeRootsHRClosure(G1CollectedHeap* g1h, uint worker_id) :
6882     _g1h(g1h), _worker_id(worker_id) {}
6883 
6884   bool doHeapRegion(HeapRegion *hr) {
6885     HeapRegionRemSet* hrrs = hr->rem_set();
6886     if (hr->continuesHumongous()) {
6887       // Code roots should never be attached to a continuation of a humongous region
6888       assert(hrrs->strong_code_roots_list_length() == 0,
6889              err_msg("code roots should never be attached to continuations of humongous region "HR_FORMAT
6890                      " starting at "HR_FORMAT", but has "SIZE_FORMAT,
6891                      HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()),
6892                      hrrs->strong_code_roots_list_length()));
6893       return false;
6894     }
6895 
6896     if (hr->in_collection_set()) {
6897       // Don't mark code roots into regions in the collection set here.
6898       // They will be marked when we scan them.
6899       return false;
6900     }
6901 
6902     MarkStrongCodeRootCodeBlobClosure cb_cl(_g1h->concurrent_mark(), hr, _worker_id);
6903     hr->strong_code_roots_do(&cb_cl);
6904     return false;
6905   }
6906 };
6907 
6908 void G1CollectedHeap::mark_strong_code_roots(uint worker_id) {
6909   MarkStrongCodeRootsHRClosure cl(this, worker_id);
6910   if (G1CollectedHeap::use_parallel_gc_threads()) {