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