src/hotspot/share/runtime/perfData.hpp
changeset 47216 71c04702a3d5
parent 46630 75aa3e39d02c
child 48115 d8ec0640616c
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2001, 2017, 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_RUNTIME_PERFDATA_HPP
       
    26 #define SHARE_VM_RUNTIME_PERFDATA_HPP
       
    27 
       
    28 #include "memory/allocation.inline.hpp"
       
    29 #include "runtime/perfMemory.hpp"
       
    30 #include "runtime/timer.hpp"
       
    31 #include "utilities/growableArray.hpp"
       
    32 
       
    33 /* jvmstat global and subsystem counter name space - enumeration value
       
    34  * serve as an index into the PerfDataManager::_name_space[] array
       
    35  * containing the corresponding name space string. Only the top level
       
    36  * subsystem name spaces are represented here.
       
    37  */
       
    38 enum CounterNS {
       
    39   // top level name spaces
       
    40   JAVA_NS,
       
    41   COM_NS,
       
    42   SUN_NS,
       
    43   // subsystem name spaces
       
    44   JAVA_GC,              // Garbage Collection name spaces
       
    45   COM_GC,
       
    46   SUN_GC,
       
    47   JAVA_CI,              // Compiler name spaces
       
    48   COM_CI,
       
    49   SUN_CI,
       
    50   JAVA_CLS,             // Class Loader name spaces
       
    51   COM_CLS,
       
    52   SUN_CLS,
       
    53   JAVA_RT,              // Runtime name spaces
       
    54   COM_RT,
       
    55   SUN_RT,
       
    56   JAVA_OS,              // Operating System name spaces
       
    57   COM_OS,
       
    58   SUN_OS,
       
    59   JAVA_THREADS,         // Threads System name spaces
       
    60   COM_THREADS,
       
    61   SUN_THREADS,
       
    62   JAVA_PROPERTY,        // Java Property name spaces
       
    63   COM_PROPERTY,
       
    64   SUN_PROPERTY,
       
    65   NULL_NS,
       
    66   COUNTERNS_LAST = NULL_NS
       
    67 };
       
    68 
       
    69 /*
       
    70  * Classes to support access to production performance data
       
    71  *
       
    72  * The PerfData class structure is provided for creation, access, and update
       
    73  * of performance data (a.k.a. instrumentation) in a specific memory region
       
    74  * which is possibly accessible as shared memory. Although not explicitly
       
    75  * prevented from doing so, developers should not use the values returned
       
    76  * by accessor methods to make algorithmic decisions as they are potentially
       
    77  * extracted from a shared memory region. Although any shared memory region
       
    78  * created is with appropriate access restrictions, allowing read-write access
       
    79  * only to the principal that created the JVM, it is believed that a the
       
    80  * shared memory region facilitates an easier attack path than attacks
       
    81  * launched through mechanisms such as /proc. For this reason, it is
       
    82  * recommended that data returned by PerfData accessor methods be used
       
    83  * cautiously.
       
    84  *
       
    85  * There are three variability classifications of performance data
       
    86  *   Constants  -  value is written to the PerfData memory once, on creation
       
    87  *   Variables  -  value is modifiable, with no particular restrictions
       
    88  *   Counters   -  value is monotonically changing (increasing or decreasing)
       
    89  *
       
    90  * The performance data items can also have various types. The class
       
    91  * hierarchy and the structure of the memory region are designed to
       
    92  * accommodate new types as they are needed. Types are specified in
       
    93  * terms of Java basic types, which accommodates client applications
       
    94  * written in the Java programming language. The class hierarchy is:
       
    95  *
       
    96  * - PerfData (Abstract)
       
    97  *     - PerfLong (Abstract)
       
    98  *         - PerfLongConstant        (alias: PerfConstant)
       
    99  *         - PerfLongVariant (Abstract)
       
   100  *             - PerfLongVariable    (alias: PerfVariable)
       
   101  *             - PerfLongCounter     (alias: PerfCounter)
       
   102  *
       
   103  *     - PerfByteArray (Abstract)
       
   104  *         - PerfString (Abstract)
       
   105  *             - PerfStringVariable
       
   106  *             - PerfStringConstant
       
   107  *
       
   108  *
       
   109  * As seen in the class hierarchy, the initially supported types are:
       
   110  *
       
   111  *    Long      - performance data holds a Java long type
       
   112  *    ByteArray - performance data holds an array of Java bytes
       
   113  *                used for holding C++ char arrays.
       
   114  *
       
   115  * The String type is derived from the ByteArray type.
       
   116  *
       
   117  * A PerfData subtype is not required to provide an implementation for
       
   118  * each variability classification. For example, the String type provides
       
   119  * Variable and Constant variability classifications in the PerfStringVariable
       
   120  * and PerfStringConstant classes, but does not provide a counter type.
       
   121  *
       
   122  * Performance data are also described by a unit of measure. Units allow
       
   123  * client applications to make reasonable decisions on how to treat
       
   124  * performance data generically, preventing the need to hard-code the
       
   125  * specifics of a particular data item in client applications. The current
       
   126  * set of units are:
       
   127  *
       
   128  *   None        - the data has no units of measure
       
   129  *   Bytes       - data is measured in bytes
       
   130  *   Ticks       - data is measured in clock ticks
       
   131  *   Events      - data is measured in events. For example,
       
   132  *                 the number of garbage collection events or the
       
   133  *                 number of methods compiled.
       
   134  *   String      - data is not numerical. For example,
       
   135  *                 the java command line options
       
   136  *   Hertz       - data is a frequency
       
   137  *
       
   138  * The performance counters also provide a support attribute, indicating
       
   139  * the stability of the counter as a programmatic interface. The support
       
   140  * level is also implied by the name space in which the counter is created.
       
   141  * The counter name space support conventions follow the Java package, class,
       
   142  * and property support conventions:
       
   143  *
       
   144  *    java.*          - stable, supported interface
       
   145  *    com.sun.*       - unstable, supported interface
       
   146  *    sun.*           - unstable, unsupported interface
       
   147  *
       
   148  * In the above context, unstable is a measure of the interface support
       
   149  * level, not the implementation stability level.
       
   150  *
       
   151  * Currently, instances of PerfData subtypes are considered to have
       
   152  * a life time equal to that of the VM and are managed by the
       
   153  * PerfDataManager class. All constructors for the PerfData class and
       
   154  * its subtypes have protected constructors. Creation of PerfData
       
   155  * instances is performed by invoking various create methods on the
       
   156  * PerfDataManager class. Users should not attempt to delete these
       
   157  * instances as the PerfDataManager class expects to perform deletion
       
   158  * operations on exit of the VM.
       
   159  *
       
   160  * Examples:
       
   161  *
       
   162  * Creating performance counter that holds a monotonically increasing
       
   163  * long data value with units specified in U_Bytes in the "java.gc.*"
       
   164  * name space.
       
   165  *
       
   166  *   PerfLongCounter* foo_counter;
       
   167  *
       
   168  *   foo_counter = PerfDataManager::create_long_counter(JAVA_GC, "foo",
       
   169  *                                                       PerfData::U_Bytes,
       
   170  *                                                       optionalInitialValue,
       
   171  *                                                       CHECK);
       
   172  *   foo_counter->inc();
       
   173  *
       
   174  * Creating a performance counter that holds a variably change long
       
   175  * data value with units specified in U_Bytes in the "com.sun.ci
       
   176  * name space.
       
   177  *
       
   178  *   PerfLongVariable* bar_variable;
       
   179  *   bar_variable = PerfDataManager::create_long_variable(COM_CI, "bar",
       
   180 .*                                                        PerfData::U_Bytes,
       
   181  *                                                        optionalInitialValue,
       
   182  *                                                        CHECK);
       
   183  *
       
   184  *   bar_variable->inc();
       
   185  *   bar_variable->set_value(0);
       
   186  *
       
   187  * Creating a performance counter that holds a constant string value in
       
   188  * the "sun.cls.*" name space.
       
   189  *
       
   190  *   PerfDataManager::create_string_constant(SUN_CLS, "foo", string, CHECK);
       
   191  *
       
   192  *   Although the create_string_constant() factory method returns a pointer
       
   193  *   to the PerfStringConstant object, it can safely be ignored. Developers
       
   194  *   are not encouraged to access the string constant's value via this
       
   195  *   pointer at this time due to security concerns.
       
   196  *
       
   197  * Creating a performance counter in an arbitrary name space that holds a
       
   198  * value that is sampled by the StatSampler periodic task.
       
   199  *
       
   200  *    PerfDataManager::create_counter("foo.sampled", PerfData::U_Events,
       
   201  *                                    &my_jlong, CHECK);
       
   202  *
       
   203  *    In this example, the PerfData pointer can be ignored as the caller
       
   204  *    is relying on the StatSampler PeriodicTask to sample the given
       
   205  *    address at a regular interval. The interval is defined by the
       
   206  *    PerfDataSamplingInterval global variable, and is applied on
       
   207  *    a system wide basis, not on an per-counter basis.
       
   208  *
       
   209  * Creating a performance counter in an arbitrary name space that utilizes
       
   210  * a helper object to return a value to the StatSampler via the take_sample()
       
   211  * method.
       
   212  *
       
   213  *     class MyTimeSampler : public PerfLongSampleHelper {
       
   214  *       public:
       
   215  *         jlong take_sample() { return os::elapsed_counter(); }
       
   216  *     };
       
   217  *
       
   218  *     PerfDataManager::create_counter(SUN_RT, "helped",
       
   219  *                                     PerfData::U_Ticks,
       
   220  *                                     new MyTimeSampler(), CHECK);
       
   221  *
       
   222  *     In this example, a subtype of PerfLongSampleHelper is instantiated
       
   223  *     and its take_sample() method is overridden to perform whatever
       
   224  *     operation is necessary to generate the data sample. This method
       
   225  *     will be called by the StatSampler at a regular interval, defined
       
   226  *     by the PerfDataSamplingInterval global variable.
       
   227  *
       
   228  *     As before, PerfSampleHelper is an alias for PerfLongSampleHelper.
       
   229  *
       
   230  * For additional uses of PerfData subtypes, see the utility classes
       
   231  * PerfTraceTime and PerfTraceTimedEvent below.
       
   232  *
       
   233  * Always-on non-sampled counters can be created independent of
       
   234  * the UsePerfData flag. Counters will be created on the c-heap
       
   235  * if UsePerfData is false.
       
   236  *
       
   237  * Until further notice, all PerfData objects should be created and
       
   238  * manipulated within a guarded block. The guard variable is
       
   239  * UsePerfData, a product flag set to true by default. This flag may
       
   240  * be removed from the product in the future.
       
   241  *
       
   242  */
       
   243 class PerfData : public CHeapObj<mtInternal> {
       
   244 
       
   245   friend class StatSampler;      // for access to protected void sample()
       
   246   friend class PerfDataManager;  // for access to protected destructor
       
   247 
       
   248   public:
       
   249 
       
   250     // the Variability enum must be kept in synchronization with the
       
   251     // the com.sun.hotspot.perfdata.Variability class
       
   252     enum Variability {
       
   253       V_Constant = 1,
       
   254       V_Monotonic = 2,
       
   255       V_Variable = 3,
       
   256       V_last = V_Variable
       
   257     };
       
   258 
       
   259     // the Units enum must be kept in synchronization with the
       
   260     // the com.sun.hotspot.perfdata.Units class
       
   261     enum Units {
       
   262       U_None = 1,
       
   263       U_Bytes = 2,
       
   264       U_Ticks = 3,
       
   265       U_Events = 4,
       
   266       U_String = 5,
       
   267       U_Hertz = 6,
       
   268       U_Last = U_Hertz
       
   269     };
       
   270 
       
   271     // Miscellaneous flags
       
   272     enum Flags {
       
   273       F_None = 0x0,
       
   274       F_Supported = 0x1    // interface is supported - java.* and com.sun.*
       
   275     };
       
   276 
       
   277   private:
       
   278     char* _name;
       
   279     Variability _v;
       
   280     Units _u;
       
   281     bool _on_c_heap;
       
   282     Flags _flags;
       
   283 
       
   284     PerfDataEntry* _pdep;
       
   285 
       
   286   protected:
       
   287 
       
   288     void *_valuep;
       
   289 
       
   290     PerfData(CounterNS ns, const char* name, Units u, Variability v);
       
   291     virtual ~PerfData();
       
   292 
       
   293     // create the entry for the PerfData item in the PerfData memory region.
       
   294     // this region is maintained separately from the PerfData objects to
       
   295     // facilitate its use by external processes.
       
   296     void create_entry(BasicType dtype, size_t dsize, size_t dlen = 0);
       
   297 
       
   298     // sample the data item given at creation time and write its value
       
   299     // into the its corresponding PerfMemory location.
       
   300     virtual void sample() = 0;
       
   301 
       
   302   public:
       
   303 
       
   304     // returns a boolean indicating the validity of this object.
       
   305     // the object is valid if and only if memory in PerfMemory
       
   306     // region was successfully allocated.
       
   307     inline bool is_valid() { return _valuep != NULL; }
       
   308 
       
   309     // returns a boolean indicating whether the underlying object
       
   310     // was allocated in the PerfMemory region or on the C heap.
       
   311     inline bool is_on_c_heap() { return _on_c_heap; }
       
   312 
       
   313     // returns a pointer to a char* containing the name of the item.
       
   314     // The pointer returned is the pointer to a copy of the name
       
   315     // passed to the constructor, not the pointer to the name in the
       
   316     // PerfData memory region. This redundancy is maintained for
       
   317     // security reasons as the PerfMemory region may be in shared
       
   318     // memory.
       
   319     const char* name() { return _name; }
       
   320 
       
   321     // returns the variability classification associated with this item
       
   322     Variability variability() { return _v; }
       
   323 
       
   324     // returns the units associated with this item.
       
   325     Units units() { return _u; }
       
   326 
       
   327     // returns the flags associated with this item.
       
   328     Flags flags() { return _flags; }
       
   329 
       
   330     // returns the address of the data portion of the item in the
       
   331     // PerfData memory region.
       
   332     inline void* get_address() { return _valuep; }
       
   333 
       
   334     // returns the value of the data portion of the item in the
       
   335     // PerfData memory region formatted as a string.
       
   336     virtual int format(char* cp, int length) = 0;
       
   337 };
       
   338 
       
   339 /*
       
   340  * PerfLongSampleHelper, and its alias PerfSamplerHelper, is a base class
       
   341  * for helper classes that rely upon the StatSampler periodic task to
       
   342  * invoke the take_sample() method and write the value returned to its
       
   343  * appropriate location in the PerfData memory region.
       
   344  */
       
   345 class PerfLongSampleHelper : public CHeapObj<mtInternal> {
       
   346   public:
       
   347     virtual jlong take_sample() = 0;
       
   348 };
       
   349 
       
   350 typedef PerfLongSampleHelper PerfSampleHelper;
       
   351 
       
   352 
       
   353 /*
       
   354  * PerfLong is the base class for the various Long PerfData subtypes.
       
   355  * it contains implementation details that are common among its derived
       
   356  * types.
       
   357  */
       
   358 class PerfLong : public PerfData {
       
   359 
       
   360   protected:
       
   361 
       
   362     PerfLong(CounterNS ns, const char* namep, Units u, Variability v);
       
   363 
       
   364   public:
       
   365     int format(char* buffer, int length);
       
   366 
       
   367     // returns the value of the data portion of the item in the
       
   368     // PerfData memory region.
       
   369     inline jlong get_value() { return *(jlong*)_valuep; }
       
   370 };
       
   371 
       
   372 /*
       
   373  * The PerfLongConstant class, and its alias PerfConstant, implement
       
   374  * a PerfData subtype that holds a jlong data value that is set upon
       
   375  * creation of an instance of this class. This class provides no
       
   376  * methods for changing the data value stored in PerfData memory region.
       
   377  */
       
   378 class PerfLongConstant : public PerfLong {
       
   379 
       
   380   friend class PerfDataManager; // for access to protected constructor
       
   381 
       
   382   private:
       
   383     // hide sample() - no need to sample constants
       
   384     void sample() { }
       
   385 
       
   386   protected:
       
   387 
       
   388     PerfLongConstant(CounterNS ns, const char* namep, Units u,
       
   389                      jlong initial_value=0)
       
   390                     : PerfLong(ns, namep, u, V_Constant) {
       
   391 
       
   392        if (is_valid()) *(jlong*)_valuep = initial_value;
       
   393     }
       
   394 };
       
   395 
       
   396 typedef PerfLongConstant PerfConstant;
       
   397 
       
   398 /*
       
   399  * The PerfLongVariant class, and its alias PerfVariant, implement
       
   400  * a PerfData subtype that holds a jlong data value that can be modified
       
   401  * in an unrestricted manner. This class provides the implementation details
       
   402  * for common functionality among its derived types.
       
   403  */
       
   404 class PerfLongVariant : public PerfLong {
       
   405 
       
   406   protected:
       
   407     jlong* _sampled;
       
   408     PerfLongSampleHelper* _sample_helper;
       
   409 
       
   410     PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
       
   411                     jlong initial_value=0)
       
   412                    : PerfLong(ns, namep, u, v) {
       
   413       if (is_valid()) *(jlong*)_valuep = initial_value;
       
   414     }
       
   415 
       
   416     PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
       
   417                     jlong* sampled);
       
   418 
       
   419     PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
       
   420                     PerfLongSampleHelper* sample_helper);
       
   421 
       
   422     void sample();
       
   423 
       
   424   public:
       
   425     inline void inc() { (*(jlong*)_valuep)++; }
       
   426     inline void inc(jlong val) { (*(jlong*)_valuep) += val; }
       
   427     inline void dec(jlong val) { inc(-val); }
       
   428     inline void add(jlong val) { (*(jlong*)_valuep) += val; }
       
   429     void clear_sample_helper() { _sample_helper = NULL; }
       
   430 };
       
   431 
       
   432 /*
       
   433  * The PerfLongCounter class, and its alias PerfCounter, implement
       
   434  * a PerfData subtype that holds a jlong data value that can (should)
       
   435  * be modified in a monotonic manner. The inc(jlong) and add(jlong)
       
   436  * methods can be passed negative values to implement a monotonically
       
   437  * decreasing value. However, we rely upon the programmer to honor
       
   438  * the notion that this counter always moves in the same direction -
       
   439  * either increasing or decreasing.
       
   440  */
       
   441 class PerfLongCounter : public PerfLongVariant {
       
   442 
       
   443   friend class PerfDataManager; // for access to protected constructor
       
   444 
       
   445   protected:
       
   446 
       
   447     PerfLongCounter(CounterNS ns, const char* namep, Units u,
       
   448                     jlong initial_value=0)
       
   449                    : PerfLongVariant(ns, namep, u, V_Monotonic,
       
   450                                      initial_value) { }
       
   451 
       
   452     PerfLongCounter(CounterNS ns, const char* namep, Units u, jlong* sampled)
       
   453                   : PerfLongVariant(ns, namep, u, V_Monotonic, sampled) { }
       
   454 
       
   455     PerfLongCounter(CounterNS ns, const char* namep, Units u,
       
   456                     PerfLongSampleHelper* sample_helper)
       
   457                    : PerfLongVariant(ns, namep, u, V_Monotonic,
       
   458                                      sample_helper) { }
       
   459 };
       
   460 
       
   461 typedef PerfLongCounter PerfCounter;
       
   462 
       
   463 /*
       
   464  * The PerfLongVariable class, and its alias PerfVariable, implement
       
   465  * a PerfData subtype that holds a jlong data value that can
       
   466  * be modified in an unrestricted manner.
       
   467  */
       
   468 class PerfLongVariable : public PerfLongVariant {
       
   469 
       
   470   friend class PerfDataManager; // for access to protected constructor
       
   471 
       
   472   protected:
       
   473 
       
   474     PerfLongVariable(CounterNS ns, const char* namep, Units u,
       
   475                      jlong initial_value=0)
       
   476                     : PerfLongVariant(ns, namep, u, V_Variable,
       
   477                                       initial_value) { }
       
   478 
       
   479     PerfLongVariable(CounterNS ns, const char* namep, Units u, jlong* sampled)
       
   480                     : PerfLongVariant(ns, namep, u, V_Variable, sampled) { }
       
   481 
       
   482     PerfLongVariable(CounterNS ns, const char* namep, Units u,
       
   483                      PerfLongSampleHelper* sample_helper)
       
   484                     : PerfLongVariant(ns, namep, u, V_Variable,
       
   485                                       sample_helper) { }
       
   486 
       
   487   public:
       
   488     inline void set_value(jlong val) { (*(jlong*)_valuep) = val; }
       
   489 };
       
   490 
       
   491 typedef PerfLongVariable PerfVariable;
       
   492 
       
   493 /*
       
   494  * The PerfByteArray provides a PerfData subtype that allows the creation
       
   495  * of a contiguous region of the PerfData memory region for storing a vector
       
   496  * of bytes. This class is currently intended to be a base class for
       
   497  * the PerfString class, and cannot be instantiated directly.
       
   498  */
       
   499 class PerfByteArray : public PerfData {
       
   500 
       
   501   protected:
       
   502     jint _length;
       
   503 
       
   504     PerfByteArray(CounterNS ns, const char* namep, Units u, Variability v,
       
   505                   jint length);
       
   506 };
       
   507 
       
   508 class PerfString : public PerfByteArray {
       
   509 
       
   510   protected:
       
   511 
       
   512     void set_string(const char* s2);
       
   513 
       
   514     PerfString(CounterNS ns, const char* namep, Variability v, jint length,
       
   515                const char* initial_value)
       
   516               : PerfByteArray(ns, namep, U_String, v, length) {
       
   517        if (is_valid()) set_string(initial_value);
       
   518     }
       
   519 
       
   520   public:
       
   521 
       
   522     int format(char* buffer, int length);
       
   523 };
       
   524 
       
   525 /*
       
   526  * The PerfStringConstant class provides a PerfData sub class that
       
   527  * allows a null terminated string of single byte characters to be
       
   528  * stored in the PerfData memory region.
       
   529  */
       
   530 class PerfStringConstant : public PerfString {
       
   531 
       
   532   friend class PerfDataManager; // for access to protected constructor
       
   533 
       
   534   private:
       
   535 
       
   536     // hide sample() - no need to sample constants
       
   537     void sample() { }
       
   538 
       
   539   protected:
       
   540 
       
   541     // Restrict string constant lengths to be <= PerfMaxStringConstLength.
       
   542     // This prevents long string constants, as can occur with very
       
   543     // long classpaths or java command lines, from consuming too much
       
   544     // PerfData memory.
       
   545     PerfStringConstant(CounterNS ns, const char* namep,
       
   546                        const char* initial_value);
       
   547 };
       
   548 
       
   549 /*
       
   550  * The PerfStringVariable class provides a PerfData sub class that
       
   551  * allows a null terminated string of single byte character data
       
   552  * to be stored in PerfData memory region. The string value can be reset
       
   553  * after initialization. If the string value is >= max_length, then
       
   554  * it will be truncated to max_length characters. The copied string
       
   555  * is always null terminated.
       
   556  */
       
   557 class PerfStringVariable : public PerfString {
       
   558 
       
   559   friend class PerfDataManager; // for access to protected constructor
       
   560 
       
   561   protected:
       
   562 
       
   563     // sampling of string variables are not yet supported
       
   564     void sample() { }
       
   565 
       
   566     PerfStringVariable(CounterNS ns, const char* namep, jint max_length,
       
   567                        const char* initial_value)
       
   568                       : PerfString(ns, namep, V_Variable, max_length+1,
       
   569                                    initial_value) { }
       
   570 
       
   571   public:
       
   572     inline void set_value(const char* val) { set_string(val); }
       
   573 };
       
   574 
       
   575 
       
   576 /*
       
   577  * The PerfDataList class is a container class for managing lists
       
   578  * of PerfData items. The intention of this class is to allow for
       
   579  * alternative implementations for management of list of PerfData
       
   580  * items without impacting the code that uses the lists.
       
   581  *
       
   582  * The initial implementation is based upon GrowableArray. Searches
       
   583  * on GrowableArray types is linear in nature and this may become
       
   584  * a performance issue for creation of PerfData items, particularly
       
   585  * from Java code where a test for existence is implemented as a
       
   586  * search over all existing PerfData items.
       
   587  *
       
   588  * The abstraction is not complete. A more general container class
       
   589  * would provide an Iterator abstraction that could be used to
       
   590  * traverse the lists. This implementation still relies upon integer
       
   591  * iterators and the at(int index) method. However, the GrowableArray
       
   592  * is not directly visible outside this class and can be replaced by
       
   593  * some other implementation, as long as that implementation provides
       
   594  * a mechanism to iterate over the container by index.
       
   595  */
       
   596 class PerfDataList : public CHeapObj<mtInternal> {
       
   597 
       
   598   private:
       
   599 
       
   600     // GrowableArray implementation
       
   601     typedef GrowableArray<PerfData*> PerfDataArray;
       
   602 
       
   603     PerfDataArray* _set;
       
   604 
       
   605     // method to search for a instrumentation object by name
       
   606     static bool by_name(void* name, PerfData* pd);
       
   607 
       
   608   protected:
       
   609     // we expose the implementation here to facilitate the clone
       
   610     // method.
       
   611     PerfDataArray* get_impl() { return _set; }
       
   612 
       
   613   public:
       
   614 
       
   615     // create a PerfDataList with the given initial length
       
   616     PerfDataList(int length);
       
   617 
       
   618     // create a PerfDataList as a shallow copy of the given PerfDataList
       
   619     PerfDataList(PerfDataList* p);
       
   620 
       
   621     ~PerfDataList();
       
   622 
       
   623     // return the PerfData item indicated by name,
       
   624     // or NULL if it doesn't exist.
       
   625     PerfData* find_by_name(const char* name);
       
   626 
       
   627     // return true if a PerfData item with the name specified in the
       
   628     // argument exists, otherwise return false.
       
   629     bool contains(const char* name) { return find_by_name(name) != NULL; }
       
   630 
       
   631     // return the number of PerfData items in this list
       
   632     int length() { return _set->length(); }
       
   633 
       
   634     // add a PerfData item to this list
       
   635     void append(PerfData *p) { _set->append(p); }
       
   636 
       
   637     // remove the given PerfData item from this list. When called
       
   638     // while iterating over the list, this method will result in a
       
   639     // change in the length of the container. The at(int index)
       
   640     // method is also impacted by this method as elements with an
       
   641     // index greater than the index of the element removed by this
       
   642     // method will be shifted down by one.
       
   643     void remove(PerfData *p) { _set->remove(p); }
       
   644 
       
   645     // create a new PerfDataList from this list. The new list is
       
   646     // a shallow copy of the original list and care should be taken
       
   647     // with respect to delete operations on the elements of the list
       
   648     // as the are likely in use by another copy of the list.
       
   649     PerfDataList* clone();
       
   650 
       
   651     // for backward compatibility with GrowableArray - need to implement
       
   652     // some form of iterator to provide a cleaner abstraction for
       
   653     // iteration over the container.
       
   654     PerfData* at(int index) { return _set->at(index); }
       
   655 };
       
   656 
       
   657 
       
   658 /*
       
   659  * The PerfDataManager class is responsible for creating PerfData
       
   660  * subtypes via a set a factory methods and for managing lists
       
   661  * of the various PerfData types.
       
   662  */
       
   663 class PerfDataManager : AllStatic {
       
   664 
       
   665   friend class StatSampler;   // for access to protected PerfDataList methods
       
   666 
       
   667   private:
       
   668     static PerfDataList* _all;
       
   669     static PerfDataList* _sampled;
       
   670     static PerfDataList* _constants;
       
   671     static const char* _name_spaces[];
       
   672     static volatile bool _has_PerfData;
       
   673 
       
   674     // add a PerfData item to the list(s) of know PerfData objects
       
   675     static void add_item(PerfData* p, bool sampled);
       
   676 
       
   677   protected:
       
   678     // return the list of all known PerfData items
       
   679     static PerfDataList* all();
       
   680     static int count() { return _all->length(); }
       
   681 
       
   682     // return the list of all known PerfData items that are to be
       
   683     // sampled by the StatSampler.
       
   684     static PerfDataList* sampled();
       
   685     static int sampled_count() { return _sampled->length(); }
       
   686 
       
   687     // return the list of all known PerfData items that have a
       
   688     // variability classification of type Constant
       
   689     static PerfDataList* constants();
       
   690     static int constants_count() { return _constants->length(); }
       
   691 
       
   692   public:
       
   693 
       
   694     // method to check for the existence of a PerfData item with
       
   695     // the given name.
       
   696     static bool exists(const char* name) { return _all->contains(name); }
       
   697 
       
   698     // method to search for a instrumentation object by name
       
   699     static PerfData* find_by_name(const char* name);
       
   700 
       
   701     // method to map a CounterNS enumeration to a namespace string
       
   702     static const char* ns_to_string(CounterNS ns) {
       
   703       return _name_spaces[ns];
       
   704     }
       
   705 
       
   706     // methods to test the interface stability of a given counter namespace
       
   707     //
       
   708     static bool is_stable_supported(CounterNS ns) {
       
   709       return (ns != NULL_NS) && ((ns % 3) == JAVA_NS);
       
   710     }
       
   711     static bool is_unstable_supported(CounterNS ns) {
       
   712       return (ns != NULL_NS) && ((ns % 3) == COM_NS);
       
   713     }
       
   714     static bool is_unstable_unsupported(CounterNS ns) {
       
   715       return (ns == NULL_NS) || ((ns % 3) == SUN_NS);
       
   716     }
       
   717 
       
   718     // methods to test the interface stability of a given counter name
       
   719     //
       
   720     static bool is_stable_supported(const char* name) {
       
   721       const char* javadot = "java.";
       
   722       return strncmp(name, javadot, strlen(javadot)) == 0;
       
   723     }
       
   724     static bool is_unstable_supported(const char* name) {
       
   725       const char* comdot = "com.sun.";
       
   726       return strncmp(name, comdot, strlen(comdot)) == 0;
       
   727     }
       
   728     static bool is_unstable_unsupported(const char* name) {
       
   729       return !(is_stable_supported(name) && is_unstable_supported(name));
       
   730     }
       
   731 
       
   732     // method to construct counter name strings in a given name space.
       
   733     // The string object is allocated from the Resource Area and calls
       
   734     // to this method must be made within a ResourceMark.
       
   735     //
       
   736     static char* counter_name(const char* name_space, const char* name);
       
   737 
       
   738     // method to construct name space strings in a given name space.
       
   739     // The string object is allocated from the Resource Area and calls
       
   740     // to this method must be made within a ResourceMark.
       
   741     //
       
   742     static char* name_space(const char* name_space, const char* sub_space) {
       
   743       return counter_name(name_space, sub_space);
       
   744     }
       
   745 
       
   746     // same as above, but appends the instance number to the name space
       
   747     //
       
   748     static char* name_space(const char* name_space, const char* sub_space,
       
   749                             int instance);
       
   750     static char* name_space(const char* name_space, int instance);
       
   751 
       
   752 
       
   753     // these methods provide the general interface for creating
       
   754     // performance data resources. The types of performance data
       
   755     // resources can be extended by adding additional create<type>
       
   756     // methods.
       
   757 
       
   758     // Constant Types
       
   759     static PerfStringConstant* create_string_constant(CounterNS ns,
       
   760                                                       const char* name,
       
   761                                                       const char *s, TRAPS);
       
   762 
       
   763     static PerfLongConstant* create_long_constant(CounterNS ns,
       
   764                                                   const char* name,
       
   765                                                   PerfData::Units u,
       
   766                                                   jlong val, TRAPS);
       
   767 
       
   768 
       
   769     // Variable Types
       
   770     static PerfStringVariable* create_string_variable(CounterNS ns,
       
   771                                                       const char* name,
       
   772                                                       int max_length,
       
   773                                                       const char *s, TRAPS);
       
   774 
       
   775     static PerfStringVariable* create_string_variable(CounterNS ns,
       
   776                                                       const char* name,
       
   777                                                       const char *s, TRAPS) {
       
   778       return create_string_variable(ns, name, 0, s, THREAD);
       
   779     };
       
   780 
       
   781     static PerfLongVariable* create_long_variable(CounterNS ns,
       
   782                                                   const char* name,
       
   783                                                   PerfData::Units u,
       
   784                                                   jlong ival, TRAPS);
       
   785 
       
   786     static PerfLongVariable* create_long_variable(CounterNS ns,
       
   787                                                   const char* name,
       
   788                                                   PerfData::Units u, TRAPS) {
       
   789       return create_long_variable(ns, name, u, (jlong)0, THREAD);
       
   790     };
       
   791 
       
   792     static PerfLongVariable* create_long_variable(CounterNS, const char* name,
       
   793                                                   PerfData::Units u,
       
   794                                                   jlong* sp, TRAPS);
       
   795 
       
   796     static PerfLongVariable* create_long_variable(CounterNS ns,
       
   797                                                   const char* name,
       
   798                                                   PerfData::Units u,
       
   799                                                   PerfLongSampleHelper* sh,
       
   800                                                   TRAPS);
       
   801 
       
   802 
       
   803     // Counter Types
       
   804     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
       
   805                                                 PerfData::Units u,
       
   806                                                 jlong ival, TRAPS);
       
   807 
       
   808     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
       
   809                                                 PerfData::Units u, TRAPS) {
       
   810       return create_long_counter(ns, name, u, (jlong)0, THREAD);
       
   811     };
       
   812 
       
   813     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
       
   814                                                 PerfData::Units u, jlong* sp,
       
   815                                                 TRAPS);
       
   816 
       
   817     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
       
   818                                                 PerfData::Units u,
       
   819                                                 PerfLongSampleHelper* sh,
       
   820                                                 TRAPS);
       
   821 
       
   822 
       
   823     // these creation methods are provided for ease of use. These allow
       
   824     // Long performance data types to be created with a shorthand syntax.
       
   825 
       
   826     static PerfConstant* create_constant(CounterNS ns, const char* name,
       
   827                                          PerfData::Units u, jlong val, TRAPS) {
       
   828       return create_long_constant(ns, name, u, val, THREAD);
       
   829     }
       
   830 
       
   831     static PerfVariable* create_variable(CounterNS ns, const char* name,
       
   832                                          PerfData::Units u, jlong ival, TRAPS) {
       
   833       return create_long_variable(ns, name, u, ival, THREAD);
       
   834     }
       
   835 
       
   836     static PerfVariable* create_variable(CounterNS ns, const char* name,
       
   837                                          PerfData::Units u, TRAPS) {
       
   838       return create_long_variable(ns, name, u, (jlong)0, THREAD);
       
   839     }
       
   840 
       
   841     static PerfVariable* create_variable(CounterNS ns, const char* name,
       
   842                                          PerfData::Units u, jlong* sp, TRAPS) {
       
   843       return create_long_variable(ns, name, u, sp, THREAD);
       
   844     }
       
   845 
       
   846     static PerfVariable* create_variable(CounterNS ns, const char* name,
       
   847                                          PerfData::Units u,
       
   848                                          PerfSampleHelper* sh, TRAPS) {
       
   849       return create_long_variable(ns, name, u, sh, THREAD);
       
   850     }
       
   851 
       
   852     static PerfCounter* create_counter(CounterNS ns, const char* name,
       
   853                                        PerfData::Units u, jlong ival, TRAPS) {
       
   854       return create_long_counter(ns, name, u, ival, THREAD);
       
   855     }
       
   856 
       
   857     static PerfCounter* create_counter(CounterNS ns, const char* name,
       
   858                                        PerfData::Units u, TRAPS) {
       
   859       return create_long_counter(ns, name, u, (jlong)0, THREAD);
       
   860     }
       
   861 
       
   862     static PerfCounter* create_counter(CounterNS ns, const char* name,
       
   863                                        PerfData::Units u, jlong* sp, TRAPS) {
       
   864       return create_long_counter(ns, name, u, sp, THREAD);
       
   865     }
       
   866 
       
   867     static PerfCounter* create_counter(CounterNS ns, const char* name,
       
   868                                        PerfData::Units u,
       
   869                                        PerfSampleHelper* sh, TRAPS) {
       
   870       return create_long_counter(ns, name, u, sh, THREAD);
       
   871     }
       
   872 
       
   873     static void destroy();
       
   874     static bool has_PerfData() { return _has_PerfData; }
       
   875 };
       
   876 
       
   877 // Useful macros to create the performance counters
       
   878 #define NEWPERFTICKCOUNTER(counter, counter_ns, counter_name)  \
       
   879   {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
       
   880                                              PerfData::U_Ticks,CHECK);}
       
   881 
       
   882 #define NEWPERFEVENTCOUNTER(counter, counter_ns, counter_name)  \
       
   883   {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
       
   884                                              PerfData::U_Events,CHECK);}
       
   885 
       
   886 #define NEWPERFBYTECOUNTER(counter, counter_ns, counter_name)  \
       
   887   {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
       
   888                                              PerfData::U_Bytes,CHECK);}
       
   889 
       
   890 // Utility Classes
       
   891 
       
   892 /*
       
   893  * this class will administer a PerfCounter used as a time accumulator
       
   894  * for a basic block much like the TraceTime class.
       
   895  *
       
   896  * Example:
       
   897  *
       
   898  *    static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, 0LL, CHECK);
       
   899  *
       
   900  *    {
       
   901  *      PerfTraceTime ptt(my_time_counter);
       
   902  *      // perform the operation you want to measure
       
   903  *    }
       
   904  *
       
   905  * Note: use of this class does not need to occur within a guarded
       
   906  * block. The UsePerfData guard is used with the implementation
       
   907  * of this class.
       
   908  */
       
   909 class PerfTraceTime : public StackObj {
       
   910 
       
   911   protected:
       
   912     elapsedTimer _t;
       
   913     PerfLongCounter* _timerp;
       
   914     // pointer to thread-local or global recursion counter variable
       
   915     int* _recursion_counter;
       
   916 
       
   917   public:
       
   918     inline PerfTraceTime(PerfLongCounter* timerp) : _timerp(timerp), _recursion_counter(NULL) {
       
   919       if (!UsePerfData) return;
       
   920       _t.start();
       
   921     }
       
   922 
       
   923     inline PerfTraceTime(PerfLongCounter* timerp, int* recursion_counter) : _timerp(timerp), _recursion_counter(recursion_counter) {
       
   924       if (!UsePerfData || (_recursion_counter != NULL &&
       
   925                            (*_recursion_counter)++ > 0)) return;
       
   926       _t.start();
       
   927     }
       
   928 
       
   929     inline void suspend() { if (!UsePerfData) return; _t.stop(); }
       
   930     inline void resume() { if (!UsePerfData) return; _t.start(); }
       
   931 
       
   932     inline ~PerfTraceTime() {
       
   933       if (!UsePerfData || (_recursion_counter != NULL &&
       
   934                            --(*_recursion_counter) > 0)) return;
       
   935       _t.stop();
       
   936       _timerp->inc(_t.ticks());
       
   937     }
       
   938 };
       
   939 
       
   940 /* The PerfTraceTimedEvent class is responsible for counting the
       
   941  * occurrence of some event and measuring the the elapsed time of
       
   942  * the event in two separate PerfCounter instances.
       
   943  *
       
   944  * Example:
       
   945  *
       
   946  *    static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, CHECK);
       
   947  *    static PerfCounter* my_event_counter = PerfDataManager::create_counter("my.event.counter", PerfData::U_Events, CHECK);
       
   948  *
       
   949  *    {
       
   950  *      PerfTraceTimedEvent ptte(my_time_counter, my_event_counter);
       
   951  *      // perform the operation you want to count and measure
       
   952  *    }
       
   953  *
       
   954  * Note: use of this class does not need to occur within a guarded
       
   955  * block. The UsePerfData guard is used with the implementation
       
   956  * of this class.
       
   957  *
       
   958  */
       
   959 class PerfTraceTimedEvent : public PerfTraceTime {
       
   960 
       
   961   protected:
       
   962     PerfLongCounter* _eventp;
       
   963 
       
   964   public:
       
   965     inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp): PerfTraceTime(timerp), _eventp(eventp) {
       
   966       if (!UsePerfData) return;
       
   967       _eventp->inc();
       
   968     }
       
   969 
       
   970     inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp, int* recursion_counter): PerfTraceTime(timerp, recursion_counter), _eventp(eventp) {
       
   971       if (!UsePerfData) return;
       
   972       _eventp->inc();
       
   973     }
       
   974 };
       
   975 
       
   976 #endif // SHARE_VM_RUNTIME_PERFDATA_HPP