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(¤t);
708 print_summary_info(&_last_period_summary);
709
710 _last_period_summary.set(¤t);
711 }
712
713 void G1RemSet::print_summary_info() {
714 G1RemSetSummary current;
715 current.initialize(this, n_workers());
716
717 print_summary_info(¤t, " 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();
|