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