1 /*
  2  * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 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 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCARDSTATS_HPP
 26 #define SHARE_GC_SHENANDOAH_SHENANDOAHCARDSTATS_HPP
 27 
 28 #include "gc/shared/gc_globals.hpp"
 29 #include "gc/shenandoah/shenandoahNumberSeq.hpp"
 30 
 31 enum CardStatType {
 32   DIRTY_RUN           = 0,
 33   CLEAN_RUN           = 1,
 34   DIRTY_CARDS         = 2,
 35   CLEAN_CARDS         = 3,
 36   MAX_DIRTY_RUN       = 4,
 37   MAX_CLEAN_RUN       = 5,
 38   DIRTY_SCAN_OBJS     = 6,
 39   ALTERNATIONS        = 7,
 40   MAX_CARD_STAT_TYPE  = 8
 41 };
 42 
 43 enum CardStatLogType {
 44   CARD_STAT_SCAN_RS       = 0,
 45   CARD_STAT_UPDATE_REFS   = 1,
 46   MAX_CARD_STAT_LOG_TYPE  = 2
 47 };
 48 
 49 class ShenandoahCardStats: public CHeapObj<mtGC> {
 50 private:
 51   size_t _cards_in_cluster;
 52   HdrSeq* _local_card_stats;
 53 
 54   size_t _dirty_card_cnt;
 55   size_t _clean_card_cnt;
 56 
 57   size_t _max_dirty_run;
 58   size_t _max_clean_run;
 59 
 60   size_t _dirty_scan_obj_cnt;
 61 
 62   size_t _alternation_cnt;
 63 
 64 public:
 65   ShenandoahCardStats(size_t cards_in_cluster, HdrSeq* card_stats) :
 66     _cards_in_cluster(cards_in_cluster),
 67     _local_card_stats(card_stats),
 68     _dirty_card_cnt(0),
 69     _clean_card_cnt(0),
 70     _max_dirty_run(0),
 71     _max_clean_run(0),
 72     _dirty_scan_obj_cnt(0),
 73     _alternation_cnt(0)
 74   { }
 75 
 76   ~ShenandoahCardStats() {
 77     record();
 78    }
 79 
 80    void record() {
 81     if (ShenandoahEnableCardStats) {
 82       // Update global stats for distribution of dirty/clean cards as a percentage of chunk
 83       _local_card_stats[DIRTY_CARDS].add(percent_of(_dirty_card_cnt, _cards_in_cluster));
 84       _local_card_stats[CLEAN_CARDS].add(percent_of(_clean_card_cnt, _cards_in_cluster));
 85 
 86       // Update global stats for max dirty/clean run distribution as a percentage of chunk
 87       _local_card_stats[MAX_DIRTY_RUN].add(percent_of(_max_dirty_run, _cards_in_cluster));
 88       _local_card_stats[MAX_CLEAN_RUN].add(percent_of(_max_clean_run, _cards_in_cluster));
 89 
 90       // Update global stats for dirty obj scan counts
 91       _local_card_stats[DIRTY_SCAN_OBJS].add(_dirty_scan_obj_cnt);
 92 
 93       // Update global stats for alternation counts
 94       _local_card_stats[ALTERNATIONS].add(_alternation_cnt);
 95     }
 96   }
 97 
 98 public:
 99   inline void record_dirty_run(size_t len) {
100     if (ShenandoahEnableCardStats) {
101       _alternation_cnt++;
102       if (len > _max_dirty_run) {
103         _max_dirty_run = len;
104       }
105       _dirty_card_cnt += len;
106       assert(len <= _cards_in_cluster, "Error");
107       _local_card_stats[DIRTY_RUN].add(percent_of(len, _cards_in_cluster));
108     }
109   }
110 
111   inline void record_clean_run(size_t len) {
112     if (ShenandoahEnableCardStats) {
113       _alternation_cnt++;
114       if (len > _max_clean_run) {
115         _max_clean_run = len;
116       }
117       _clean_card_cnt += len;
118       assert(len <= _cards_in_cluster, "Error");
119       _local_card_stats[CLEAN_RUN].add(percent_of(len, _cards_in_cluster));
120     }
121   }
122 
123   inline void record_scan_obj_cnt(size_t i) {
124     if (ShenandoahEnableCardStats) {
125       _dirty_scan_obj_cnt += i;
126     }
127   }
128 
129   void log() const PRODUCT_RETURN;
130 };
131 
132 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCARDSTATS_HPP