src/share/vm/runtime/perfData.hpp

Wed, 31 Jan 2018 19:24:57 -0500

author
dbuck
date
Wed, 31 Jan 2018 19:24:57 -0500
changeset 9289
427b2fb1944f
parent 6198
55fb97c4c58d
child 6876
710a3c8b516e
permissions
-rw-r--r--

8189170: Add option to disable stack overflow checking in primordial thread for use with JNI_CreateJavaJVM
Reviewed-by: dcubed

     1 /*
     2  * Copyright (c) 2001, 2013, 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  */
    25 #ifndef SHARE_VM_RUNTIME_PERFDATA_HPP
    26 #define SHARE_VM_RUNTIME_PERFDATA_HPP
    28 #include "memory/allocation.inline.hpp"
    29 #include "runtime/perfMemory.hpp"
    30 #include "runtime/timer.hpp"
    31 #include "utilities/growableArray.hpp"
    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 };
    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 variablility 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 untis specified in U_Bytes in the "com.sun.ci
   176  * name space.
   177  *
   178  *   PerfLongVariable* bar_varible;
   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 applyied 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 noice, 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> {
   245   friend class StatSampler;      // for access to protected void sample()
   246   friend class PerfDataManager;  // for access to protected destructor
   248   public:
   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     };
   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     };
   271     // Miscellaneous flags
   272     enum Flags {
   273       F_None = 0x0,
   274       F_Supported = 0x1    // interface is supported - java.* and com.sun.*
   275     };
   277   private:
   278     char* _name;
   279     Variability _v;
   280     Units _u;
   281     bool _on_c_heap;
   282     Flags _flags;
   284     PerfDataEntry* _pdep;
   286   protected:
   288     void *_valuep;
   290     PerfData(CounterNS ns, const char* name, Units u, Variability v);
   291     ~PerfData();
   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);
   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;
   302   public:
   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; }
   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; }
   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; }
   321     // returns the variability classification associated with this item
   322     Variability variability() { return _v; }
   324     // returns the units associated with this item.
   325     Units units() { return _u; }
   327     // returns the flags associated with this item.
   328     Flags flags() { return _flags; }
   330     // returns the address of the data portion of the item in the
   331     // PerfData memory region.
   332     inline void* get_address() { return _valuep; }
   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 };
   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 };
   350 typedef PerfLongSampleHelper PerfSampleHelper;
   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 {
   360   protected:
   362     PerfLong(CounterNS ns, const char* namep, Units u, Variability v);
   364   public:
   365     int format(char* buffer, int length);
   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 };
   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 {
   380   friend class PerfDataManager; // for access to protected constructor
   382   private:
   383     // hide sample() - no need to sample constants
   384     void sample() { }
   386   protected:
   388     PerfLongConstant(CounterNS ns, const char* namep, Units u,
   389                      jlong initial_value=0)
   390                     : PerfLong(ns, namep, u, V_Constant) {
   392        if (is_valid()) *(jlong*)_valuep = initial_value;
   393     }
   394 };
   396 typedef PerfLongConstant PerfConstant;
   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 {
   406   protected:
   407     jlong* _sampled;
   408     PerfLongSampleHelper* _sample_helper;
   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     }
   416     PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
   417                     jlong* sampled);
   419     PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
   420                     PerfLongSampleHelper* sample_helper);
   422     void sample();
   424   public:
   425     inline void inc() { (*(jlong*)_valuep)++; }
   426     inline void inc(jlong val) { (*(jlong*)_valuep) += val; }
   427     inline void add(jlong val) { (*(jlong*)_valuep) += val; }
   428     void clear_sample_helper() { _sample_helper = NULL; }
   429 };
   431 /*
   432  * The PerfLongCounter class, and its alias PerfCounter, implement
   433  * a PerfData subtype that holds a jlong data value that can (should)
   434  * be modified in a monotonic manner. The inc(jlong) and add(jlong)
   435  * methods can be passed negative values to implement a monotonically
   436  * decreasing value. However, we rely upon the programmer to honor
   437  * the notion that this counter always moves in the same direction -
   438  * either increasing or decreasing.
   439  */
   440 class PerfLongCounter : public PerfLongVariant {
   442   friend class PerfDataManager; // for access to protected constructor
   444   protected:
   446     PerfLongCounter(CounterNS ns, const char* namep, Units u,
   447                     jlong initial_value=0)
   448                    : PerfLongVariant(ns, namep, u, V_Monotonic,
   449                                      initial_value) { }
   451     PerfLongCounter(CounterNS ns, const char* namep, Units u, jlong* sampled)
   452                   : PerfLongVariant(ns, namep, u, V_Monotonic, sampled) { }
   454     PerfLongCounter(CounterNS ns, const char* namep, Units u,
   455                     PerfLongSampleHelper* sample_helper)
   456                    : PerfLongVariant(ns, namep, u, V_Monotonic,
   457                                      sample_helper) { }
   458 };
   460 typedef PerfLongCounter PerfCounter;
   462 /*
   463  * The PerfLongVariable class, and its alias PerfVariable, implement
   464  * a PerfData subtype that holds a jlong data value that can
   465  * be modified in an unrestricted manner.
   466  */
   467 class PerfLongVariable : public PerfLongVariant {
   469   friend class PerfDataManager; // for access to protected constructor
   471   protected:
   473     PerfLongVariable(CounterNS ns, const char* namep, Units u,
   474                      jlong initial_value=0)
   475                     : PerfLongVariant(ns, namep, u, V_Variable,
   476                                       initial_value) { }
   478     PerfLongVariable(CounterNS ns, const char* namep, Units u, jlong* sampled)
   479                     : PerfLongVariant(ns, namep, u, V_Variable, sampled) { }
   481     PerfLongVariable(CounterNS ns, const char* namep, Units u,
   482                      PerfLongSampleHelper* sample_helper)
   483                     : PerfLongVariant(ns, namep, u, V_Variable,
   484                                       sample_helper) { }
   486   public:
   487     inline void set_value(jlong val) { (*(jlong*)_valuep) = val; }
   488 };
   490 typedef PerfLongVariable PerfVariable;
   492 /*
   493  * The PerfByteArray provides a PerfData subtype that allows the creation
   494  * of a contiguous region of the PerfData memory region for storing a vector
   495  * of bytes. This class is currently intended to be a base class for
   496  * the PerfString class, and cannot be instantiated directly.
   497  */
   498 class PerfByteArray : public PerfData {
   500   protected:
   501     jint _length;
   503     PerfByteArray(CounterNS ns, const char* namep, Units u, Variability v,
   504                   jint length);
   505 };
   507 class PerfString : public PerfByteArray {
   509   protected:
   511     void set_string(const char* s2);
   513     PerfString(CounterNS ns, const char* namep, Variability v, jint length,
   514                const char* initial_value)
   515               : PerfByteArray(ns, namep, U_String, v, length) {
   516        if (is_valid()) set_string(initial_value);
   517     }
   519   public:
   521     int format(char* buffer, int length);
   522 };
   524 /*
   525  * The PerfStringConstant class provides a PerfData sub class that
   526  * allows a null terminated string of single byte characters to be
   527  * stored in the PerfData memory region.
   528  */
   529 class PerfStringConstant : public PerfString {
   531   friend class PerfDataManager; // for access to protected constructor
   533   private:
   535     // hide sample() - no need to sample constants
   536     void sample() { }
   538   protected:
   540     // Restrict string constant lengths to be <= PerfMaxStringConstLength.
   541     // This prevents long string constants, as can occur with very
   542     // long classpaths or java command lines, from consuming too much
   543     // PerfData memory.
   544     PerfStringConstant(CounterNS ns, const char* namep,
   545                        const char* initial_value);
   546 };
   548 /*
   549  * The PerfStringVariable class provides a PerfData sub class that
   550  * allows a null terminated string of single byte character data
   551  * to be stored in PerfData memory region. The string value can be reset
   552  * after initialization. If the string value is >= max_length, then
   553  * it will be truncated to max_length characters. The copied string
   554  * is always null terminated.
   555  */
   556 class PerfStringVariable : public PerfString {
   558   friend class PerfDataManager; // for access to protected constructor
   560   protected:
   562     // sampling of string variables are not yet supported
   563     void sample() { }
   565     PerfStringVariable(CounterNS ns, const char* namep, jint max_length,
   566                        const char* initial_value)
   567                       : PerfString(ns, namep, V_Variable, max_length+1,
   568                                    initial_value) { }
   570   public:
   571     inline void set_value(const char* val) { set_string(val); }
   572 };
   575 /*
   576  * The PerfDataList class is a container class for managing lists
   577  * of PerfData items. The intention of this class is to allow for
   578  * alternative implementations for management of list of PerfData
   579  * items without impacting the code that uses the lists.
   580  *
   581  * The initial implementation is based upon GrowableArray. Searches
   582  * on GrowableArray types is linear in nature and this may become
   583  * a performance issue for creation of PerfData items, particularly
   584  * from Java code where a test for existence is implemented as a
   585  * search over all existing PerfData items.
   586  *
   587  * The abstraction is not complete. A more general container class
   588  * would provide an Iterator abstraction that could be used to
   589  * traverse the lists. This implementation still relys upon integer
   590  * iterators and the at(int index) method. However, the GrowableArray
   591  * is not directly visible outside this class and can be replaced by
   592  * some other implementation, as long as that implementation provides
   593  * a mechanism to iterate over the container by index.
   594  */
   595 class PerfDataList : public CHeapObj<mtInternal> {
   597   private:
   599     // GrowableArray implementation
   600     typedef GrowableArray<PerfData*> PerfDataArray;
   602     PerfDataArray* _set;
   604     // method to search for a instrumentation object by name
   605     static bool by_name(void* name, PerfData* pd);
   607   protected:
   608     // we expose the implementation here to facilitate the clone
   609     // method.
   610     PerfDataArray* get_impl() { return _set; }
   612   public:
   614     // create a PerfDataList with the given initial length
   615     PerfDataList(int length);
   617     // create a PerfDataList as a shallow copy of the given PerfDataList
   618     PerfDataList(PerfDataList* p);
   620     ~PerfDataList();
   622     // return the PerfData item indicated by name,
   623     // or NULL if it doesn't exist.
   624     PerfData* find_by_name(const char* name);
   626     // return true if a PerfData item with the name specified in the
   627     // argument exists, otherwise return false.
   628     bool contains(const char* name) { return find_by_name(name) != NULL; }
   630     // return the number of PerfData items in this list
   631     int length() { return _set->length(); }
   633     // add a PerfData item to this list
   634     void append(PerfData *p) { _set->append(p); }
   636     // remove the given PerfData item from this list. When called
   637     // while iterating over the list, this method will result in a
   638     // change in the length of the container. The at(int index)
   639     // method is also impacted by this method as elements with an
   640     // index greater than the index of the element removed by this
   641     // method will be shifted down by one.
   642     void remove(PerfData *p) { _set->remove(p); }
   644     // create a new PerfDataList from this list. The new list is
   645     // a shallow copy of the original list and care should be taken
   646     // with respect to delete operations on the elements of the list
   647     // as the are likely in use by another copy of the list.
   648     PerfDataList* clone();
   650     // for backward compatibility with GrowableArray - need to implement
   651     // some form of iterator to provide a cleaner abstraction for
   652     // iteration over the container.
   653     PerfData* at(int index) { return _set->at(index); }
   654 };
   657 /*
   658  * The PerfDataManager class is responsible for creating PerfData
   659  * subtypes via a set a factory methods and for managing lists
   660  * of the various PerfData types.
   661  */
   662 class PerfDataManager : AllStatic {
   664   friend class StatSampler;   // for access to protected PerfDataList methods
   666   private:
   667     static PerfDataList* _all;
   668     static PerfDataList* _sampled;
   669     static PerfDataList* _constants;
   670     static const char* _name_spaces[];
   672     // add a PerfData item to the list(s) of know PerfData objects
   673     static void add_item(PerfData* p, bool sampled);
   675   protected:
   676     // return the list of all known PerfData items
   677     static PerfDataList* all();
   678     static int count() { return _all->length(); }
   680     // return the list of all known PerfData items that are to be
   681     // sampled by the StatSampler.
   682     static PerfDataList* sampled();
   683     static int sampled_count() { return _sampled->length(); }
   685     // return the list of all known PerfData items that have a
   686     // variability classification of type Constant
   687     static PerfDataList* constants();
   688     static int constants_count() { return _constants->length(); }
   690   public:
   692     // method to check for the existence of a PerfData item with
   693     // the given name.
   694     static bool exists(const char* name) { return _all->contains(name); }
   696     // method to search for a instrumentation object by name
   697     static PerfData* find_by_name(const char* name);
   699     // method to map a CounterNS enumeration to a namespace string
   700     static const char* ns_to_string(CounterNS ns) {
   701       return _name_spaces[ns];
   702     }
   704     // methods to test the interface stability of a given counter namespace
   705     //
   706     static bool is_stable_supported(CounterNS ns) {
   707       return (ns != NULL_NS) && ((ns % 3) == JAVA_NS);
   708     }
   709     static bool is_unstable_supported(CounterNS ns) {
   710       return (ns != NULL_NS) && ((ns % 3) == COM_NS);
   711     }
   712     static bool is_unstable_unsupported(CounterNS ns) {
   713       return (ns == NULL_NS) || ((ns % 3) == SUN_NS);
   714     }
   716     // methods to test the interface stability of a given counter name
   717     //
   718     static bool is_stable_supported(const char* name) {
   719       const char* javadot = "java.";
   720       return strncmp(name, javadot, strlen(javadot)) == 0;
   721     }
   722     static bool is_unstable_supported(const char* name) {
   723       const char* comdot = "com.sun.";
   724       return strncmp(name, comdot, strlen(comdot)) == 0;
   725     }
   726     static bool is_unstable_unsupported(const char* name) {
   727       return !(is_stable_supported(name) && is_unstable_supported(name));
   728     }
   730     // method to construct counter name strings in a given name space.
   731     // The string object is allocated from the Resource Area and calls
   732     // to this method must be made within a ResourceMark.
   733     //
   734     static char* counter_name(const char* name_space, const char* name);
   736     // method to construct name space strings in a given name space.
   737     // The string object is allocated from the Resource Area and calls
   738     // to this method must be made within a ResourceMark.
   739     //
   740     static char* name_space(const char* name_space, const char* sub_space) {
   741       return counter_name(name_space, sub_space);
   742     }
   744     // same as above, but appends the instance number to the name space
   745     //
   746     static char* name_space(const char* name_space, const char* sub_space,
   747                             int instance);
   748     static char* name_space(const char* name_space, int instance);
   751     // these methods provide the general interface for creating
   752     // performance data resources. The types of performance data
   753     // resources can be extended by adding additional create<type>
   754     // methods.
   756     // Constant Types
   757     static PerfStringConstant* create_string_constant(CounterNS ns,
   758                                                       const char* name,
   759                                                       const char *s, TRAPS);
   761     static PerfLongConstant* create_long_constant(CounterNS ns,
   762                                                   const char* name,
   763                                                   PerfData::Units u,
   764                                                   jlong val, TRAPS);
   767     // Variable Types
   768     static PerfStringVariable* create_string_variable(CounterNS ns,
   769                                                       const char* name,
   770                                                       int max_length,
   771                                                       const char *s, TRAPS);
   773     static PerfStringVariable* create_string_variable(CounterNS ns,
   774                                                       const char* name,
   775                                                       const char *s, TRAPS) {
   776       return create_string_variable(ns, name, 0, s, CHECK_NULL);
   777     };
   779     static PerfLongVariable* create_long_variable(CounterNS ns,
   780                                                   const char* name,
   781                                                   PerfData::Units u,
   782                                                   jlong ival, TRAPS);
   784     static PerfLongVariable* create_long_variable(CounterNS ns,
   785                                                   const char* name,
   786                                                   PerfData::Units u, TRAPS) {
   787       return create_long_variable(ns, name, u, (jlong)0, CHECK_NULL);
   788     };
   790     static PerfLongVariable* create_long_variable(CounterNS, const char* name,
   791                                                   PerfData::Units u,
   792                                                   jlong* sp, TRAPS);
   794     static PerfLongVariable* create_long_variable(CounterNS ns,
   795                                                   const char* name,
   796                                                   PerfData::Units u,
   797                                                   PerfLongSampleHelper* sh,
   798                                                   TRAPS);
   801     // Counter Types
   802     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
   803                                                 PerfData::Units u,
   804                                                 jlong ival, TRAPS);
   806     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
   807                                                 PerfData::Units u, TRAPS) {
   808       return create_long_counter(ns, name, u, (jlong)0, CHECK_NULL);
   809     };
   811     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
   812                                                 PerfData::Units u, jlong* sp,
   813                                                 TRAPS);
   815     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
   816                                                 PerfData::Units u,
   817                                                 PerfLongSampleHelper* sh,
   818                                                 TRAPS);
   821     // these creation methods are provided for ease of use. These allow
   822     // Long performance data types to be created with a shorthand syntax.
   824     static PerfConstant* create_constant(CounterNS ns, const char* name,
   825                                          PerfData::Units u, jlong val, TRAPS) {
   826       return create_long_constant(ns, name, u, val, CHECK_NULL);
   827     }
   829     static PerfVariable* create_variable(CounterNS ns, const char* name,
   830                                          PerfData::Units u, jlong ival, TRAPS) {
   831       return create_long_variable(ns, name, u, ival, CHECK_NULL);
   832     }
   834     static PerfVariable* create_variable(CounterNS ns, const char* name,
   835                                          PerfData::Units u, TRAPS) {
   836       return create_long_variable(ns, name, u, (jlong)0, CHECK_NULL);
   837     }
   839     static PerfVariable* create_variable(CounterNS ns, const char* name,
   840                                          PerfData::Units u, jlong* sp, TRAPS) {
   841       return create_long_variable(ns, name, u, sp, CHECK_NULL);
   842     }
   844     static PerfVariable* create_variable(CounterNS ns, const char* name,
   845                                          PerfData::Units u,
   846                                          PerfSampleHelper* sh, TRAPS) {
   847       return create_long_variable(ns, name, u, sh, CHECK_NULL);
   848     }
   850     static PerfCounter* create_counter(CounterNS ns, const char* name,
   851                                        PerfData::Units u, jlong ival, TRAPS) {
   852       return create_long_counter(ns, name, u, ival, CHECK_NULL);
   853     }
   855     static PerfCounter* create_counter(CounterNS ns, const char* name,
   856                                        PerfData::Units u, TRAPS) {
   857       return create_long_counter(ns, name, u, (jlong)0, CHECK_NULL);
   858     }
   860     static PerfCounter* create_counter(CounterNS ns, const char* name,
   861                                        PerfData::Units u, jlong* sp, TRAPS) {
   862       return create_long_counter(ns, name, u, sp, CHECK_NULL);
   863     }
   865     static PerfCounter* create_counter(CounterNS ns, const char* name,
   866                                        PerfData::Units u,
   867                                        PerfSampleHelper* sh, TRAPS) {
   868       return create_long_counter(ns, name, u, sh, CHECK_NULL);
   869     }
   871     static void destroy();
   872 };
   874 // Useful macros to create the performance counters
   875 #define NEWPERFTICKCOUNTER(counter, counter_ns, counter_name)  \
   876   {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
   877                                              PerfData::U_Ticks,CHECK);}
   879 #define NEWPERFEVENTCOUNTER(counter, counter_ns, counter_name)  \
   880   {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
   881                                              PerfData::U_Events,CHECK);}
   883 #define NEWPERFBYTECOUNTER(counter, counter_ns, counter_name)  \
   884   {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
   885                                              PerfData::U_Bytes,CHECK);}
   887 // Utility Classes
   889 /*
   890  * this class will administer a PerfCounter used as a time accumulator
   891  * for a basic block much like the TraceTime class.
   892  *
   893  * Example:
   894  *
   895  *    static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, 0LL, CHECK);
   896  *
   897  *    {
   898  *      PerfTraceTime ptt(my_time_counter);
   899  *      // perform the operation you want to measure
   900  *    }
   901  *
   902  * Note: use of this class does not need to occur within a guarded
   903  * block. The UsePerfData guard is used with the implementation
   904  * of this class.
   905  */
   906 class PerfTraceTime : public StackObj {
   908   protected:
   909     elapsedTimer _t;
   910     PerfLongCounter* _timerp;
   911     // pointer to thread-local or global recursion counter variable
   912     int* _recursion_counter;
   914   public:
   915     inline PerfTraceTime(PerfLongCounter* timerp) : _timerp(timerp), _recursion_counter(NULL) {
   916       if (!UsePerfData) return;
   917       _t.start();
   918     }
   920     inline PerfTraceTime(PerfLongCounter* timerp, int* recursion_counter) : _timerp(timerp), _recursion_counter(recursion_counter) {
   921       if (!UsePerfData || (_recursion_counter != NULL &&
   922                            (*_recursion_counter)++ > 0)) return;
   923       _t.start();
   924     }
   926     inline void suspend() { if (!UsePerfData) return; _t.stop(); }
   927     inline void resume() { if (!UsePerfData) return; _t.start(); }
   929     inline ~PerfTraceTime() {
   930       if (!UsePerfData || (_recursion_counter != NULL &&
   931                            --(*_recursion_counter) > 0)) return;
   932       _t.stop();
   933       _timerp->inc(_t.ticks());
   934     }
   935 };
   937 /* The PerfTraceTimedEvent class is responsible for counting the
   938  * occurrence of some event and measuring the the elapsed time of
   939  * the event in two separate PerfCounter instances.
   940  *
   941  * Example:
   942  *
   943  *    static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, CHECK);
   944  *    static PerfCounter* my_event_counter = PerfDataManager::create_counter("my.event.counter", PerfData::U_Events, CHECK);
   945  *
   946  *    {
   947  *      PerfTraceTimedEvent ptte(my_time_counter, my_event_counter);
   948  *      // perform the operation you want to count and measure
   949  *    }
   950  *
   951  * Note: use of this class does not need to occur within a guarded
   952  * block. The UsePerfData guard is used with the implementation
   953  * of this class.
   954  *
   955  */
   956 class PerfTraceTimedEvent : public PerfTraceTime {
   958   protected:
   959     PerfLongCounter* _eventp;
   961   public:
   962     inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp): PerfTraceTime(timerp), _eventp(eventp) {
   963       if (!UsePerfData) return;
   964       _eventp->inc();
   965     }
   967     inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp, int* recursion_counter): PerfTraceTime(timerp, recursion_counter), _eventp(eventp) {
   968       if (!UsePerfData) return;
   969       _eventp->inc();
   970     }
   971 };
   973 #endif // SHARE_VM_RUNTIME_PERFDATA_HPP

mercurial