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