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