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 inline void reset() { (*(jlong*)_valuep) = 0; } 374 }; 375 376 /* 377 * The PerfLongCounter class, and its alias PerfCounter, implement 378 * a PerfData subtype that holds a jlong data value that can (should) 379 * be modified in a monotonic manner. The inc(jlong) and add(jlong) 380 * methods can be passed negative values to implement a monotonically 381 * decreasing value. However, we rely upon the programmer to honor 382 * the notion that this counter always moves in the same direction - 383 * either increasing or decreasing. 384 */ 385 class PerfLongCounter : public PerfLongVariant { 386 387 friend class PerfDataManager; // for access to protected constructor 388 389 protected: 390 391 PerfLongCounter(CounterNS ns, const char* namep, Units u, 392 jlong initial_value=0) 393 : PerfLongVariant(ns, namep, u, V_Monotonic, 394 initial_value) { } 395 }; 396 397 /* 398 * The PerfLongVariable class, and its alias PerfVariable, implement 399 * a PerfData subtype that holds a jlong data value that can 400 * be modified in an unrestricted manner. 401 */ 402 class PerfLongVariable : public PerfLongVariant { 403 404 friend class PerfDataManager; // for access to protected constructor 405 406 protected: 407 408 PerfLongVariable(CounterNS ns, const char* namep, Units u, 409 jlong initial_value=0) 410 : PerfLongVariant(ns, namep, u, V_Variable, 411 initial_value) { } 412 413 public: 414 inline void set_value(jlong val) { (*(jlong*)_valuep) = val; } 415 }; 416 417 /* 418 * The PerfByteArray provides a PerfData subtype that allows the creation 419 * of a contiguous region of the PerfData memory region for storing a vector 420 * of bytes. This class is currently intended to be a base class for 421 * the PerfString class, and cannot be instantiated directly. 422 */ 423 class PerfByteArray : public PerfData { 424 425 protected: 426 jint _length; 427 428 PerfByteArray(CounterNS ns, const char* namep, Units u, Variability v, 429 jint length); 430 }; 431 432 class PerfString : public PerfByteArray { 433 434 protected: 435 436 void set_string(const char* s2); 437 438 PerfString(CounterNS ns, const char* namep, Variability v, jint length, 439 const char* initial_value) 440 : PerfByteArray(ns, namep, U_String, v, length) { 441 if (is_valid()) set_string(initial_value); 442 } 443 444 }; 445 446 /* 447 * The PerfStringConstant class provides a PerfData sub class that 448 * allows a null terminated string of single byte characters to be 449 * stored in the PerfData memory region. 450 */ 451 class PerfStringConstant : public PerfString { 452 453 friend class PerfDataManager; // for access to protected constructor 454 455 protected: 456 457 // Restrict string constant lengths to be <= PerfMaxStringConstLength. 458 // This prevents long string constants, as can occur with very 459 // long classpaths or java command lines, from consuming too much 460 // PerfData memory. 461 PerfStringConstant(CounterNS ns, const char* namep, 462 const char* initial_value); 463 }; 464 465 /* 466 * The PerfStringVariable class provides a PerfData sub class that 467 * allows a null terminated string of single byte character data 468 * to be stored in PerfData memory region. The string value can be reset 469 * after initialization. If the string value is >= max_length, then 470 * it will be truncated to max_length characters. The copied string 471 * is always null terminated. 472 */ 473 class PerfStringVariable : public PerfString { 474 475 friend class PerfDataManager; // for access to protected constructor 476 477 protected: 478 479 PerfStringVariable(CounterNS ns, const char* namep, jint max_length, 480 const char* initial_value) 481 : PerfString(ns, namep, V_Variable, max_length+1, 482 initial_value) { } 483 484 public: 485 inline void set_value(const char* val) { set_string(val); } 486 }; 487 488 489 /* 490 * The PerfDataList class is a container class for managing lists 491 * of PerfData items. The intention of this class is to allow for 492 * alternative implementations for management of list of PerfData 493 * items without impacting the code that uses the lists. 494 * 495 * The initial implementation is based upon GrowableArray. Searches 496 * on GrowableArray types is linear in nature and this may become 497 * a performance issue for creation of PerfData items, particularly 498 * from Java code where a test for existence is implemented as a 499 * search over all existing PerfData items. 500 * 501 * The abstraction is not complete. A more general container class 502 * would provide an Iterator abstraction that could be used to 503 * traverse the lists. This implementation still relies upon integer 504 * iterators and the at(int index) method. However, the GrowableArray 505 * is not directly visible outside this class and can be replaced by 506 * some other implementation, as long as that implementation provides 507 * a mechanism to iterate over the container by index. 508 */ 509 class PerfDataList : public CHeapObj<mtInternal> { 510 511 private: 512 513 // GrowableArray implementation 514 typedef GrowableArray<PerfData*> PerfDataArray; 515 516 PerfDataArray* _set; 517 518 // method to search for a instrumentation object by name 519 static bool by_name(const char* name, PerfData* pd); 520 521 protected: 522 // we expose the implementation here to facilitate the clone 523 // method. 524 PerfDataArray* get_impl() { return _set; } 525 526 public: 527 528 // create a PerfDataList with the given initial length 529 PerfDataList(int length); 530 531 // create a PerfDataList as a shallow copy of the given PerfDataList 532 PerfDataList(PerfDataList* p); 533 534 ~PerfDataList(); 535 536 // return the PerfData item indicated by name, 537 // or null if it doesn't exist. 538 PerfData* find_by_name(const char* name); 539 540 // return true if a PerfData item with the name specified in the 541 // argument exists, otherwise return false. 542 bool contains(const char* name) { return find_by_name(name) != nullptr; } 543 544 // return the number of PerfData items in this list 545 inline int length(); 546 547 // add a PerfData item to this list 548 inline void append(PerfData *p); 549 550 // create a new PerfDataList from this list. The new list is 551 // a shallow copy of the original list and care should be taken 552 // with respect to delete operations on the elements of the list 553 // as the are likely in use by another copy of the list. 554 PerfDataList* clone(); 555 556 // for backward compatibility with GrowableArray - need to implement 557 // some form of iterator to provide a cleaner abstraction for 558 // iteration over the container. 559 inline PerfData* at(int index); 560 }; 561 562 class PerfTickCounters : public CHeapObj<mtInternal> { 563 private: 564 const char* _name; 565 PerfCounter* const _elapsed_counter; 566 PerfCounter* const _thread_counter; 567 public: 568 PerfTickCounters(const char* name, PerfCounter* elapsed_counter, PerfCounter* thread_counter) : 569 _name(name), _elapsed_counter(elapsed_counter), _thread_counter(thread_counter) { 570 } 571 572 const char* name() { return _name; } 573 574 PerfCounter* elapsed_counter() const { 575 return _elapsed_counter; 576 } 577 long elapsed_counter_value() const { 578 return _elapsed_counter->get_value(); 579 } 580 inline jlong elapsed_counter_value_ms() const; 581 inline jlong elapsed_counter_value_us() const; 582 583 PerfCounter* thread_counter() const { 584 return _thread_counter; 585 } 586 jlong thread_counter_value() const { 587 return _thread_counter->get_value(); 588 } 589 inline jlong thread_counter_value_ms() const; 590 inline jlong thread_counter_value_us() const; 591 592 void reset() { 593 _elapsed_counter->reset(); 594 _thread_counter->reset(); 595 } 596 }; 597 598 /* 599 * The PerfDataManager class is responsible for creating PerfData 600 * subtypes via a set a factory methods and for managing lists 601 * of the various PerfData types. 602 */ 603 class PerfDataManager : AllStatic { 604 private: 605 static PerfDataList* _all; 606 static PerfDataList* _constants; 607 static const char* _name_spaces[]; 608 static volatile bool _has_PerfData; 609 610 // add a PerfData item to the list(s) of know PerfData objects 611 static void add_item(PerfData* p); 612 613 static void create_system_property_instrumentation(TRAPS); 614 static void assert_system_property(const char* name, const char* value, TRAPS); 615 static void add_property_constant(CounterNS name_space, const char* name, const char* value, TRAPS); 616 static void add_property_constant(CounterNS name_space, const char* name, TRAPS); 617 static void add_optional_property_constant(CounterNS name_space, const char* name, TRAPS); 618 public: 619 // Creates miscellaneous perfdata constants 620 static void create_misc_perfdata(); 621 622 // method to check for the existence of a PerfData item with 623 // the given name. 624 static inline bool exists(const char* name); 625 626 // method to map a CounterNS enumeration to a namespace string 627 static const char* ns_to_string(CounterNS ns) { 628 return _name_spaces[ns]; 629 } 630 631 // methods to test the interface stability of a given counter namespace 632 // 633 static bool is_stable_supported(CounterNS ns) { 634 return (ns != NULL_NS) && ((ns % 3) == JAVA_NS); 635 } 636 static bool is_unstable_supported(CounterNS ns) { 637 return (ns != NULL_NS) && ((ns % 3) == COM_NS); 638 } 639 640 // methods to test the interface stability of a given counter name 641 // 642 static bool is_stable_supported(const char* name) { 643 const char* javadot = "java."; 644 return strncmp(name, javadot, strlen(javadot)) == 0; 645 } 646 static bool is_unstable_supported(const char* name) { 647 const char* comdot = "com.sun."; 648 return strncmp(name, comdot, strlen(comdot)) == 0; 649 } 650 651 // method to construct counter name strings in a given name space. 652 // The string object is allocated from the Resource Area and calls 653 // to this method must be made within a ResourceMark. 654 // 655 static char* counter_name(const char* name_space, const char* name); 656 657 // method to construct name space strings in a given name space. 658 // The string object is allocated from the Resource Area and calls 659 // to this method must be made within a ResourceMark. 660 // 661 static char* name_space(const char* name_space, const char* sub_space) { 662 return counter_name(name_space, sub_space); 663 } 664 665 // same as above, but appends the instance number to the name space 666 // 667 static char* name_space(const char* name_space, const char* sub_space, 668 int instance); 669 static char* name_space(const char* name_space, int instance); 670 671 672 // these methods provide the general interface for creating 673 // performance data resources. The types of performance data 674 // resources can be extended by adding additional create<type> 675 // methods. 676 677 // Constant Types 678 static PerfStringConstant* create_string_constant(CounterNS ns, 679 const char* name, 680 const char *s, TRAPS); 681 682 static PerfLongConstant* create_long_constant(CounterNS ns, 683 const char* name, 684 PerfData::Units u, 685 jlong val, TRAPS); 686 687 688 // Variable Types 689 static PerfStringVariable* create_string_variable(CounterNS ns, 690 const char* name, 691 int max_length, 692 const char *s, TRAPS); 693 694 static PerfLongVariable* create_long_variable(CounterNS ns, 695 const char* name, 696 PerfData::Units u, 697 jlong ival, TRAPS); 698 699 static PerfLongVariable* create_long_variable(CounterNS ns, 700 const char* name, 701 PerfData::Units u, TRAPS) { 702 return create_long_variable(ns, name, u, (jlong)0, THREAD); 703 }; 704 705 706 // Counter Types 707 static PerfLongCounter* create_long_counter(CounterNS ns, const char* name, 708 PerfData::Units u, 709 jlong ival, TRAPS); 710 711 712 // these creation methods are provided for ease of use. These allow 713 // Long performance data types to be created with a shorthand syntax. 714 715 static PerfConstant* create_constant(CounterNS ns, const char* name, 716 PerfData::Units u, jlong val, TRAPS) { 717 return create_long_constant(ns, name, u, val, THREAD); 718 } 719 720 static PerfVariable* create_variable(CounterNS ns, const char* name, 721 PerfData::Units u, jlong ival, TRAPS) { 722 return create_long_variable(ns, name, u, ival, THREAD); 723 } 724 725 static PerfVariable* create_variable(CounterNS ns, const char* name, 726 PerfData::Units u, TRAPS) { 727 return create_long_variable(ns, name, u, (jlong)0, THREAD); 728 } 729 730 static PerfCounter* create_counter(CounterNS ns, const char* name, 731 PerfData::Units u, TRAPS) { 732 return create_long_counter(ns, name, u, (jlong)0, THREAD); 733 } 734 735 static PerfTickCounters* create_tick_counters(CounterNS ns, 736 const char* counter_name, 737 const char* elapsed_counter_name, 738 const char* thread_counter_name, 739 PerfData::Units u, TRAPS) { 740 PerfCounter* elapsed_counter = create_long_counter(ns, elapsed_counter_name, u, (jlong)0, THREAD); 741 PerfCounter* thread_counter = create_long_counter(ns, thread_counter_name, u, (jlong)0, THREAD); 742 743 PerfTickCounters* counters = new PerfTickCounters(counter_name, elapsed_counter, thread_counter); 744 return counters; 745 } 746 747 static void destroy(); 748 static bool has_PerfData() { return Atomic::load_acquire(&_has_PerfData); } 749 }; 750 751 // Useful macros to create the performance counters 752 #define NEWPERFTICKCOUNTER(counter, counter_ns, counter_name) \ 753 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \ 754 PerfData::U_Ticks,CHECK);} 755 756 #define NEWPERFEVENTCOUNTER(counter, counter_ns, counter_name) \ 757 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \ 758 PerfData::U_Events,CHECK);} 759 760 #define NEWPERFBYTECOUNTER(counter, counter_ns, counter_name) \ 761 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \ 762 PerfData::U_Bytes,CHECK);} 763 764 #define NEWPERFTICKCOUNTERS(counter, counter_ns, counter_name) \ 765 {counter = PerfDataManager::create_tick_counters(counter_ns, counter_name, counter_name "_elapsed_time", \ 766 counter_name "_thread_time", PerfData::U_Ticks,CHECK);} 767 768 // Utility Classes 769 770 /* PerfTraceElapsedTime and PerfTraceThreadTime will administer a PerfCounter used as a time accumulator 771 * for a basic block much like the TraceTime class. 772 * PerfTraceElapsedTime uses elapsedTimer to measure time which reflects the elapsed time, 773 * and PerfTraceThreadTime uses ThreadTimer which reflects thread cpu time. 774 * 775 * Example: 776 * 777 * static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, 0LL, CHECK); 778 * 779 * { 780 * PerfTraceElapsedTime ptt(my_time_counter); 781 * // perform the operation you want to measure 782 * } 783 * 784 * Note: use of this class does not need to occur within a guarded 785 * block. The UsePerfData guard is used with the implementation 786 * of this class. 787 */ 788 789 class PerfTraceTimeBase : public StackObj { 790 friend class PerfPauseTimer; 791 private: 792 BaseTimer* _t; 793 protected: 794 PerfLongCounter* _counter; 795 796 public: 797 inline PerfTraceTimeBase(BaseTimer* t, PerfLongCounter* counter) : _t(t), _counter(counter) {} 798 799 ~PerfTraceTimeBase(); 800 801 jlong active_ticks() { return _t->active_ticks(); } 802 803 const char* name() { return _counter->name(); } 804 BaseTimer* timer() { return _t; } 805 }; 806 807 class PerfTraceElapsedTime: public PerfTraceTimeBase { 808 protected: 809 elapsedTimer _t; 810 811 public: 812 inline PerfTraceElapsedTime(PerfCounter* counter) : PerfTraceTimeBase(&_t, counter) { 813 if (!UsePerfData || counter == nullptr) { return; } 814 _t.start(); 815 } 816 }; 817 818 class PerfTraceThreadTime: public PerfTraceTimeBase { 819 protected: 820 ThreadTimer _t; 821 822 public: 823 inline PerfTraceThreadTime(PerfCounter* counter) : PerfTraceTimeBase(&_t, counter) { 824 if (!UsePerfData || !TraceThreadTime || counter == nullptr) { return; } 825 _t.start(); 826 } 827 }; 828 829 // PerfTraceTime is a utility class to provide the ability to measure both elapsed and thread cpu time using a single object. 830 class PerfTraceTime : public StackObj { 831 friend class PerfPauseTimer; 832 private: 833 PerfTickCounters* _counters; 834 PerfTraceElapsedTime _elapsed_timer; 835 PerfTraceThreadTime _thread_timer; 836 837 public: 838 inline PerfTraceTime(PerfTickCounters* counters, bool is_on = true): 839 _counters(counters), 840 _elapsed_timer(counters != nullptr ? counters->elapsed_counter() : nullptr), 841 _thread_timer(counters != nullptr ? counters->thread_counter() : nullptr) {} 842 843 const char* name() { return _counters->name(); } 844 PerfTraceTimeBase* elapsed_timer() { return &_elapsed_timer; } 845 PerfTraceTimeBase* thread_timer() { return &_thread_timer; } 846 847 jlong elapsed_timer_active_ticks() { 848 return _elapsed_timer.active_ticks(); 849 } 850 851 jlong thread_timer_active_ticks() { 852 return _thread_timer.active_ticks(); 853 } 854 }; 855 856 class PerfPauseTimerBase : public StackObj { 857 protected: 858 bool _is_active; 859 BaseTimer* _timer; 860 861 public: 862 inline PerfPauseTimerBase(PerfTraceTimeBase* timer, bool is_on) : _is_active(false), _timer(nullptr) { 863 _is_active = (is_on && timer != nullptr); 864 if (UsePerfData && _is_active) { 865 _timer = timer->timer(); 866 _timer->stop(); // pause 867 } 868 } 869 870 inline ~PerfPauseTimerBase() { 871 if (UsePerfData && _is_active) { 872 assert(_timer != nullptr, ""); 873 _timer->start(); // resume 874 } 875 } 876 }; 877 878 class PerfPauseTimer : public StackObj { 879 private: 880 PerfPauseTimerBase _elapsed_timer_pause; 881 PerfPauseTimerBase _thread_timer_pause; 882 883 public: 884 inline PerfPauseTimer(PerfTraceTime* timer, bool is_on) : 885 _elapsed_timer_pause(timer != nullptr ? timer->elapsed_timer() : nullptr, is_on), 886 _thread_timer_pause(timer != nullptr ? timer->thread_timer() : nullptr, is_on) {} 887 }; 888 889 /* The PerfTraceElapsedTimeEvent class is responsible for counting the 890 * occurrence of some event and measuring the elapsed time of 891 * the event in two separate PerfCounter instances. 892 * 893 * Example: 894 * 895 * static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, CHECK); 896 * static PerfCounter* my_event_counter = PerfDataManager::create_counter("my.event.counter", PerfData::U_Events, CHECK); 897 * 898 * { 899 * PerfTraceElapsedTimeEvent ptte(my_time_counter, my_event_counter); 900 * // perform the operation you want to count and measure 901 * } 902 * 903 * Note: use of this class does not need to occur within a guarded 904 * block. The UsePerfData guard is used with the implementation 905 * of this class. 906 * 907 * Similarly, PerfTraceThreadTimeEvent can count the occurrence of some event and measure the thread cpu time of the event. 908 * PerfTraceTimedEvent can count the occurrence of some event and measure both the elapsed time and the thread cpu time of the event. 909 */ 910 class PerfTraceElapsedTimeEvent: public PerfTraceElapsedTime { 911 protected: 912 PerfLongCounter* _eventp; 913 914 public: 915 inline PerfTraceElapsedTimeEvent(PerfCounter* counter, PerfLongCounter* eventp) : PerfTraceElapsedTime(counter), _eventp(eventp) { 916 if (!UsePerfData || counter == nullptr) return; 917 _eventp->inc(); 918 } 919 }; 920 921 class PerfTraceThreadTimeEvent: public PerfTraceThreadTime { 922 protected: 923 PerfLongCounter* _eventp; 924 925 public: 926 inline PerfTraceThreadTimeEvent(PerfCounter* counter, PerfLongCounter* eventp) : PerfTraceThreadTime(counter), _eventp(eventp) { 927 if (!UsePerfData || counter == nullptr) return; 928 _eventp->inc(); 929 } 930 }; 931 932 class PerfTraceTimedEvent : public PerfTraceTime { 933 protected: 934 PerfLongCounter* _eventp; 935 936 public: 937 inline PerfTraceTimedEvent(PerfTickCounters* counters, PerfLongCounter* eventp, bool is_on = true) : PerfTraceTime(counters, is_on), _eventp(eventp) { 938 if (!UsePerfData || !is_on || counters == nullptr) return; 939 _eventp->inc(); 940 } 941 }; 942 #endif // SHARE_RUNTIME_PERFDATA_HPP