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 * For additional uses of PerfData subtypes, see the utility classes 204 * PerfTraceTime and PerfTraceTimedEvent below. 205 * 206 * Always-on counters can be created independent of 207 * the UsePerfData flag. Counters will be created on the c-heap 208 * if UsePerfData is false. 209 * 210 * Until further notice, all PerfData objects should be created and 211 * manipulated within a guarded block. The guard variable is 212 * UsePerfData, a product flag set to true by default. This flag may 213 * be removed from the product in the future. 214 * 215 * There are possible shutdown races between counter uses and counter 216 * destruction code. Normal shutdown happens with taking VM_Exit safepoint 217 * operation, so in the vast majority of uses this is not an issue. On the 218 * paths where a concurrent access can still happen when VM is at safepoint, 219 * use the following pattern to coordinate with shutdown: 220 * 221 * { 222 * GlobalCounter::CriticalSection cs(Thread::current()); 223 * if (PerfDataManager::has_PerfData()) { 224 * <update-counter> 225 * } 226 * } 227 */ 228 class PerfData : public CHeapObj<mtInternal> { 229 230 friend class PerfDataManager; // for access to protected destructor 231 friend class VMStructs; 232 233 public: 234 235 // the Variability enum must be kept in synchronization with the 236 // the com.sun.hotspot.perfdata.Variability class 237 enum Variability { 238 V_Constant = 1, 239 V_Monotonic = 2, 240 V_Variable = 3, 241 V_last = V_Variable 242 }; 243 244 // the Units enum must be kept in synchronization with the 245 // the com.sun.hotspot.perfdata.Units class 246 enum Units { 247 U_None = 1, 248 U_Bytes = 2, 249 U_Ticks = 3, 250 U_Events = 4, 251 U_String = 5, 252 U_Hertz = 6, 253 U_Last = U_Hertz 254 }; 255 256 // Miscellaneous flags 257 enum Flags { 258 F_None = 0x0, 259 F_Supported = 0x1 // interface is supported - java.* and com.sun.* 260 }; 261 262 private: 263 char* _name; 264 Variability _v; 265 Units _u; 266 bool _on_c_heap; 267 Flags _flags; 268 269 PerfDataEntry* _pdep; 270 271 protected: 272 273 void *_valuep; 274 275 PerfData(CounterNS ns, const char* name, Units u, Variability v); 276 virtual ~PerfData(); 277 278 // create the entry for the PerfData item in the PerfData memory region. 279 // this region is maintained separately from the PerfData objects to 280 // facilitate its use by external processes. 281 void create_entry(BasicType dtype, size_t dsize, size_t dlen = 0); 282 283 public: 284 285 // returns a boolean indicating the validity of this object. 286 // the object is valid if and only if memory in PerfMemory 287 // region was successfully allocated. 288 inline bool is_valid() { return _valuep != nullptr; } 289 290 // returns a boolean indicating whether the underlying object 291 // was allocated in the PerfMemory region or on the C heap. 292 inline bool is_on_c_heap() { return _on_c_heap; } 293 294 // returns a pointer to a char* containing the name of the item. 295 // The pointer returned is the pointer to a copy of the name 296 // passed to the constructor, not the pointer to the name in the 297 // PerfData memory region. This redundancy is maintained for 298 // security reasons as the PerfMemory region may be in shared 299 // memory. 300 const char* name() const { return _name; } 301 bool name_equals(const char* name) const; 302 303 // returns the variability classification associated with this item 304 Variability variability() { return _v; } 305 306 // returns the units associated with this item. 307 Units units() { return _u; } 308 309 // returns the flags associated with this item. 310 Flags flags() { return _flags; } 311 312 // returns the address of the data portion of the item in the 313 // PerfData memory region. 314 inline void* get_address() { return _valuep; } 315 }; 316 317 /* 318 * PerfLong is the base class for the various Long PerfData subtypes. 319 * it contains implementation details that are common among its derived 320 * types. 321 */ 322 class PerfLong : public PerfData { 323 324 protected: 325 326 PerfLong(CounterNS ns, const char* namep, Units u, Variability v); 327 328 public: 329 // returns the value of the data portion of the item in the 330 // PerfData memory region. 331 inline jlong get_value() { return *(jlong*)_valuep; } 332 }; 333 334 /* 335 * The PerfLongConstant class, and its alias PerfConstant, implement 336 * a PerfData subtype that holds a jlong data value that is set upon 337 * creation of an instance of this class. This class provides no 338 * methods for changing the data value stored in PerfData memory region. 339 */ 340 class PerfLongConstant : public PerfLong { 341 342 friend class PerfDataManager; // for access to protected constructor 343 344 protected: 345 346 PerfLongConstant(CounterNS ns, const char* namep, Units u, 347 jlong initial_value=0) 348 : PerfLong(ns, namep, u, V_Constant) { 349 350 if (is_valid()) *(jlong*)_valuep = initial_value; 351 } 352 }; 353 354 /* 355 * The PerfLongVariant class, and its alias PerfVariant, implement 356 * a PerfData subtype that holds a jlong data value that can be modified 357 * in an unrestricted manner. This class provides the implementation details 358 * for common functionality among its derived types. 359 */ 360 class PerfLongVariant : public PerfLong { 361 362 protected: 363 PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v, 364 jlong initial_value=0) 365 : PerfLong(ns, namep, u, v) { 366 if (is_valid()) *(jlong*)_valuep = initial_value; 367 } 368 369 public: 370 inline void inc() { (*(jlong*)_valuep)++; } 371 inline void inc(jlong val) { (*(jlong*)_valuep) += val; } 372 inline void dec(jlong val) { inc(-val); } 373 }; 374 375 /* 376 * The PerfLongCounter class, and its alias PerfCounter, implement 377 * a PerfData subtype that holds a jlong data value that can (should) 378 * be modified in a monotonic manner. The inc(jlong) and add(jlong) 379 * methods can be passed negative values to implement a monotonically 380 * decreasing value. However, we rely upon the programmer to honor 381 * the notion that this counter always moves in the same direction - 382 * either increasing or decreasing. 383 */ 384 class PerfLongCounter : public PerfLongVariant { 385 386 friend class PerfDataManager; // for access to protected constructor 387 388 protected: 389 390 PerfLongCounter(CounterNS ns, const char* namep, Units u, 391 jlong initial_value=0) 392 : PerfLongVariant(ns, namep, u, V_Monotonic, 393 initial_value) { } 394 }; 395 396 /* 397 * The PerfLongVariable class, and its alias PerfVariable, implement 398 * a PerfData subtype that holds a jlong data value that can 399 * be modified in an unrestricted manner. 400 */ 401 class PerfLongVariable : public PerfLongVariant { 402 403 friend class PerfDataManager; // for access to protected constructor 404 405 protected: 406 407 PerfLongVariable(CounterNS ns, const char* namep, Units u, 408 jlong initial_value=0) 409 : PerfLongVariant(ns, namep, u, V_Variable, 410 initial_value) { } 411 412 public: 413 inline void set_value(jlong val) { (*(jlong*)_valuep) = val; } 414 }; 415 416 /* 417 * The PerfByteArray provides a PerfData subtype that allows the creation 418 * of a contiguous region of the PerfData memory region for storing a vector 419 * of bytes. This class is currently intended to be a base class for 420 * the PerfString class, and cannot be instantiated directly. 421 */ 422 class PerfByteArray : public PerfData { 423 424 protected: 425 jint _length; 426 427 PerfByteArray(CounterNS ns, const char* namep, Units u, Variability v, 428 jint length); 429 }; 430 431 class PerfString : public PerfByteArray { 432 433 protected: 434 435 void set_string(const char* s2); 436 437 PerfString(CounterNS ns, const char* namep, Variability v, jint length, 438 const char* initial_value) 439 : PerfByteArray(ns, namep, U_String, v, length) { 440 if (is_valid()) set_string(initial_value); 441 } 442 443 }; 444 445 /* 446 * The PerfStringConstant class provides a PerfData sub class that 447 * allows a null terminated string of single byte characters to be 448 * stored in the PerfData memory region. 449 */ 450 class PerfStringConstant : public PerfString { 451 452 friend class PerfDataManager; // for access to protected constructor 453 454 protected: 455 456 // Restrict string constant lengths to be <= PerfMaxStringConstLength. 457 // This prevents long string constants, as can occur with very 458 // long classpaths or java command lines, from consuming too much 459 // PerfData memory. 460 PerfStringConstant(CounterNS ns, const char* namep, 461 const char* initial_value); 462 }; 463 464 /* 465 * The PerfStringVariable class provides a PerfData sub class that 466 * allows a null terminated string of single byte character data 467 * to be stored in PerfData memory region. The string value can be reset 468 * after initialization. If the string value is >= max_length, then 469 * it will be truncated to max_length characters. The copied string 470 * is always null terminated. 471 */ 472 class PerfStringVariable : public PerfString { 473 474 friend class PerfDataManager; // for access to protected constructor 475 476 protected: 477 478 PerfStringVariable(CounterNS ns, const char* namep, jint max_length, 479 const char* initial_value) 480 : PerfString(ns, namep, V_Variable, max_length+1, 481 initial_value) { } 482 483 public: 484 inline void set_value(const char* val) { set_string(val); } 485 }; 486 487 488 /* 489 * The PerfDataList class is a container class for managing lists 490 * of PerfData items. The intention of this class is to allow for 491 * alternative implementations for management of list of PerfData 492 * items without impacting the code that uses the lists. 493 * 494 * The initial implementation is based upon GrowableArray. Searches 495 * on GrowableArray types is linear in nature and this may become 496 * a performance issue for creation of PerfData items, particularly 497 * from Java code where a test for existence is implemented as a 498 * search over all existing PerfData items. 499 * 500 * The abstraction is not complete. A more general container class 501 * would provide an Iterator abstraction that could be used to 502 * traverse the lists. This implementation still relies upon integer 503 * iterators and the at(int index) method. However, the GrowableArray 504 * is not directly visible outside this class and can be replaced by 505 * some other implementation, as long as that implementation provides 506 * a mechanism to iterate over the container by index. 507 */ 508 class PerfDataList : public CHeapObj<mtInternal> { 509 510 private: 511 512 // GrowableArray implementation 513 typedef GrowableArray<PerfData*> PerfDataArray; 514 515 PerfDataArray* _set; 516 517 // method to search for a instrumentation object by name 518 static bool by_name(const char* name, PerfData* pd); 519 520 protected: 521 // we expose the implementation here to facilitate the clone 522 // method. 523 PerfDataArray* get_impl() { return _set; } 524 525 public: 526 527 // create a PerfDataList with the given initial length 528 PerfDataList(int length); 529 530 // create a PerfDataList as a shallow copy of the given PerfDataList 531 PerfDataList(PerfDataList* p); 532 533 ~PerfDataList(); 534 535 // return the PerfData item indicated by name, 536 // or null if it doesn't exist. 537 PerfData* find_by_name(const char* name); 538 539 // return true if a PerfData item with the name specified in the 540 // argument exists, otherwise return false. 541 bool contains(const char* name) { return find_by_name(name) != nullptr; } 542 543 // return the number of PerfData items in this list 544 inline int length(); 545 546 // add a PerfData item to this list 547 inline void append(PerfData *p); 548 549 // create a new PerfDataList from this list. The new list is 550 // a shallow copy of the original list and care should be taken 551 // with respect to delete operations on the elements of the list 552 // as the are likely in use by another copy of the list. 553 PerfDataList* clone(); 554 555 // for backward compatibility with GrowableArray - need to implement 556 // some form of iterator to provide a cleaner abstraction for 557 // iteration over the container. 558 inline PerfData* at(int index); 559 }; 560 561 562 /* 563 * The PerfDataManager class is responsible for creating PerfData 564 * subtypes via a set a factory methods and for managing lists 565 * of the various PerfData types. 566 */ 567 class PerfDataManager : AllStatic { 568 private: 569 static PerfDataList* _all; 570 static PerfDataList* _constants; 571 static const char* _name_spaces[]; 572 static volatile bool _has_PerfData; 573 574 // add a PerfData item to the list(s) of know PerfData objects 575 static void add_item(PerfData* p); 576 577 static void create_system_property_instrumentation(TRAPS); 578 static void assert_system_property(const char* name, const char* value, TRAPS); 579 static void add_property_constant(CounterNS name_space, const char* name, const char* value, TRAPS); 580 static void add_property_constant(CounterNS name_space, const char* name, TRAPS); 581 static void add_optional_property_constant(CounterNS name_space, const char* name, TRAPS); 582 public: 583 // Creates miscellaneous perfdata constants 584 static void create_misc_perfdata(); 585 586 // method to check for the existence of a PerfData item with 587 // the given name. 588 static inline bool exists(const char* name); 589 590 // method to map a CounterNS enumeration to a namespace string 591 static const char* ns_to_string(CounterNS ns) { 592 return _name_spaces[ns]; 593 } 594 595 // methods to test the interface stability of a given counter namespace 596 // 597 static bool is_stable_supported(CounterNS ns) { 598 return (ns != NULL_NS) && ((ns % 3) == JAVA_NS); 599 } 600 static bool is_unstable_supported(CounterNS ns) { 601 return (ns != NULL_NS) && ((ns % 3) == COM_NS); 602 } 603 604 // methods to test the interface stability of a given counter name 605 // 606 static bool is_stable_supported(const char* name) { 607 const char* javadot = "java."; 608 return strncmp(name, javadot, strlen(javadot)) == 0; 609 } 610 static bool is_unstable_supported(const char* name) { 611 const char* comdot = "com.sun."; 612 return strncmp(name, comdot, strlen(comdot)) == 0; 613 } 614 615 // method to construct counter name strings in a given name space. 616 // The string object is allocated from the Resource Area and calls 617 // to this method must be made within a ResourceMark. 618 // 619 static char* counter_name(const char* name_space, const char* name); 620 621 // method to construct name space strings in a given name space. 622 // The string object is allocated from the Resource Area and calls 623 // to this method must be made within a ResourceMark. 624 // 625 static char* name_space(const char* name_space, const char* sub_space) { 626 return counter_name(name_space, sub_space); 627 } 628 629 // same as above, but appends the instance number to the name space 630 // 631 static char* name_space(const char* name_space, const char* sub_space, 632 int instance); 633 static char* name_space(const char* name_space, int instance); 634 635 636 // these methods provide the general interface for creating 637 // performance data resources. The types of performance data 638 // resources can be extended by adding additional create<type> 639 // methods. 640 641 // Constant Types 642 static PerfStringConstant* create_string_constant(CounterNS ns, 643 const char* name, 644 const char *s, TRAPS); 645 646 static PerfLongConstant* create_long_constant(CounterNS ns, 647 const char* name, 648 PerfData::Units u, 649 jlong val, TRAPS); 650 651 652 // Variable Types 653 static PerfStringVariable* create_string_variable(CounterNS ns, 654 const char* name, 655 int max_length, 656 const char *s, TRAPS); 657 658 static PerfLongVariable* create_long_variable(CounterNS ns, 659 const char* name, 660 PerfData::Units u, 661 jlong ival, TRAPS); 662 663 static PerfLongVariable* create_long_variable(CounterNS ns, 664 const char* name, 665 PerfData::Units u, TRAPS) { 666 return create_long_variable(ns, name, u, (jlong)0, THREAD); 667 }; 668 669 670 // Counter Types 671 static PerfLongCounter* create_long_counter(CounterNS ns, const char* name, 672 PerfData::Units u, 673 jlong ival, TRAPS); 674 675 676 // these creation methods are provided for ease of use. These allow 677 // Long performance data types to be created with a shorthand syntax. 678 679 static PerfConstant* create_constant(CounterNS ns, const char* name, 680 PerfData::Units u, jlong val, TRAPS) { 681 return create_long_constant(ns, name, u, val, THREAD); 682 } 683 684 static PerfVariable* create_variable(CounterNS ns, const char* name, 685 PerfData::Units u, jlong ival, TRAPS) { 686 return create_long_variable(ns, name, u, ival, THREAD); 687 } 688 689 static PerfVariable* create_variable(CounterNS ns, const char* name, 690 PerfData::Units u, TRAPS) { 691 return create_long_variable(ns, name, u, (jlong)0, THREAD); 692 } 693 694 static PerfCounter* create_counter(CounterNS ns, const char* name, 695 PerfData::Units u, TRAPS) { 696 return create_long_counter(ns, name, u, (jlong)0, THREAD); 697 } 698 699 static void destroy(); 700 static bool has_PerfData() { return Atomic::load_acquire(&_has_PerfData); } 701 }; 702 703 // Useful macros to create the performance counters 704 #define NEWPERFTICKCOUNTER(counter, counter_ns, counter_name) \ 705 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \ 706 PerfData::U_Ticks,CHECK);} 707 708 #define NEWPERFEVENTCOUNTER(counter, counter_ns, counter_name) \ 709 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \ 710 PerfData::U_Events,CHECK);} 711 712 #define NEWPERFBYTECOUNTER(counter, counter_ns, counter_name) \ 713 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \ 714 PerfData::U_Bytes,CHECK);} 715 716 // Utility Classes 717 718 /* 719 * this class will administer a PerfCounter used as a time accumulator 720 * for a basic block much like the TraceTime class. 721 * 722 * Example: 723 * 724 * static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, 0LL, CHECK); 725 * 726 * { 727 * PerfTraceTime ptt(my_time_counter); 728 * // perform the operation you want to measure 729 * } 730 * 731 * Note: use of this class does not need to occur within a guarded 732 * block. The UsePerfData guard is used with the implementation 733 * of this class. 734 */ 735 class PerfTraceTime : public StackObj { 736 737 protected: 738 elapsedTimer _t; 739 PerfLongCounter* _timerp; 740 741 public: 742 inline PerfTraceTime(PerfLongCounter* timerp) : _timerp(timerp) { 743 if (!UsePerfData || timerp == nullptr) { return; } 744 _t.start(); 745 } 746 747 const char* name() const { 748 assert(_timerp != nullptr, "sanity"); 749 return _timerp->name(); 750 } 751 752 ~PerfTraceTime() { 753 if (!UsePerfData || !_t.is_active()) { return; } 754 _t.stop(); 755 _timerp->inc(_t.ticks()); 756 } 757 }; 758 759 /* The PerfTraceTimedEvent class is responsible for counting the 760 * occurrence of some event and measuring the elapsed time of 761 * the event in two separate PerfCounter instances. 762 * 763 * Example: 764 * 765 * static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, CHECK); 766 * static PerfCounter* my_event_counter = PerfDataManager::create_counter("my.event.counter", PerfData::U_Events, CHECK); 767 * 768 * { 769 * PerfTraceTimedEvent ptte(my_time_counter, my_event_counter); 770 * // perform the operation you want to count and measure 771 * } 772 * 773 * Note: use of this class does not need to occur within a guarded 774 * block. The UsePerfData guard is used with the implementation 775 * of this class. 776 * 777 */ 778 class PerfTraceTimedEvent : public PerfTraceTime { 779 780 protected: 781 PerfLongCounter* _eventp; 782 783 public: 784 inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp): PerfTraceTime(timerp), _eventp(eventp) { 785 if (!UsePerfData || timerp == nullptr) { return; } 786 _eventp->inc(); 787 } 788 789 }; 790 791 #endif // SHARE_RUNTIME_PERFDATA_HPP