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