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