1 /*
   2  * Copyright (c) 2011, 2015, Oracle and/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_VM_GC_G1_G1ERGOVERBOSE_HPP
  26 #define SHARE_VM_GC_G1_G1ERGOVERBOSE_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "utilities/debug.hpp"
  30 
  31 // The log of G1's heuristic decisions comprises of a series of
  32 // records which have a similar format in order to maintain
  33 // consistency across records and ultimately easier parsing of the
  34 // output, if we ever choose to do that. Each record consists of:
  35 // * A time stamp to be able to easily correlate each record with
  36 // other events.
  37 // * A unique string to allow us to easily identify such records.
  38 // * The name of the heuristic the record corresponds to.
  39 // * An action string which describes the action that G1 did or is
  40 // about to do.
  41 // * An optional reason string which describes the reason for the
  42 // action.
  43 // * An optional number of name/value pairs which contributed to the
  44 // decision to take the action described in the record.
  45 //
  46 // Each record is associated with a "tag" which is the combination of
  47 // the heuristic the record corresponds to, as well as the min level
  48 // of verboseness at which the record should be printed. The tag is
  49 // checked against the current settings to determine whether the record
  50 // should be printed or not.
  51 
  52 // The available verboseness levels.
  53 typedef enum {
  54   // Determine which part of the tag is occupied by the level.
  55   ErgoLevelShift = 8,
  56   ErgoLevelMask = ~((1 << ErgoLevelShift) - 1),
  57 
  58   // ErgoLow is 0 so that we don't have to explicitly or a heuristic
  59   // id with ErgoLow to keep its use simpler.
  60   ErgoLow = 0,
  61   ErgoHigh = 1 << ErgoLevelShift
  62 } ErgoLevel;
  63 
  64 // The available heuristics.
  65 typedef enum {
  66   // Determines which part of the tag is occupied by the heuristic id.
  67   ErgoHeuristicMask = ~ErgoLevelMask,
  68 
  69   ErgoHeapSizing = 0,
  70   ErgoCSetConstruction,
  71   ErgoConcCycles,
  72   ErgoMixedGCs,
  73   ErgoTiming,
  74   ErgoIHOP,
  75 
  76   ErgoHeuristicNum
  77 } ErgoHeuristic;
  78 
  79 class G1ErgoVerbose : AllStatic {
  80 private:
  81   // Determines the minimum verboseness level at which records will be
  82   // printed.
  83   static ErgoLevel _level;
  84   // Determines which heuristics are currently enabled.
  85   static bool _enabled[ErgoHeuristicNum];
  86 
  87   static ErgoLevel extract_level(int tag) {
  88     return (ErgoLevel) (tag & ErgoLevelMask);
  89   }
  90 
  91   static ErgoHeuristic extract_heuristic(int tag) {
  92     return (ErgoHeuristic) (tag & ErgoHeuristicMask);
  93   }
  94 
  95 public:
  96   // Needs to be explicitly called at GC initialization.
  97   static void initialize();
  98 
  99   static void set_level(ErgoLevel level);
 100   static void set_enabled(ErgoHeuristic h, bool enabled);
 101   // It is applied to all heuristics.
 102   static void set_enabled(bool enabled);
 103 
 104   static bool enabled(int tag) {
 105     ErgoLevel level = extract_level(tag);
 106     ErgoHeuristic n = extract_heuristic(tag);
 107     return level <= _level && _enabled[n];
 108   }
 109 
 110   // Extract the heuristic id from the tag and return a string with
 111   // its name.
 112   static const char* to_string(int tag);
 113 };
 114 
 115 // The macros below generate the format string for values of different
 116 // types and/or metrics.
 117 
 118 // The reason for the action is optional and is handled specially: the
 119 // reason string is concatenated here so it's not necessary to pass it
 120 // as a parameter.
 121 #define ergo_format_reason(_reason_) ", reason: " _reason_
 122 
 123 // Single parameter format strings
 124 #define ergo_format_str(_name_)      ", " _name_ ": %s"
 125 #define ergo_format_region(_name_)   ", " _name_ ": %u regions"
 126 #define ergo_format_byte(_name_)     ", " _name_ ": " SIZE_FORMAT " bytes"
 127 #define ergo_format_double(_name_)   ", " _name_ ": %1.2f"
 128 #define ergo_format_perc(_name_)     ", " _name_ ": %1.2f %%"
 129 #define ergo_format_ms(_name_)       ", " _name_ ": %1.2f ms"
 130 #define ergo_format_size(_name_)     ", " _name_ ": " SIZE_FORMAT
 131 
 132 // Double parameter format strings
 133 #define ergo_format_byte_perc(_name_)                                   \
 134                              ", " _name_ ": " SIZE_FORMAT " bytes (%1.2f %%)"
 135 
 136 // Generates the format string
 137 #define ergo_format(_extra_format_)                           \
 138   " %1.3f: [G1Ergonomics (%s) %s" _extra_format_ "]"
 139 
 140 // Conditionally, prints an ergonomic decision record. _extra_format_
 141 // is the format string for the optional items we'd like to print
 142 // (i.e., the decision's reason and any associated values). This
 143 // string should be built up using the ergo_*_format macros (see
 144 // above) to ensure consistency.
 145 //
 146 // Since we cannot rely on the compiler supporting variable argument
 147 // macros, this macro accepts a fixed number of arguments and passes
 148 // them to the print method. For convenience, we have wrapper macros
 149 // below which take a specific number of arguments and set the rest to
 150 // a default value.
 151 #define ergo_verbose_common(_tag_, _action_, _extra_format_,                \
 152                             _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_) \
 153   do {                                                                      \
 154     if (G1ErgoVerbose::enabled((_tag_))) {                                  \
 155       gclog_or_tty->print_cr(ergo_format(_extra_format_),                   \
 156                              os::elapsedTime(),                             \
 157                              G1ErgoVerbose::to_string((_tag_)),             \
 158                              (_action_),                                    \
 159                              (_arg0_), (_arg1_), (_arg2_),                  \
 160                              (_arg3_), (_arg4_), (_arg5_));                 \
 161     }                                                                       \
 162   } while (0)
 163 
 164 
 165 #define ergo_verbose6(_tag_, _action_, _extra_format_,                  \
 166                       _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)   \
 167   ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
 168                       _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)
 169 
 170 #define ergo_verbose5(_tag_, _action_, _extra_format_,                  \
 171                       _arg0_, _arg1_, _arg2_, _arg3_, _arg4_)           \
 172   ergo_verbose6(_tag_, _action_, _extra_format_ "%s",                   \
 173                 _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, "")
 174 
 175 #define ergo_verbose4(_tag_, _action_, _extra_format_,                  \
 176                       _arg0_, _arg1_, _arg2_, _arg3_)                   \
 177   ergo_verbose5(_tag_, _action_, _extra_format_ "%s",                   \
 178                 _arg0_, _arg1_, _arg2_, _arg3_, "")
 179 
 180 #define ergo_verbose3(_tag_, _action_, _extra_format_,                  \
 181                       _arg0_, _arg1_, _arg2_)                           \
 182   ergo_verbose4(_tag_, _action_, _extra_format_ "%s",                   \
 183                 _arg0_, _arg1_, _arg2_, "")
 184 
 185 #define ergo_verbose2(_tag_, _action_, _extra_format_,                  \
 186                       _arg0_, _arg1_)                                   \
 187   ergo_verbose3(_tag_, _action_, _extra_format_ "%s",                   \
 188                 _arg0_, _arg1_, "")
 189 
 190 #define ergo_verbose1(_tag_, _action_, _extra_format_,                  \
 191                       _arg0_)                                           \
 192   ergo_verbose2(_tag_, _action_, _extra_format_ "%s",                   \
 193                 _arg0_, "")
 194 
 195 
 196 #define ergo_verbose0(_tag_, _action_, _extra_format_)                  \
 197   ergo_verbose1(_tag_, _action_, _extra_format_ "%s",                   \
 198                 "")
 199 
 200 #define ergo_verbose(_tag_, _action_)                                   \
 201   ergo_verbose0(_tag_, _action_, "")
 202 
 203 
 204 #endif // SHARE_VM_GC_G1_G1ERGOVERBOSE_HPP