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