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

Print this page




  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc_implementation/g1/bufferingOopClosure.hpp"
  27 #include "gc_implementation/g1/concurrentG1Refine.hpp"
  28 #include "gc_implementation/g1/concurrentG1RefineThread.hpp"
  29 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
  30 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  31 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
  32 #include "gc_implementation/g1/g1HotCardCache.hpp"
  33 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
  34 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
  35 #include "gc_implementation/g1/g1RemSet.inline.hpp"
  36 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"

  37 #include "memory/iterator.hpp"
  38 #include "oops/oop.inline.hpp"
  39 #include "utilities/intHisto.hpp"
  40 
  41 #define CARD_REPEAT_HISTO 0
  42 
  43 #if CARD_REPEAT_HISTO
  44 static size_t ct_freq_sz;
  45 static jbyte* ct_freq = NULL;
  46 
  47 void init_ct_freq_table(size_t heap_sz_bytes) {
  48   if (ct_freq == NULL) {
  49     ct_freq_sz = heap_sz_bytes/CardTableModRefBS::card_size;
  50     ct_freq = new jbyte[ct_freq_sz];
  51     for (size_t j = 0; j < ct_freq_sz; j++) ct_freq[j] = 0;
  52   }
  53 }
  54 
  55 void ct_freq_note_card(size_t index) {
  56   assert(0 <= index && index < ct_freq_sz, "Bounds error.");
  57   if (ct_freq[index] < 100) { ct_freq[index]++; }
  58 }
  59 
  60 static IntHistogram card_repeat_count(10, 10);
  61 
  62 void ct_freq_update_histo_and_reset() {
  63   for (size_t j = 0; j < ct_freq_sz; j++) {
  64     card_repeat_count.add_entry(ct_freq[j]);
  65     ct_freq[j] = 0;
  66   }
  67 
  68 }
  69 #endif
  70 
  71 G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
  72   : _g1(g1), _conc_refine_cards(0),
  73     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
  74     _cg1r(g1->concurrent_g1_refine()),
  75     _cset_rs_update_cl(NULL),
  76     _cards_scanned(NULL), _total_cards_scanned(0)

  77 {
  78   _seq_task = new SubTasksDone(NumSeqTasks);
  79   guarantee(n_workers() > 0, "There should be some workers");
  80   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC);
  81   for (uint i = 0; i < n_workers(); i++) {
  82     _cset_rs_update_cl[i] = NULL;
  83   }

  84 }
  85 
  86 G1RemSet::~G1RemSet() {
  87   delete _seq_task;
  88   for (uint i = 0; i < n_workers(); i++) {
  89     assert(_cset_rs_update_cl[i] == NULL, "it should be");
  90   }
  91   FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC);
  92 }
  93 
  94 void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) {
  95   if (_g1->is_in_g1_reserved(mr.start())) {
  96     _n += (int) ((mr.byte_size() / CardTableModRefBS::card_size));
  97     if (_start_first == NULL) _start_first = mr.start();
  98   }
  99 }
 100 
 101 class ScanRSClosure : public HeapRegionClosure {
 102   size_t _cards_done, _cards;
 103   G1CollectedHeap* _g1h;


 680         JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
 681       sdcq->enqueue(card_ptr);
 682     }
 683   } else {
 684     _conc_refine_cards++;
 685   }
 686 
 687   // This gets set to true if the card being refined has
 688   // references that point into the collection set.
 689   bool has_refs_into_cset = trigger_cl.triggered();
 690 
 691   // We should only be detecting that the card contains references
 692   // that point into the collection set if the current thread is
 693   // a GC worker thread.
 694   assert(!has_refs_into_cset || SafepointSynchronize::is_at_safepoint(),
 695            "invalid result at non safepoint");
 696 
 697   return has_refs_into_cset;
 698 }
 699 
 700 class HRRSStatsIter: public HeapRegionClosure {
 701   size_t _occupied;
 702   size_t _total_mem_sz;
 703   size_t _max_mem_sz;
 704   HeapRegion* _max_mem_sz_region;
 705 public:
 706   HRRSStatsIter() :
 707     _occupied(0),
 708     _total_mem_sz(0),
 709     _max_mem_sz(0),
 710     _max_mem_sz_region(NULL)
 711   {}
 712 
 713   bool doHeapRegion(HeapRegion* r) {
 714     if (r->continuesHumongous()) return false;
 715     size_t mem_sz = r->rem_set()->mem_size();
 716     if (mem_sz > _max_mem_sz) {
 717       _max_mem_sz = mem_sz;
 718       _max_mem_sz_region = r;
 719     }
 720     _total_mem_sz += mem_sz;
 721     size_t occ = r->rem_set()->occupied();
 722     _occupied += occ;
 723     return false;
 724   }
 725   size_t total_mem_sz() { return _total_mem_sz; }
 726   size_t max_mem_sz() { return _max_mem_sz; }
 727   size_t occupied() { return _occupied; }
 728   HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
 729 };
 730 
 731 class PrintRSThreadVTimeClosure : public ThreadClosure {
 732 public:
 733   virtual void do_thread(Thread *t) {
 734     ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
 735     gclog_or_tty->print("    %5.2f", crt->vtime_accum());
 736   }
 737 };
 738 
 739 void G1RemSet::print_summary_info() {
 740   G1CollectedHeap* g1 = G1CollectedHeap::heap();











 741 
 742 #if CARD_REPEAT_HISTO
 743   gclog_or_tty->print_cr("\nG1 card_repeat count histogram: ");
 744   gclog_or_tty->print_cr("  # of repeats --> # of cards with that number.");
 745   card_repeat_count.print_on(gclog_or_tty);
 746 #endif
 747 
 748   gclog_or_tty->print_cr("\n Concurrent RS processed %d cards",
 749                          _conc_refine_cards);
 750   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 751   jint tot_processed_buffers =
 752     dcqs.processed_buffers_mut() + dcqs.processed_buffers_rs_thread();
 753   gclog_or_tty->print_cr("  Of %d completed buffers:", tot_processed_buffers);
 754   gclog_or_tty->print_cr("     %8d (%5.1f%%) by conc RS threads.",
 755                 dcqs.processed_buffers_rs_thread(),
 756                 100.0*(float)dcqs.processed_buffers_rs_thread()/
 757                 (float)tot_processed_buffers);
 758   gclog_or_tty->print_cr("     %8d (%5.1f%%) by mutator threads.",
 759                 dcqs.processed_buffers_mut(),
 760                 100.0*(float)dcqs.processed_buffers_mut()/
 761                 (float)tot_processed_buffers);
 762   gclog_or_tty->print_cr("  Conc RS threads times(s)");
 763   PrintRSThreadVTimeClosure p;
 764   gclog_or_tty->print("     ");
 765   g1->concurrent_g1_refine()->threads_do(&p);
 766   gclog_or_tty->print_cr("");
 767 
 768   HRRSStatsIter blk;
 769   g1->heap_region_iterate(&blk);
 770   gclog_or_tty->print_cr("  Total heap region rem set sizes = "SIZE_FORMAT"K."
 771                          "  Max = "SIZE_FORMAT"K.",
 772                          blk.total_mem_sz()/K, blk.max_mem_sz()/K);
 773   gclog_or_tty->print_cr("  Static structures = "SIZE_FORMAT"K,"
 774                          " free_lists = "SIZE_FORMAT"K.",
 775                          HeapRegionRemSet::static_mem_size() / K,
 776                          HeapRegionRemSet::fl_mem_size() / K);
 777   gclog_or_tty->print_cr("    "SIZE_FORMAT" occupied cards represented.",
 778                          blk.occupied());
 779   HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
 780   HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
 781   gclog_or_tty->print_cr("    Max size region = "HR_FORMAT", "
 782                          "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
 783                          HR_FORMAT_PARAMS(max_mem_sz_region),
 784                          (rem_set->mem_size() + K - 1)/K,
 785                          (rem_set->occupied() + K - 1)/K);
 786   gclog_or_tty->print_cr("    Did %d coarsenings.",
 787                          HeapRegionRemSet::n_coarsenings());
 788 }
 789 
 790 void G1RemSet::prepare_for_verify() {
 791   if (G1HRRSFlushLogBuffersOnVerify &&
 792       (VerifyBeforeGC || VerifyAfterGC)
 793       &&  !_g1->full_collection()) {
 794     cleanupHRRS();
 795     _g1->set_refine_cte_cl_concurrency(false);
 796     if (SafepointSynchronize::is_at_safepoint()) {
 797       DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 798       dcqs.concatenate_logs();
 799     }
 800 
 801     G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
 802     bool use_hot_card_cache = hot_card_cache->use_cache();
 803     hot_card_cache->set_use_cache(false);
 804 
 805     DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
 806     updateRS(&into_cset_dcq, 0);
 807     _g1->into_cset_dirty_card_queue_set().clear();


  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc_implementation/g1/bufferingOopClosure.hpp"
  27 #include "gc_implementation/g1/concurrentG1Refine.hpp"
  28 #include "gc_implementation/g1/concurrentG1RefineThread.hpp"
  29 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
  30 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  31 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
  32 #include "gc_implementation/g1/g1HotCardCache.hpp"
  33 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
  34 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
  35 #include "gc_implementation/g1/g1RemSet.inline.hpp"
  36 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
  37 #include "gc_implementation/g1/heapRegionRemSet.hpp"
  38 #include "memory/iterator.hpp"
  39 #include "oops/oop.inline.hpp"
  40 #include "utilities/intHisto.hpp"
  41 
  42 #define CARD_REPEAT_HISTO 0
  43 
  44 #if CARD_REPEAT_HISTO
  45 static size_t ct_freq_sz;
  46 static jbyte* ct_freq = NULL;
  47 
  48 void init_ct_freq_table(size_t heap_sz_bytes) {
  49   if (ct_freq == NULL) {
  50     ct_freq_sz = heap_sz_bytes/CardTableModRefBS::card_size;
  51     ct_freq = new jbyte[ct_freq_sz];
  52     for (size_t j = 0; j < ct_freq_sz; j++) ct_freq[j] = 0;
  53   }
  54 }
  55 
  56 void ct_freq_note_card(size_t index) {
  57   assert(0 <= index && index < ct_freq_sz, "Bounds error.");
  58   if (ct_freq[index] < 100) { ct_freq[index]++; }
  59 }
  60 
  61 static IntHistogram card_repeat_count(10, 10);
  62 
  63 void ct_freq_update_histo_and_reset() {
  64   for (size_t j = 0; j < ct_freq_sz; j++) {
  65     card_repeat_count.add_entry(ct_freq[j]);
  66     ct_freq[j] = 0;
  67   }
  68 
  69 }
  70 #endif
  71 
  72 G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
  73   : _g1(g1), _conc_refine_cards(0),
  74     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
  75     _cg1r(g1->concurrent_g1_refine()),
  76     _cset_rs_update_cl(NULL),
  77     _cards_scanned(NULL), _total_cards_scanned(0),
  78     _last_period_summary()
  79 {
  80   _seq_task = new SubTasksDone(NumSeqTasks);
  81   guarantee(n_workers() > 0, "There should be some workers");
  82   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC);
  83   for (uint i = 0; i < n_workers(); i++) {
  84     _cset_rs_update_cl[i] = NULL;
  85   }
  86   _last_period_summary.initialize(this, n_workers());
  87 }
  88 
  89 G1RemSet::~G1RemSet() {
  90   delete _seq_task;
  91   for (uint i = 0; i < n_workers(); i++) {
  92     assert(_cset_rs_update_cl[i] == NULL, "it should be");
  93   }
  94   FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC);
  95 }
  96 
  97 void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) {
  98   if (_g1->is_in_g1_reserved(mr.start())) {
  99     _n += (int) ((mr.byte_size() / CardTableModRefBS::card_size));
 100     if (_start_first == NULL) _start_first = mr.start();
 101   }
 102 }
 103 
 104 class ScanRSClosure : public HeapRegionClosure {
 105   size_t _cards_done, _cards;
 106   G1CollectedHeap* _g1h;


 683         JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
 684       sdcq->enqueue(card_ptr);
 685     }
 686   } else {
 687     _conc_refine_cards++;
 688   }
 689 
 690   // This gets set to true if the card being refined has
 691   // references that point into the collection set.
 692   bool has_refs_into_cset = trigger_cl.triggered();
 693 
 694   // We should only be detecting that the card contains references
 695   // that point into the collection set if the current thread is
 696   // a GC worker thread.
 697   assert(!has_refs_into_cset || SafepointSynchronize::is_at_safepoint(),
 698            "invalid result at non safepoint");
 699 
 700   return has_refs_into_cset;
 701 }
 702 
 703 void G1RemSet::print_periodic_summary_info() {
 704   G1RemSetSummary current;
 705   current.initialize(this, n_workers());









 706 
 707   _last_period_summary.subtract_from(&current);
 708   print_summary_info(&_last_period_summary);















 709 
 710   _last_period_summary.set(&current);
 711 }





 712 
 713 void G1RemSet::print_summary_info() {
 714   G1RemSetSummary current;
 715   current.initialize(this, n_workers());
 716 
 717   print_summary_info(&current, " Cumulative RS summary");
 718 }
 719 
 720 void G1RemSet::print_summary_info(G1RemSetSummary * summary, const char * header) {
 721   assert(summary != NULL, "just checking");
 722 
 723   if (header != NULL) {
 724     gclog_or_tty->print_cr("%s", header);
 725   }
 726 
 727 #if CARD_REPEAT_HISTO
 728   gclog_or_tty->print_cr("\nG1 card_repeat count histogram: ");
 729   gclog_or_tty->print_cr("  # of repeats --> # of cards with that number.");
 730   card_repeat_count.print_on(gclog_or_tty);
 731 #endif
 732 
 733   summary->print_on(gclog_or_tty);







































 734 }
 735 
 736 void G1RemSet::prepare_for_verify() {
 737   if (G1HRRSFlushLogBuffersOnVerify &&
 738       (VerifyBeforeGC || VerifyAfterGC)
 739       &&  !_g1->full_collection()) {
 740     cleanupHRRS();
 741     _g1->set_refine_cte_cl_concurrency(false);
 742     if (SafepointSynchronize::is_at_safepoint()) {
 743       DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 744       dcqs.concatenate_logs();
 745     }
 746 
 747     G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
 748     bool use_hot_card_cache = hot_card_cache->use_cache();
 749     hot_card_cache->set_use_cache(false);
 750 
 751     DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
 752     updateRS(&into_cset_dcq, 0);
 753     _g1->into_cset_dirty_card_queue_set().clear();