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