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/atomicAccess.hpp"
30 #include "runtime/perfDataTypes.hpp"
31 #include "runtime/perfMemory.hpp"
32 #include "runtime/timer.hpp"
33
34 template <typename T> class GrowableArray;
35
36 /* jvmstat global and subsystem counter name space - enumeration value
37 * serve as an index into the PerfDataManager::_name_space[] array
38 * containing the corresponding name space string. Only the top level
39 * subsystem name spaces are represented here.
40 */
41 enum CounterNS {
42 // top level name spaces
43 JAVA_NS,
44 COM_NS,
45 SUN_NS,
46 // subsystem name spaces
47 JAVA_GC, // Garbage Collection name spaces
48 COM_GC,
49 SUN_GC,
50 JAVA_CI, // Compiler name spaces
51 COM_CI,
52 SUN_CI,
53 JAVA_CLS, // Class Loader name spaces
54 COM_CLS,
55 SUN_CLS,
56 JAVA_RT, // Runtime name spaces
57 COM_RT,
58 SUN_RT,
59 JAVA_OS, // Operating System name spaces
60 COM_OS,
61 SUN_OS,
62 JAVA_THREADS, // Threads System name spaces
63 COM_THREADS,
64 SUN_THREADS,
65 JAVA_THREADS_CPUTIME, // Thread CPU time name spaces
66 COM_THREADS_CPUTIME,
67 SUN_THREADS_CPUTIME,
68 JAVA_PROPERTY, // Java Property name spaces
69 COM_PROPERTY,
70 SUN_PROPERTY,
71 NULL_NS,
72 COUNTERNS_LAST = NULL_NS
73 };
74
75 /*
76 * Classes to support access to production performance data
77 *
78 * The PerfData class structure is provided for creation, access, and update
79 * of performance data (a.k.a. instrumentation) in a specific memory region
80 * which is possibly accessible as shared memory. Although not explicitly
81 * prevented from doing so, developers should not use the values returned
82 * by accessor methods to make algorithmic decisions as they are potentially
83 * extracted from a shared memory region. Although any shared memory region
84 * created is with appropriate access restrictions, allowing read-write access
85 * only to the principal that created the JVM, it is believed that the
86 * shared memory region facilitates an easier attack path than attacks
87 * launched through mechanisms such as /proc. For this reason, it is
88 * recommended that data returned by PerfData accessor methods be used
89 * cautiously.
90 *
91 * There are three variability classifications of performance data
92 * Constants - value is written to the PerfData memory once, on creation
93 * Variables - value is modifiable, with no particular restrictions
94 * Counters - value is monotonically changing (increasing or decreasing)
95 *
96 * The performance data items can also have various types. The class
97 * hierarchy and the structure of the memory region are designed to
98 * accommodate new types as they are needed. Types are specified in
99 * terms of Java basic types, which accommodates client applications
100 * written in the Java programming language. The class hierarchy is:
101 *
102 * - PerfData (Abstract)
103 * - PerfLong (Abstract)
104 * - PerfLongConstant (alias: PerfConstant)
105 * - PerfLongVariant (Abstract)
106 * - PerfLongVariable (alias: PerfVariable)
107 * - PerfLongCounter (alias: PerfCounter)
108 *
109 * - PerfByteArray (Abstract)
110 * - PerfString (Abstract)
111 * - PerfStringVariable
112 * - PerfStringConstant
113 *
114 *
115 * As seen in the class hierarchy, the initially supported types are:
116 *
117 * Long - performance data holds a Java long type
118 * ByteArray - performance data holds an array of Java bytes
119 * used for holding C++ char arrays.
120 *
121 * The String type is derived from the ByteArray type.
122 *
123 * A PerfData subtype is not required to provide an implementation for
124 * each variability classification. For example, the String type provides
125 * Variable and Constant variability classifications in the PerfStringVariable
126 * and PerfStringConstant classes, but does not provide a counter type.
127 *
128 * Performance data are also described by a unit of measure. Units allow
129 * client applications to make reasonable decisions on how to treat
130 * performance data generically, preventing the need to hard-code the
131 * specifics of a particular data item in client applications. The current
132 * set of units are:
133 *
134 * None - the data has no units of measure
135 * Bytes - data is measured in bytes
136 * Ticks - data is measured in clock ticks
137 * Events - data is measured in events. For example,
138 * the number of garbage collection events or the
139 * number of methods compiled.
140 * String - data is not numerical. For example,
141 * the java command line options
142 * Hertz - data is a frequency
143 *
144 * The performance counters also provide a support attribute, indicating
145 * the stability of the counter as a programmatic interface. The support
146 * level is also implied by the name space in which the counter is created.
147 * The counter name space support conventions follow the Java package, class,
148 * and property support conventions:
149 *
150 * java.* - stable, supported interface
151 * com.sun.* - unstable, supported interface
152 * sun.* - unstable, unsupported interface
153 *
154 * In the above context, unstable is a measure of the interface support
155 * level, not the implementation stability level.
156 *
157 * Currently, instances of PerfData subtypes are considered to have
158 * a life time equal to that of the VM and are managed by the
159 * PerfDataManager class. All constructors for the PerfData class and
160 * its subtypes have protected constructors. Creation of PerfData
161 * instances is performed by invoking various create methods on the
162 * PerfDataManager class. Users should not attempt to delete these
163 * instances as the PerfDataManager class expects to perform deletion
164 * operations on exit of the VM.
165 *
166 * Examples:
167 *
168 * Creating performance counter that holds a monotonically increasing
169 * long data value with units specified in U_Bytes in the "java.gc.*"
170 * name space.
171 *
172 * PerfLongCounter* foo_counter;
173 *
174 * foo_counter = PerfDataManager::create_long_counter(JAVA_GC, "foo",
175 * PerfData::U_Bytes,
176 * optionalInitialValue,
177 * CHECK);
178 * foo_counter->inc();
179 *
180 * Creating a performance counter that holds a variably change long
181 * data value with units specified in U_Bytes in the "com.sun.ci
182 * name space.
183 *
184 * PerfLongVariable* bar_variable;
185 * bar_variable = PerfDataManager::create_long_variable(COM_CI, "bar",
186 .* PerfData::U_Bytes,
187 * optionalInitialValue,
188 * CHECK);
189 *
190 * bar_variable->inc();
191 * bar_variable->set_value(0);
192 *
193 * Creating a performance counter that holds a constant string value in
194 * the "sun.cls.*" name space.
195 *
196 * PerfDataManager::create_string_constant(SUN_CLS, "foo", string, CHECK);
197 *
198 * Although the create_string_constant() factory method returns a pointer
199 * to the PerfStringConstant object, it can safely be ignored. Developers
200 * are not encouraged to access the string constant's value via this
201 * pointer at this time due to security concerns.
202 *
203 * For additional uses of PerfData subtypes, see the utility classes
204 * PerfTraceTime and PerfTraceTimedEvent below.
205 *
206 * Always-on counters can be created independent of
207 * the UsePerfData flag. Counters will be created on the c-heap
208 * if UsePerfData is false.
209 *
210 * Until further notice, all PerfData objects should be created and
211 * manipulated within a guarded block. The guard variable is
212 * UsePerfData, a product flag set to true by default. This flag may
213 * be removed from the product in the future.
214 *
215 * There are possible shutdown races between counter uses and counter
216 * destruction code. Normal shutdown happens with taking VM_Exit safepoint
217 * operation, so in the vast majority of uses this is not an issue. On the
218 * paths where a concurrent access can still happen when VM is at safepoint,
219 * use the following pattern to coordinate with shutdown:
220 *
221 * {
222 * GlobalCounter::CriticalSection cs(Thread::current());
223 * if (PerfDataManager::has_PerfData()) {
224 * <update-counter>
225 * }
226 * }
227 */
228 class PerfData : public CHeapObj<mtInternal> {
229
230 friend class PerfDataManager; // for access to protected destructor
231 friend class VMStructs;
232
233 public:
234
235 // the Variability enum must be kept in synchronization with the
236 // the com.sun.hotspot.perfdata.Variability class
237 enum Variability {
238 V_Constant = 1,
239 V_Monotonic = 2,
240 V_Variable = 3,
241 V_last = V_Variable
242 };
243
244 // the Units enum must be kept in synchronization with the
245 // the com.sun.hotspot.perfdata.Units class
246 enum Units {
247 U_None = 1,
248 U_Bytes = 2,
249 U_Ticks = 3,
250 U_Events = 4,
251 U_String = 5,
252 U_Hertz = 6,
253 U_Last = U_Hertz
254 };
255
256 // Miscellaneous flags
257 enum Flags {
258 F_None = 0x0,
259 F_Supported = 0x1 // interface is supported - java.* and com.sun.*
260 };
261
262 private:
263 char* _name;
264 Variability _v;
265 Units _u;
266 bool _on_c_heap;
267 Flags _flags;
268
269 PerfDataEntry* _pdep;
270
271 protected:
272
273 void *_valuep;
274
275 PerfData(CounterNS ns, const char* name, Units u, Variability v);
276 virtual ~PerfData();
277
278 // create the entry for the PerfData item in the PerfData memory region.
279 // this region is maintained separately from the PerfData objects to
280 // facilitate its use by external processes.
281 void create_entry(BasicType dtype, size_t dsize, size_t dlen = 0);
282
283 public:
284
285 // returns a boolean indicating the validity of this object.
286 // the object is valid if and only if memory in PerfMemory
287 // region was successfully allocated.
288 inline bool is_valid() { return _valuep != nullptr; }
289
290 // returns a boolean indicating whether the underlying object
291 // was allocated in the PerfMemory region or on the C heap.
292 inline bool is_on_c_heap() { return _on_c_heap; }
293
294 // returns a pointer to a char* containing the name of the item.
295 // The pointer returned is the pointer to a copy of the name
296 // passed to the constructor, not the pointer to the name in the
297 // PerfData memory region. This redundancy is maintained for
298 // security reasons as the PerfMemory region may be in shared
299 // memory.
300 const char* name() const { return _name; }
301 bool name_equals(const char* name) const;
302
303 // returns the variability classification associated with this item
304 Variability variability() { return _v; }
305
306 // returns the units associated with this item.
307 Units units() { return _u; }
308
309 // returns the flags associated with this item.
310 Flags flags() { return _flags; }
311
312 // returns the address of the data portion of the item in the
313 // PerfData memory region.
314 inline void* get_address() { return _valuep; }
315 };
316
317 /*
318 * PerfLong is the base class for the various Long PerfData subtypes.
319 * it contains implementation details that are common among its derived
320 * types.
321 */
322 class PerfLong : public PerfData {
323
324 protected:
325
326 PerfLong(CounterNS ns, const char* namep, Units u, Variability v);
327
328 public:
329 // returns the value of the data portion of the item in the
330 // PerfData memory region.
331 inline jlong get_value() { return *(jlong*)_valuep; }
332 };
333
334 /*
335 * The PerfLongConstant class, and its alias PerfConstant, implement
336 * a PerfData subtype that holds a jlong data value that is set upon
337 * creation of an instance of this class. This class provides no
338 * methods for changing the data value stored in PerfData memory region.
339 */
340 class PerfLongConstant : public PerfLong {
341
342 friend class PerfDataManager; // for access to protected constructor
343
344 protected:
345
346 PerfLongConstant(CounterNS ns, const char* namep, Units u,
347 jlong initial_value=0)
348 : PerfLong(ns, namep, u, V_Constant) {
349
350 if (is_valid()) *(jlong*)_valuep = initial_value;
351 }
352 };
353
354 /*
355 * The PerfLongVariant class, and its alias PerfVariant, implement
356 * a PerfData subtype that holds a jlong data value that can be modified
357 * in an unrestricted manner. This class provides the implementation details
358 * for common functionality among its derived types.
359 */
360 class PerfLongVariant : public PerfLong {
361
362 protected:
363 PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
364 jlong initial_value=0)
365 : PerfLong(ns, namep, u, v) {
366 if (is_valid()) *(jlong*)_valuep = initial_value;
367 }
368
369 public:
370 inline void inc() { (*(jlong*)_valuep)++; }
371 inline void inc(jlong val) { (*(jlong*)_valuep) += val; }
372 inline void dec(jlong val) { inc(-val); }
373 };
374
375 /*
376 * The PerfLongCounter class, and its alias PerfCounter, implement
377 * a PerfData subtype that holds a jlong data value that can (should)
378 * be modified in a monotonic manner. The inc(jlong) and add(jlong)
379 * methods can be passed negative values to implement a monotonically
380 * decreasing value. However, we rely upon the programmer to honor
381 * the notion that this counter always moves in the same direction -
382 * either increasing or decreasing.
383 */
384 class PerfLongCounter : public PerfLongVariant {
385
386 friend class PerfDataManager; // for access to protected constructor
387
388 protected:
389
390 PerfLongCounter(CounterNS ns, const char* namep, Units u,
391 jlong initial_value=0)
392 : PerfLongVariant(ns, namep, u, V_Monotonic,
393 initial_value) { }
394 };
395
396 /*
397 * The PerfLongVariable class, and its alias PerfVariable, implement
398 * a PerfData subtype that holds a jlong data value that can
399 * be modified in an unrestricted manner.
400 */
401 class PerfLongVariable : public PerfLongVariant {
402
403 friend class PerfDataManager; // for access to protected constructor
404
405 protected:
406
407 PerfLongVariable(CounterNS ns, const char* namep, Units u,
408 jlong initial_value=0)
409 : PerfLongVariant(ns, namep, u, V_Variable,
410 initial_value) { }
411
412 public:
413 inline void set_value(jlong val) { (*(jlong*)_valuep) = val; }
414 };
415
416 /*
417 * The PerfByteArray provides a PerfData subtype that allows the creation
418 * of a contiguous region of the PerfData memory region for storing a vector
419 * of bytes. This class is currently intended to be a base class for
420 * the PerfString class, and cannot be instantiated directly.
421 */
422 class PerfByteArray : public PerfData {
423
424 protected:
425 jint _length;
426
427 PerfByteArray(CounterNS ns, const char* namep, Units u, Variability v,
428 jint length);
429 };
430
431 class PerfString : public PerfByteArray {
432
433 protected:
434
435 void set_string(const char* s2);
436
437 PerfString(CounterNS ns, const char* namep, Variability v, jint length,
438 const char* initial_value)
439 : PerfByteArray(ns, namep, U_String, v, length) {
440 if (is_valid()) set_string(initial_value);
441 }
442
443 };
444
445 /*
446 * The PerfStringConstant class provides a PerfData sub class that
447 * allows a null terminated string of single byte characters to be
448 * stored in the PerfData memory region.
449 */
450 class PerfStringConstant : public PerfString {
451
452 friend class PerfDataManager; // for access to protected constructor
453
454 protected:
455
456 // Restrict string constant lengths to be <= PerfMaxStringConstLength.
457 // This prevents long string constants, as can occur with very
458 // long classpaths or java command lines, from consuming too much
459 // PerfData memory.
460 PerfStringConstant(CounterNS ns, const char* namep,
461 const char* initial_value);
462 };
463
464 /*
465 * The PerfStringVariable class provides a PerfData sub class that
466 * allows a null terminated string of single byte character data
467 * to be stored in PerfData memory region. The string value can be reset
468 * after initialization. If the string value is >= max_length, then
469 * it will be truncated to max_length characters. The copied string
470 * is always null terminated.
471 */
472 class PerfStringVariable : public PerfString {
473
474 friend class PerfDataManager; // for access to protected constructor
475
476 protected:
477
478 PerfStringVariable(CounterNS ns, const char* namep, jint max_length,
479 const char* initial_value)
480 : PerfString(ns, namep, V_Variable, max_length+1,
481 initial_value) { }
482
483 public:
484 inline void set_value(const char* val) { set_string(val); }
485 };
486
487
488 /*
489 * The PerfDataList class is a container class for managing lists
490 * of PerfData items. The intention of this class is to allow for
491 * alternative implementations for management of list of PerfData
492 * items without impacting the code that uses the lists.
493 *
494 * The initial implementation is based upon GrowableArray. Searches
495 * on GrowableArray types is linear in nature and this may become
496 * a performance issue for creation of PerfData items, particularly
497 * from Java code where a test for existence is implemented as a
498 * search over all existing PerfData items.
499 *
500 * The abstraction is not complete. A more general container class
501 * would provide an Iterator abstraction that could be used to
502 * traverse the lists. This implementation still relies upon integer
503 * iterators and the at(int index) method. However, the GrowableArray
504 * is not directly visible outside this class and can be replaced by
505 * some other implementation, as long as that implementation provides
506 * a mechanism to iterate over the container by index.
507 */
508 class PerfDataList : public CHeapObj<mtInternal> {
509
510 private:
511
512 // GrowableArray implementation
513 typedef GrowableArray<PerfData*> PerfDataArray;
514
515 PerfDataArray* _set;
516
517 // method to search for a instrumentation object by name
518 static bool by_name(const char* name, PerfData* pd);
519
520 protected:
521 // we expose the implementation here to facilitate the clone
522 // method.
523 PerfDataArray* get_impl() { return _set; }
524
525 public:
526
527 // create a PerfDataList with the given initial length
528 PerfDataList(int length);
529
530 // create a PerfDataList as a shallow copy of the given PerfDataList
531 PerfDataList(PerfDataList* p);
532
533 ~PerfDataList();
534
535 // return the PerfData item indicated by name,
536 // or null if it doesn't exist.
537 PerfData* find_by_name(const char* name);
538
539 // return true if a PerfData item with the name specified in the
540 // argument exists, otherwise return false.
541 bool contains(const char* name) { return find_by_name(name) != nullptr; }
542
543 // return the number of PerfData items in this list
544 inline int length();
545
546 // add a PerfData item to this list
547 inline void append(PerfData *p);
548
549 // create a new PerfDataList from this list. The new list is
550 // a shallow copy of the original list and care should be taken
551 // with respect to delete operations on the elements of the list
552 // as the are likely in use by another copy of the list.
553 PerfDataList* clone();
554
555 // for backward compatibility with GrowableArray - need to implement
556 // some form of iterator to provide a cleaner abstraction for
557 // iteration over the container.
558 inline PerfData* at(int index);
559 };
560
561
562 /*
563 * The PerfDataManager class is responsible for creating PerfData
564 * subtypes via a set a factory methods and for managing lists
565 * of the various PerfData types.
566 */
567 class PerfDataManager : AllStatic {
568 private:
569 static PerfDataList* _all;
570 static PerfDataList* _constants;
571 static const char* _name_spaces[];
572 static volatile bool _has_PerfData;
573
574 // add a PerfData item to the list(s) of know PerfData objects
575 static void add_item(PerfData* p);
576
577 static void create_system_property_instrumentation(TRAPS);
578 static void assert_system_property(const char* name, const char* value, TRAPS);
579 static void add_property_constant(CounterNS name_space, const char* name, const char* value, TRAPS);
580 static void add_property_constant(CounterNS name_space, const char* name, TRAPS);
581 static void add_optional_property_constant(CounterNS name_space, const char* name, TRAPS);
582 public:
583 // Creates miscellaneous perfdata constants
584 static void create_misc_perfdata();
585
586 // method to check for the existence of a PerfData item with
587 // the given name.
588 static inline bool exists(const char* name);
589
590 // method to map a CounterNS enumeration to a namespace string
591 static const char* ns_to_string(CounterNS ns) {
592 return _name_spaces[ns];
593 }
594
595 // methods to test the interface stability of a given counter namespace
596 //
597 static bool is_stable_supported(CounterNS ns) {
598 return (ns != NULL_NS) && ((ns % 3) == JAVA_NS);
599 }
600 static bool is_unstable_supported(CounterNS ns) {
601 return (ns != NULL_NS) && ((ns % 3) == COM_NS);
602 }
603
604 // methods to test the interface stability of a given counter name
605 //
606 static bool is_stable_supported(const char* name) {
607 const char* javadot = "java.";
608 return strncmp(name, javadot, strlen(javadot)) == 0;
609 }
610 static bool is_unstable_supported(const char* name) {
611 const char* comdot = "com.sun.";
612 return strncmp(name, comdot, strlen(comdot)) == 0;
613 }
614
615 // method to construct counter name strings in a given name space.
616 // The string object is allocated from the Resource Area and calls
617 // to this method must be made within a ResourceMark.
618 //
619 static char* counter_name(const char* name_space, const char* name);
620
621 // method to construct name space strings in a given name space.
622 // The string object is allocated from the Resource Area and calls
623 // to this method must be made within a ResourceMark.
624 //
625 static char* name_space(const char* name_space, const char* sub_space) {
626 return counter_name(name_space, sub_space);
627 }
628
629 // same as above, but appends the instance number to the name space
630 //
631 static char* name_space(const char* name_space, const char* sub_space,
632 int instance);
633 static char* name_space(const char* name_space, int instance);
634
635
636 // these methods provide the general interface for creating
637 // performance data resources. The types of performance data
638 // resources can be extended by adding additional create<type>
639 // methods.
640
641 // Constant Types
642 static PerfStringConstant* create_string_constant(CounterNS ns,
643 const char* name,
644 const char *s, TRAPS);
645
646 static PerfLongConstant* create_long_constant(CounterNS ns,
647 const char* name,
648 PerfData::Units u,
649 jlong val, TRAPS);
650
651
652 // Variable Types
653 static PerfStringVariable* create_string_variable(CounterNS ns,
654 const char* name,
655 int max_length,
656 const char *s, TRAPS);
657
658 static PerfLongVariable* create_long_variable(CounterNS ns,
659 const char* name,
660 PerfData::Units u,
661 jlong ival, TRAPS);
662
663 static PerfLongVariable* create_long_variable(CounterNS ns,
664 const char* name,
665 PerfData::Units u, TRAPS) {
666 return create_long_variable(ns, name, u, (jlong)0, THREAD);
667 };
668
669
670 // Counter Types
671 static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
672 PerfData::Units u,
673 jlong ival, TRAPS);
674
675
676 // these creation methods are provided for ease of use. These allow
677 // Long performance data types to be created with a shorthand syntax.
678
679 static PerfConstant* create_constant(CounterNS ns, const char* name,
680 PerfData::Units u, jlong val, TRAPS) {
681 return create_long_constant(ns, name, u, val, THREAD);
682 }
683
684 static PerfVariable* create_variable(CounterNS ns, const char* name,
685 PerfData::Units u, jlong ival, TRAPS) {
686 return create_long_variable(ns, name, u, ival, THREAD);
687 }
688
689 static PerfVariable* create_variable(CounterNS ns, const char* name,
690 PerfData::Units u, TRAPS) {
691 return create_long_variable(ns, name, u, (jlong)0, THREAD);
692 }
693
694 static PerfCounter* create_counter(CounterNS ns, const char* name,
695 PerfData::Units u, TRAPS) {
696 return create_long_counter(ns, name, u, (jlong)0, THREAD);
697 }
698
699 static void destroy();
700 static bool has_PerfData() { return AtomicAccess::load_acquire(&_has_PerfData); }
701 };
702
703 // Useful macros to create the performance counters
704 #define NEWPERFTICKCOUNTER(counter, counter_ns, counter_name) \
705 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
706 PerfData::U_Ticks,CHECK);}
707
708 #define NEWPERFEVENTCOUNTER(counter, counter_ns, counter_name) \
709 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
710 PerfData::U_Events,CHECK);}
711
712 #define NEWPERFBYTECOUNTER(counter, counter_ns, counter_name) \
713 {counter = PerfDataManager::create_counter(counter_ns, counter_name, \
714 PerfData::U_Bytes,CHECK);}
715
716 // Utility Classes
717
718 /*
719 * this class will administer a PerfCounter used as a time accumulator
720 * for a basic block much like the TraceTime class.
721 *
722 * Example:
723 *
724 * static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, 0LL, CHECK);
725 *
726 * {
727 * PerfTraceTime ptt(my_time_counter);
728 * // perform the operation you want to measure
729 * }
730 *
731 * Note: use of this class does not need to occur within a guarded
732 * block. The UsePerfData guard is used with the implementation
733 * of this class.
734 */
735 class PerfTraceTime : public StackObj {
736
737 protected:
738 elapsedTimer _t;
739 PerfLongCounter* _timerp;
740
741 public:
742 inline PerfTraceTime(PerfLongCounter* timerp) : _timerp(timerp) {
743 if (!UsePerfData || timerp == nullptr) { return; }
744 _t.start();
745 }
746
747 const char* name() const {
748 assert(_timerp != nullptr, "sanity");
749 return _timerp->name();
750 }
751
752 ~PerfTraceTime() {
753 if (!UsePerfData || !_t.is_active()) { return; }
754 _t.stop();
755 _timerp->inc(_t.ticks());
756 }
757 };
758
759 /* The PerfTraceTimedEvent class is responsible for counting the
760 * occurrence of some event and measuring the elapsed time of
761 * the event in two separate PerfCounter instances.
762 *
763 * Example:
764 *
765 * static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, CHECK);
766 * static PerfCounter* my_event_counter = PerfDataManager::create_counter("my.event.counter", PerfData::U_Events, CHECK);
767 *
768 * {
769 * PerfTraceTimedEvent ptte(my_time_counter, my_event_counter);
770 * // perform the operation you want to count and measure
771 * }
772 *
773 * Note: use of this class does not need to occur within a guarded
774 * block. The UsePerfData guard is used with the implementation
775 * of this class.
776 *
777 */
778 class PerfTraceTimedEvent : public PerfTraceTime {
779
780 protected:
781 PerfLongCounter* _eventp;
782
783 public:
784 inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp): PerfTraceTime(timerp), _eventp(eventp) {
785 if (!UsePerfData || timerp == nullptr) { return; }
786 _eventp->inc();
787 }
788
789 };
790
791 #endif // SHARE_RUNTIME_PERFDATA_HPP