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