g1ErgoVerbose.hpp 8.4 KB
Newer Older
1
/*
2
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP
#define SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP

#include "memory/allocation.hpp"
#include "utilities/debug.hpp"

// The log of G1's heuristic decisions comprises of a series of
// records which have a similar format in order to maintain
// consistency across records and ultimately easier parsing of the
// output, if we ever choose to do that. Each record consists of:
// * A time stamp to be able to easily correlate each record with
// other events.
// * A unique string to allow us to easily identify such records.
// * The name of the heuristic the record corresponds to.
// * An action string which describes the action that G1 did or is
// about to do.
// * An optional reason string which describes the reason for the
// action.
// * An optional number of name/value pairs which contributed to the
// decision to take the action described in the record.
//
// Each record is associated with a "tag" which is the combination of
// the heuristic the record corresponds to, as well as the min level
// of verboseness at which the record should be printed. The tag is
// checked against the current settings to determine whether the record
// should be printed or not.

// The available verboseness levels.
typedef enum {
  // Determine which part of the tag is occupied by the level.
  ErgoLevelShift = 8,
  ErgoLevelMask = ~((1 << ErgoLevelShift) - 1),

  // ErgoLow is 0 so that we don't have to explicitly or a heuristic
  // id with ErgoLow to keep its use simpler.
  ErgoLow = 0,
61
  ErgoHigh = 1 << ErgoLevelShift
62 63 64 65 66 67 68 69 70 71
} ErgoLevel;

// The available heuristics.
typedef enum {
  // Determines which part of the tag is occupied by the heuristic id.
  ErgoHeuristicMask = ~ErgoLevelMask,

  ErgoHeapSizing = 0,
  ErgoCSetConstruction,
  ErgoConcCycles,
72
  ErgoMixedGCs,
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

  ErgoHeuristicNum
} ErgoHeuristic;

class G1ErgoVerbose : AllStatic {
private:
  // Determines the minimum verboseness level at which records will be
  // printed.
  static ErgoLevel _level;
  // Determines which heuristics are currently enabled.
  static bool _enabled[ErgoHeuristicNum];

  static ErgoLevel extract_level(int tag) {
    return (ErgoLevel) (tag & ErgoLevelMask);
  }

  static ErgoHeuristic extract_heuristic(int tag) {
    return (ErgoHeuristic) (tag & ErgoHeuristicMask);
  }

public:
  // Needs to be explicitly called at GC initialization.
  static void initialize();

  static void set_level(ErgoLevel level);
  static void set_enabled(ErgoHeuristic h, bool enabled);
  // It is applied to all heuristics.
  static void set_enabled(bool enabled);

  static bool enabled(int tag) {
    ErgoLevel level = extract_level(tag);
    ErgoHeuristic n = extract_heuristic(tag);
    return level <= _level && _enabled[n];
  }

  // Extract the heuristic id from the tag and return a string with
  // its name.
  static const char* to_string(int tag);
};

// The macros below generate the format string for values of different
// types and/or metrics.

// The reason for the action is optional and is handled specially: the
// reason string is concatenated here so it's not necessary to pass it
// as a parameter.
#define ergo_format_reason(_reason_) ", reason: " _reason_

// Single parameter format strings
#define ergo_format_str(_name_)      ", " _name_ ": %s"
123
#define ergo_format_region(_name_)   ", " _name_ ": %u regions"
124 125 126 127
#define ergo_format_byte(_name_)     ", " _name_ ": "SIZE_FORMAT" bytes"
#define ergo_format_double(_name_)   ", " _name_ ": %1.2f"
#define ergo_format_perc(_name_)     ", " _name_ ": %1.2f %%"
#define ergo_format_ms(_name_)       ", " _name_ ": %1.2f ms"
128
#define ergo_format_size(_name_)     ", " _name_ ": "SIZE_FORMAT
129 130 131 132 133 134

// Double parameter format strings
#define ergo_format_byte_perc(_name_)                                   \
                             ", " _name_ ": "SIZE_FORMAT" bytes (%1.2f %%)"

// Generates the format string
135 136
#define ergo_format(_extra_format_)                           \
  " %1.3f: [G1Ergonomics (%s) %s" _extra_format_ "]"
137 138 139 140 141 142 143 144 145 146 147 148

// Conditionally, prints an ergonomic decision record. _extra_format_
// is the format string for the optional items we'd like to print
// (i.e., the decision's reason and any associated values). This
// string should be built up using the ergo_*_format macros (see
// above) to ensure consistency.
//
// Since we cannot rely on the compiler supporting variable argument
// macros, this macro accepts a fixed number of arguments and passes
// them to the print method. For convenience, we have wrapper macros
// below which take a specific number of arguments and set the rest to
// a default value.
149
#define ergo_verbose_common(_tag_, _action_, _extra_format_,                \
150
                            _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_) \
151 152 153 154 155 156 157 158 159
  do {                                                                      \
    if (G1ErgoVerbose::enabled((_tag_))) {                                  \
      gclog_or_tty->print_cr(ergo_format(_extra_format_),                   \
                             os::elapsedTime(),                             \
                             G1ErgoVerbose::to_string((_tag_)),             \
                             (_action_),                                    \
                             (_arg0_), (_arg1_), (_arg2_),                  \
                             (_arg3_), (_arg4_), (_arg5_));                 \
    }                                                                       \
160 161 162
  } while (0)


163
#define ergo_verbose(_tag_, _action_)                                   \
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
  ergo_verbose_common(_tag_, _action_, "", 0, 0, 0, 0, 0, 0)

#define ergo_verbose0(_tag_, _action_, _extra_format_)                  \
  ergo_verbose_common(_tag_, _action_, _extra_format_, 0, 0, 0, 0, 0, 0)

#define ergo_verbose1(_tag_, _action_, _extra_format_,                  \
                      _arg0_)                                           \
  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
                      _arg0_, 0, 0, 0, 0, 0)

#define ergo_verbose2(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_)                                   \
  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, 0, 0, 0, 0)

#define ergo_verbose3(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, _arg2_)                           \
  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, _arg2_, 0, 0, 0)

#define ergo_verbose4(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, _arg2_, _arg3_)                   \
  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, _arg2_, _arg3_, 0, 0)

#define ergo_verbose5(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_)           \
  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, 0)

#define ergo_verbose6(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)   \
  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)

#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP