1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/runtime/perfData.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,955 @@ 1.4 +/* 1.5 + * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +/* jvmstat global and subsystem counter name space - enumeration value 1.29 + * serve as an index into the PerfDataManager::_name_space[] array 1.30 + * containing the corresponding name space string. Only the top level 1.31 + * subsystem name spaces are represented here. 1.32 + */ 1.33 +enum CounterNS { 1.34 + // top level name spaces 1.35 + JAVA_NS, 1.36 + COM_NS, 1.37 + SUN_NS, 1.38 + // subsystem name spaces 1.39 + JAVA_GC, // Garbage Collection name spaces 1.40 + COM_GC, 1.41 + SUN_GC, 1.42 + JAVA_CI, // Compiler name spaces 1.43 + COM_CI, 1.44 + SUN_CI, 1.45 + JAVA_CLS, // Class Loader name spaces 1.46 + COM_CLS, 1.47 + SUN_CLS, 1.48 + JAVA_RT, // Runtime name spaces 1.49 + COM_RT, 1.50 + SUN_RT, 1.51 + JAVA_OS, // Operating System name spaces 1.52 + COM_OS, 1.53 + SUN_OS, 1.54 + JAVA_THREADS, // Threads System name spaces 1.55 + COM_THREADS, 1.56 + SUN_THREADS, 1.57 + JAVA_PROPERTY, // Java Property name spaces 1.58 + COM_PROPERTY, 1.59 + SUN_PROPERTY, 1.60 + NULL_NS, 1.61 + COUNTERNS_LAST = NULL_NS 1.62 +}; 1.63 + 1.64 +/* 1.65 + * Classes to support access to production performance data 1.66 + * 1.67 + * The PerfData class structure is provided for creation, access, and update 1.68 + * of performance data (a.k.a. instrumentation) in a specific memory region 1.69 + * which is possibly accessible as shared memory. Although not explicitly 1.70 + * prevented from doing so, developers should not use the values returned 1.71 + * by accessor methods to make algorithmic decisions as they are potentially 1.72 + * extracted from a shared memory region. Although any shared memory region 1.73 + * created is with appropriate access restrictions, allowing read-write access 1.74 + * only to the principal that created the JVM, it is believed that a the 1.75 + * shared memory region facilitates an easier attack path than attacks 1.76 + * launched through mechanisms such as /proc. For this reason, it is 1.77 + * recommended that data returned by PerfData accessor methods be used 1.78 + * cautiously. 1.79 + * 1.80 + * There are three variability classifications of performance data 1.81 + * Constants - value is written to the PerfData memory once, on creation 1.82 + * Variables - value is modifiable, with no particular restrictions 1.83 + * Counters - value is monotonically changing (increasing or decreasing) 1.84 + * 1.85 + * The performance data items can also have various types. The class 1.86 + * hierarchy and the structure of the memory region are designed to 1.87 + * accommodate new types as they are needed. Types are specified in 1.88 + * terms of Java basic types, which accommodates client applications 1.89 + * written in the Java programming language. The class hierarchy is: 1.90 + * 1.91 + * - PerfData (Abstract) 1.92 + * - PerfLong (Abstract) 1.93 + * - PerfLongConstant (alias: PerfConstant) 1.94 + * - PerfLongVariant (Abstract) 1.95 + * - PerfLongVariable (alias: PerfVariable) 1.96 + * - PerfLongCounter (alias: PerfCounter) 1.97 + * 1.98 + * - PerfByteArray (Abstract) 1.99 + * - PerfString (Abstract) 1.100 + * - PerfStringVariable 1.101 + * - PerfStringConstant 1.102 + * 1.103 + * 1.104 + * As seen in the class hierarchy, the initially supported types are: 1.105 + * 1.106 + * Long - performance data holds a Java long type 1.107 + * ByteArray - performance data holds an array of Java bytes 1.108 + * used for holding C++ char arrays. 1.109 + * 1.110 + * The String type is derived from the ByteArray type. 1.111 + * 1.112 + * A PerfData subtype is not required to provide an implementation for 1.113 + * each variability classification. For example, the String type provides 1.114 + * Variable and Constant variablility classifications in the PerfStringVariable 1.115 + * and PerfStringConstant classes, but does not provide a counter type. 1.116 + * 1.117 + * Performance data are also described by a unit of measure. Units allow 1.118 + * client applications to make reasonable decisions on how to treat 1.119 + * performance data generically, preventing the need to hard-code the 1.120 + * specifics of a particular data item in client applications. The current 1.121 + * set of units are: 1.122 + * 1.123 + * None - the data has no units of measure 1.124 + * Bytes - data is measured in bytes 1.125 + * Ticks - data is measured in clock ticks 1.126 + * Events - data is measured in events. For example, 1.127 + * the number of garbage collection events or the 1.128 + * number of methods compiled. 1.129 + * String - data is not numerical. For example, 1.130 + * the java command line options 1.131 + * Hertz - data is a frequency 1.132 + * 1.133 + * The performance counters also provide a support attribute, indicating 1.134 + * the stability of the counter as a programmatic interface. The support 1.135 + * level is also implied by the name space in which the counter is created. 1.136 + * The counter name space support conventions follow the Java package, class, 1.137 + * and property support conventions: 1.138 + * 1.139 + * java.* - stable, supported interface 1.140 + * com.sun.* - unstable, supported interface 1.141 + * sun.* - unstable, unsupported interface 1.142 + * 1.143 + * In the above context, unstable is a measure of the interface support 1.144 + * level, not the implementation stability level. 1.145 + * 1.146 + * Currently, instances of PerfData subtypes are considered to have 1.147 + * a life time equal to that of the VM and are managed by the 1.148 + * PerfDataManager class. All constructors for the PerfData class and 1.149 + * its subtypes have protected constructors. Creation of PerfData 1.150 + * instances is performed by invoking various create methods on the 1.151 + * PerfDataManager class. Users should not attempt to delete these 1.152 + * instances as the PerfDataManager class expects to perform deletion 1.153 + * operations on exit of the VM. 1.154 + * 1.155 + * Examples: 1.156 + * 1.157 + * Creating performance counter that holds a monotonically increasing 1.158 + * long data value with units specified in U_Bytes in the "java.gc.*" 1.159 + * name space. 1.160 + * 1.161 + * PerfLongCounter* foo_counter; 1.162 + * 1.163 + * foo_counter = PerfDataManager::create_long_counter(JAVA_GC, "foo", 1.164 + * PerfData::U_Bytes, 1.165 + * optionalInitialValue, 1.166 + * CHECK); 1.167 + * foo_counter->inc(); 1.168 + * 1.169 + * Creating a performance counter that holds a variably change long 1.170 + * data value with untis specified in U_Bytes in the "com.sun.ci 1.171 + * name space. 1.172 + * 1.173 + * PerfLongVariable* bar_varible; 1.174 + * bar_variable = PerfDataManager::create_long_variable(COM_CI, "bar", 1.175 +.* PerfData::U_Bytes, 1.176 + * optionalInitialValue, 1.177 + * CHECK); 1.178 + * 1.179 + * bar_variable->inc(); 1.180 + * bar_variable->set_value(0); 1.181 + * 1.182 + * Creating a performance counter that holds a constant string value in 1.183 + * the "sun.cls.*" name space. 1.184 + * 1.185 + * PerfDataManager::create_string_constant(SUN_CLS, "foo", string, CHECK); 1.186 + * 1.187 + * Although the create_string_constant() factory method returns a pointer 1.188 + * to the PerfStringConstant object, it can safely be ignored. Developers 1.189 + * are not encouraged to access the string constant's value via this 1.190 + * pointer at this time due to security concerns. 1.191 + * 1.192 + * Creating a performance counter in an arbitrary name space that holds a 1.193 + * value that is sampled by the StatSampler periodic task. 1.194 + * 1.195 + * PerfDataManager::create_counter("foo.sampled", PerfData::U_Events, 1.196 + * &my_jlong, CHECK); 1.197 + * 1.198 + * In this example, the PerfData pointer can be ignored as the caller 1.199 + * is relying on the StatSampler PeriodicTask to sample the given 1.200 + * address at a regular interval. The interval is defined by the 1.201 + * PerfDataSamplingInterval global variable, and is applyied on 1.202 + * a system wide basis, not on an per-counter basis. 1.203 + * 1.204 + * Creating a performance counter in an arbitrary name space that utilizes 1.205 + * a helper object to return a value to the StatSampler via the take_sample() 1.206 + * method. 1.207 + * 1.208 + * class MyTimeSampler : public PerfLongSampleHelper { 1.209 + * public: 1.210 + * jlong take_sample() { return os::elapsed_counter(); } 1.211 + * }; 1.212 + * 1.213 + * PerfDataManager::create_counter(SUN_RT, "helped", 1.214 + * PerfData::U_Ticks, 1.215 + * new MyTimeSampler(), CHECK); 1.216 + * 1.217 + * In this example, a subtype of PerfLongSampleHelper is instantiated 1.218 + * and its take_sample() method is overridden to perform whatever 1.219 + * operation is necessary to generate the data sample. This method 1.220 + * will be called by the StatSampler at a regular interval, defined 1.221 + * by the PerfDataSamplingInterval global variable. 1.222 + * 1.223 + * As before, PerfSampleHelper is an alias for PerfLongSampleHelper. 1.224 + * 1.225 + * For additional uses of PerfData subtypes, see the utility classes 1.226 + * PerfTraceTime and PerfTraceTimedEvent below. 1.227 + * 1.228 + * Always-on non-sampled counters can be created independent of 1.229 + * the UsePerfData flag. Counters will be created on the c-heap 1.230 + * if UsePerfData is false. 1.231 + * 1.232 + * Until further noice, all PerfData objects should be created and 1.233 + * manipulated within a guarded block. The guard variable is 1.234 + * UsePerfData, a product flag set to true by default. This flag may 1.235 + * be removed from the product in the future. 1.236 + * 1.237 + */ 1.238 +class PerfData : public CHeapObj { 1.239 + 1.240 + friend class StatSampler; // for access to protected void sample() 1.241 + friend class PerfDataManager; // for access to protected destructor 1.242 + 1.243 + public: 1.244 + 1.245 + // the Variability enum must be kept in synchronization with the 1.246 + // the com.sun.hotspot.perfdata.Variability class 1.247 + enum Variability { 1.248 + V_Constant = 1, 1.249 + V_Monotonic = 2, 1.250 + V_Variable = 3, 1.251 + V_last = V_Variable 1.252 + }; 1.253 + 1.254 + // the Units enum must be kept in synchronization with the 1.255 + // the com.sun.hotspot.perfdata.Units class 1.256 + enum Units { 1.257 + U_None = 1, 1.258 + U_Bytes = 2, 1.259 + U_Ticks = 3, 1.260 + U_Events = 4, 1.261 + U_String = 5, 1.262 + U_Hertz = 6, 1.263 + U_Last = U_Hertz 1.264 + }; 1.265 + 1.266 + // Miscellaneous flags 1.267 + enum Flags { 1.268 + F_None = 0x0, 1.269 + F_Supported = 0x1 // interface is supported - java.* and com.sun.* 1.270 + }; 1.271 + 1.272 + private: 1.273 + char* _name; 1.274 + Variability _v; 1.275 + Units _u; 1.276 + bool _on_c_heap; 1.277 + Flags _flags; 1.278 + 1.279 + PerfDataEntry* _pdep; 1.280 + 1.281 + protected: 1.282 + 1.283 + void *_valuep; 1.284 + 1.285 + PerfData(CounterNS ns, const char* name, Units u, Variability v); 1.286 + ~PerfData(); 1.287 + 1.288 + // create the entry for the PerfData item in the PerfData memory region. 1.289 + // this region is maintained separately from the PerfData objects to 1.290 + // facilitate its use by external processes. 1.291 + void create_entry(BasicType dtype, size_t dsize, size_t dlen = 0); 1.292 + 1.293 + // sample the data item given at creation time and write its value 1.294 + // into the its corresponding PerfMemory location. 1.295 + virtual void sample() = 0; 1.296 + 1.297 + public: 1.298 + 1.299 + // returns a boolean indicating the validity of this object. 1.300 + // the object is valid if and only if memory in PerfMemory 1.301 + // region was successfully allocated. 1.302 + inline bool is_valid() { return _valuep != NULL; } 1.303 + 1.304 + // returns a boolean indicating whether the underlying object 1.305 + // was allocated in the PerfMemory region or on the C heap. 1.306 + inline bool is_on_c_heap() { return _on_c_heap; } 1.307 + 1.308 + // returns a pointer to a char* containing the name of the item. 1.309 + // The pointer returned is the pointer to a copy of the name 1.310 + // passed to the constructor, not the pointer to the name in the 1.311 + // PerfData memory region. This redundancy is maintained for 1.312 + // security reasons as the PerfMemory region may be in shared 1.313 + // memory. 1.314 + const char* name() { return _name; } 1.315 + 1.316 + // returns the variability classification associated with this item 1.317 + Variability variability() { return _v; } 1.318 + 1.319 + // returns the units associated with this item. 1.320 + Units units() { return _u; } 1.321 + 1.322 + // returns the flags associated with this item. 1.323 + Flags flags() { return _flags; } 1.324 + 1.325 + // returns the address of the data portion of the item in the 1.326 + // PerfData memory region. 1.327 + inline void* get_address() { return _valuep; } 1.328 + 1.329 + // returns the value of the data portion of the item in the 1.330 + // PerfData memory region formatted as a string. 1.331 + virtual int format(char* cp, int length) = 0; 1.332 +}; 1.333 + 1.334 +/* 1.335 + * PerfLongSampleHelper, and its alias PerfSamplerHelper, is a base class 1.336 + * for helper classes that rely upon the StatSampler periodic task to 1.337 + * invoke the take_sample() method and write the value returned to its 1.338 + * appropriate location in the PerfData memory region. 1.339 + */ 1.340 +class PerfLongSampleHelper : public CHeapObj { 1.341 + public: 1.342 + virtual jlong take_sample() = 0; 1.343 +}; 1.344 + 1.345 +typedef PerfLongSampleHelper PerfSampleHelper; 1.346 + 1.347 + 1.348 +/* 1.349 + * PerfLong is the base class for the various Long PerfData subtypes. 1.350 + * it contains implementation details that are common among its derived 1.351 + * types. 1.352 + */ 1.353 +class PerfLong : public PerfData { 1.354 + 1.355 + protected: 1.356 + 1.357 + PerfLong(CounterNS ns, const char* namep, Units u, Variability v); 1.358 + 1.359 + public: 1.360 + int format(char* buffer, int length); 1.361 + 1.362 + // returns the value of the data portion of the item in the 1.363 + // PerfData memory region. 1.364 + inline jlong get_value() { return *(jlong*)_valuep; } 1.365 +}; 1.366 + 1.367 +/* 1.368 + * The PerfLongConstant class, and its alias PerfConstant, implement 1.369 + * a PerfData subtype that holds a jlong data value that is set upon 1.370 + * creation of an instance of this class. This class provides no 1.371 + * methods for changing the data value stored in PerfData memory region. 1.372 + */ 1.373 +class PerfLongConstant : public PerfLong { 1.374 + 1.375 + friend class PerfDataManager; // for access to protected constructor 1.376 + 1.377 + private: 1.378 + // hide sample() - no need to sample constants 1.379 + void sample() { } 1.380 + 1.381 + protected: 1.382 + 1.383 + PerfLongConstant(CounterNS ns, const char* namep, Units u, 1.384 + jlong initial_value=0) 1.385 + : PerfLong(ns, namep, u, V_Constant) { 1.386 + 1.387 + if (is_valid()) *(jlong*)_valuep = initial_value; 1.388 + } 1.389 +}; 1.390 + 1.391 +typedef PerfLongConstant PerfConstant; 1.392 + 1.393 +/* 1.394 + * The PerfLongVariant class, and its alias PerfVariant, implement 1.395 + * a PerfData subtype that holds a jlong data value that can be modified 1.396 + * in an unrestricted manner. This class provides the implementation details 1.397 + * for common functionality among its derived types. 1.398 + */ 1.399 +class PerfLongVariant : public PerfLong { 1.400 + 1.401 + protected: 1.402 + jlong* _sampled; 1.403 + PerfLongSampleHelper* _sample_helper; 1.404 + 1.405 + PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v, 1.406 + jlong initial_value=0) 1.407 + : PerfLong(ns, namep, u, v) { 1.408 + if (is_valid()) *(jlong*)_valuep = initial_value; 1.409 + } 1.410 + 1.411 + PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v, 1.412 + jlong* sampled); 1.413 + 1.414 + PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v, 1.415 + PerfLongSampleHelper* sample_helper); 1.416 + 1.417 + void sample(); 1.418 + 1.419 + public: 1.420 + inline void inc() { (*(jlong*)_valuep)++; } 1.421 + inline void inc(jlong val) { (*(jlong*)_valuep) += val; } 1.422 + inline void add(jlong val) { (*(jlong*)_valuep) += val; } 1.423 +}; 1.424 + 1.425 +/* 1.426 + * The PerfLongCounter class, and its alias PerfCounter, implement 1.427 + * a PerfData subtype that holds a jlong data value that can (should) 1.428 + * be modified in a monotonic manner. The inc(jlong) and add(jlong) 1.429 + * methods can be passed negative values to implement a monotonically 1.430 + * decreasing value. However, we rely upon the programmer to honor 1.431 + * the notion that this counter always moves in the same direction - 1.432 + * either increasing or decreasing. 1.433 + */ 1.434 +class PerfLongCounter : public PerfLongVariant { 1.435 + 1.436 + friend class PerfDataManager; // for access to protected constructor 1.437 + 1.438 + protected: 1.439 + 1.440 + PerfLongCounter(CounterNS ns, const char* namep, Units u, 1.441 + jlong initial_value=0) 1.442 + : PerfLongVariant(ns, namep, u, V_Monotonic, 1.443 + initial_value) { } 1.444 + 1.445 + PerfLongCounter(CounterNS ns, const char* namep, Units u, jlong* sampled) 1.446 + : PerfLongVariant(ns, namep, u, V_Monotonic, sampled) { } 1.447 + 1.448 + PerfLongCounter(CounterNS ns, const char* namep, Units u, 1.449 + PerfLongSampleHelper* sample_helper) 1.450 + : PerfLongVariant(ns, namep, u, V_Monotonic, 1.451 + sample_helper) { } 1.452 +}; 1.453 + 1.454 +typedef PerfLongCounter PerfCounter; 1.455 + 1.456 +/* 1.457 + * The PerfLongVariable class, and its alias PerfVariable, implement 1.458 + * a PerfData subtype that holds a jlong data value that can 1.459 + * be modified in an unrestricted manner. 1.460 + */ 1.461 +class PerfLongVariable : public PerfLongVariant { 1.462 + 1.463 + friend class PerfDataManager; // for access to protected constructor 1.464 + 1.465 + protected: 1.466 + 1.467 + PerfLongVariable(CounterNS ns, const char* namep, Units u, 1.468 + jlong initial_value=0) 1.469 + : PerfLongVariant(ns, namep, u, V_Variable, 1.470 + initial_value) { } 1.471 + 1.472 + PerfLongVariable(CounterNS ns, const char* namep, Units u, jlong* sampled) 1.473 + : PerfLongVariant(ns, namep, u, V_Variable, sampled) { } 1.474 + 1.475 + PerfLongVariable(CounterNS ns, const char* namep, Units u, 1.476 + PerfLongSampleHelper* sample_helper) 1.477 + : PerfLongVariant(ns, namep, u, V_Variable, 1.478 + sample_helper) { } 1.479 + 1.480 + public: 1.481 + inline void set_value(jlong val) { (*(jlong*)_valuep) = val; } 1.482 +}; 1.483 + 1.484 +typedef PerfLongVariable PerfVariable; 1.485 + 1.486 +/* 1.487 + * The PerfByteArray provides a PerfData subtype that allows the creation 1.488 + * of a contiguous region of the PerfData memory region for storing a vector 1.489 + * of bytes. This class is currently intended to be a base class for 1.490 + * the PerfString class, and cannot be instantiated directly. 1.491 + */ 1.492 +class PerfByteArray : public PerfData { 1.493 + 1.494 + protected: 1.495 + jint _length; 1.496 + 1.497 + PerfByteArray(CounterNS ns, const char* namep, Units u, Variability v, 1.498 + jint length); 1.499 +}; 1.500 + 1.501 +class PerfString : public PerfByteArray { 1.502 + 1.503 + protected: 1.504 + 1.505 + void set_string(const char* s2); 1.506 + 1.507 + PerfString(CounterNS ns, const char* namep, Variability v, jint length, 1.508 + const char* initial_value) 1.509 + : PerfByteArray(ns, namep, U_String, v, length) { 1.510 + if (is_valid()) set_string(initial_value); 1.511 + } 1.512 + 1.513 + public: 1.514 + 1.515 + int format(char* buffer, int length); 1.516 +}; 1.517 + 1.518 +/* 1.519 + * The PerfStringConstant class provides a PerfData sub class that 1.520 + * allows a null terminated string of single byte characters to be 1.521 + * stored in the PerfData memory region. 1.522 + */ 1.523 +class PerfStringConstant : public PerfString { 1.524 + 1.525 + friend class PerfDataManager; // for access to protected constructor 1.526 + 1.527 + private: 1.528 + 1.529 + // hide sample() - no need to sample constants 1.530 + void sample() { } 1.531 + 1.532 + protected: 1.533 + 1.534 + // Restrict string constant lengths to be <= PerfMaxStringConstLength. 1.535 + // This prevents long string constants, as can occur with very 1.536 + // long classpaths or java command lines, from consuming too much 1.537 + // PerfData memory. 1.538 + PerfStringConstant(CounterNS ns, const char* namep, 1.539 + const char* initial_value); 1.540 +}; 1.541 + 1.542 +/* 1.543 + * The PerfStringVariable class provides a PerfData sub class that 1.544 + * allows a null terminated string of single byte character data 1.545 + * to be stored in PerfData memory region. The string value can be reset 1.546 + * after initialization. If the string value is >= max_length, then 1.547 + * it will be truncated to max_length characters. The copied string 1.548 + * is always null terminated. 1.549 + */ 1.550 +class PerfStringVariable : public PerfString { 1.551 + 1.552 + friend class PerfDataManager; // for access to protected constructor 1.553 + 1.554 + protected: 1.555 + 1.556 + // sampling of string variables are not yet supported 1.557 + void sample() { } 1.558 + 1.559 + PerfStringVariable(CounterNS ns, const char* namep, jint max_length, 1.560 + const char* initial_value) 1.561 + : PerfString(ns, namep, V_Variable, max_length+1, 1.562 + initial_value) { } 1.563 + 1.564 + public: 1.565 + inline void set_value(const char* val) { set_string(val); } 1.566 +}; 1.567 + 1.568 + 1.569 +/* 1.570 + * The PerfDataList class is a container class for managing lists 1.571 + * of PerfData items. The intention of this class is to allow for 1.572 + * alternative implementations for management of list of PerfData 1.573 + * items without impacting the code that uses the lists. 1.574 + * 1.575 + * The initial implementation is based upon GrowableArray. Searches 1.576 + * on GrowableArray types is linear in nature and this may become 1.577 + * a performance issue for creation of PerfData items, particularly 1.578 + * from Java code where a test for existence is implemented as a 1.579 + * search over all existing PerfData items. 1.580 + * 1.581 + * The abstraction is not complete. A more general container class 1.582 + * would provide an Iterator abstraction that could be used to 1.583 + * traverse the lists. This implementation still relys upon integer 1.584 + * iterators and the at(int index) method. However, the GrowableArray 1.585 + * is not directly visible outside this class and can be replaced by 1.586 + * some other implementation, as long as that implementation provides 1.587 + * a mechanism to iterate over the container by index. 1.588 + */ 1.589 +class PerfDataList : public CHeapObj { 1.590 + 1.591 + private: 1.592 + 1.593 + // GrowableArray implementation 1.594 + typedef GrowableArray<PerfData*> PerfDataArray; 1.595 + 1.596 + PerfDataArray* _set; 1.597 + 1.598 + // method to search for a instrumentation object by name 1.599 + static bool by_name(void* name, PerfData* pd); 1.600 + 1.601 + protected: 1.602 + // we expose the implementation here to facilitate the clone 1.603 + // method. 1.604 + PerfDataArray* get_impl() { return _set; } 1.605 + 1.606 + public: 1.607 + 1.608 + // create a PerfDataList with the given initial length 1.609 + PerfDataList(int length); 1.610 + 1.611 + // create a PerfDataList as a shallow copy of the given PerfDataList 1.612 + PerfDataList(PerfDataList* p); 1.613 + 1.614 + ~PerfDataList(); 1.615 + 1.616 + // return the PerfData item indicated by name, 1.617 + // or NULL if it doesn't exist. 1.618 + PerfData* find_by_name(const char* name); 1.619 + 1.620 + // return true if a PerfData item with the name specified in the 1.621 + // argument exists, otherwise return false. 1.622 + bool contains(const char* name) { return find_by_name(name) != NULL; } 1.623 + 1.624 + // return the number of PerfData items in this list 1.625 + int length() { return _set->length(); } 1.626 + 1.627 + // add a PerfData item to this list 1.628 + void append(PerfData *p) { _set->append(p); } 1.629 + 1.630 + // remove the given PerfData item from this list. When called 1.631 + // while iterating over the list, this method will result in a 1.632 + // change in the length of the container. The at(int index) 1.633 + // method is also impacted by this method as elements with an 1.634 + // index greater than the index of the element removed by this 1.635 + // method will be shifted down by one. 1.636 + void remove(PerfData *p) { _set->remove(p); } 1.637 + 1.638 + // create a new PerfDataList from this list. The new list is 1.639 + // a shallow copy of the original list and care should be taken 1.640 + // with respect to delete operations on the elements of the list 1.641 + // as the are likely in use by another copy of the list. 1.642 + PerfDataList* clone(); 1.643 + 1.644 + // for backward compatibility with GrowableArray - need to implement 1.645 + // some form of iterator to provide a cleaner abstraction for 1.646 + // iteration over the container. 1.647 + PerfData* at(int index) { return _set->at(index); } 1.648 +}; 1.649 + 1.650 + 1.651 +/* 1.652 + * The PerfDataManager class is responsible for creating PerfData 1.653 + * subtypes via a set a factory methods and for managing lists 1.654 + * of the various PerfData types. 1.655 + */ 1.656 +class PerfDataManager : AllStatic { 1.657 + 1.658 + friend class StatSampler; // for access to protected PerfDataList methods 1.659 + 1.660 + private: 1.661 + static PerfDataList* _all; 1.662 + static PerfDataList* _sampled; 1.663 + static PerfDataList* _constants; 1.664 + static const char* _name_spaces[]; 1.665 + 1.666 + // add a PerfData item to the list(s) of know PerfData objects 1.667 + static void add_item(PerfData* p, bool sampled); 1.668 + 1.669 + protected: 1.670 + // return the list of all known PerfData items 1.671 + static PerfDataList* all(); 1.672 + static int count() { return _all->length(); } 1.673 + 1.674 + // return the list of all known PerfData items that are to be 1.675 + // sampled by the StatSampler. 1.676 + static PerfDataList* sampled(); 1.677 + static int sampled_count() { return _sampled->length(); } 1.678 + 1.679 + // return the list of all known PerfData items that have a 1.680 + // variability classification of type Constant 1.681 + static PerfDataList* constants(); 1.682 + static int constants_count() { return _constants->length(); } 1.683 + 1.684 + public: 1.685 + 1.686 + // method to check for the existence of a PerfData item with 1.687 + // the given name. 1.688 + static bool exists(const char* name) { return _all->contains(name); } 1.689 + 1.690 + // method to map a CounterNS enumeration to a namespace string 1.691 + static const char* ns_to_string(CounterNS ns) { 1.692 + return _name_spaces[ns]; 1.693 + } 1.694 + 1.695 + // methods to test the interface stability of a given counter namespace 1.696 + // 1.697 + static bool is_stable_supported(CounterNS ns) { 1.698 + return (ns != NULL_NS) && ((ns % 3) == JAVA_NS); 1.699 + } 1.700 + static bool is_unstable_supported(CounterNS ns) { 1.701 + return (ns != NULL_NS) && ((ns % 3) == COM_NS); 1.702 + } 1.703 + static bool is_unstable_unsupported(CounterNS ns) { 1.704 + return (ns == NULL_NS) || ((ns % 3) == SUN_NS); 1.705 + } 1.706 + 1.707 + // methods to test the interface stability of a given counter name 1.708 + // 1.709 + static bool is_stable_supported(const char* name) { 1.710 + const char* javadot = "java."; 1.711 + return strncmp(name, javadot, strlen(javadot)) == 0; 1.712 + } 1.713 + static bool is_unstable_supported(const char* name) { 1.714 + const char* comdot = "com.sun."; 1.715 + return strncmp(name, comdot, strlen(comdot)) == 0; 1.716 + } 1.717 + static bool is_unstable_unsupported(const char* name) { 1.718 + return !(is_stable_supported(name) && is_unstable_supported(name)); 1.719 + } 1.720 + 1.721 + // method to construct counter name strings in a given name space. 1.722 + // The string object is allocated from the Resource Area and calls 1.723 + // to this method must be made within a ResourceMark. 1.724 + // 1.725 + static char* counter_name(const char* name_space, const char* name); 1.726 + 1.727 + // method to construct name space strings in a given name space. 1.728 + // The string object is allocated from the Resource Area and calls 1.729 + // to this method must be made within a ResourceMark. 1.730 + // 1.731 + static char* name_space(const char* name_space, const char* sub_space) { 1.732 + return counter_name(name_space, sub_space); 1.733 + } 1.734 + 1.735 + // same as above, but appends the instance number to the name space 1.736 + // 1.737 + static char* name_space(const char* name_space, const char* sub_space, 1.738 + int instance); 1.739 + static char* name_space(const char* name_space, int instance); 1.740 + 1.741 + 1.742 + // these methods provide the general interface for creating 1.743 + // performance data resources. The types of performance data 1.744 + // resources can be extended by adding additional create<type> 1.745 + // methods. 1.746 + 1.747 + // Constant Types 1.748 + static PerfStringConstant* create_string_constant(CounterNS ns, 1.749 + const char* name, 1.750 + const char *s, TRAPS); 1.751 + 1.752 + static PerfLongConstant* create_long_constant(CounterNS ns, 1.753 + const char* name, 1.754 + PerfData::Units u, 1.755 + jlong val, TRAPS); 1.756 + 1.757 + 1.758 + // Variable Types 1.759 + static PerfStringVariable* create_string_variable(CounterNS ns, 1.760 + const char* name, 1.761 + int max_length, 1.762 + const char *s, TRAPS); 1.763 + 1.764 + static PerfStringVariable* create_string_variable(CounterNS ns, 1.765 + const char* name, 1.766 + const char *s, TRAPS) { 1.767 + return create_string_variable(ns, name, 0, s, CHECK_NULL); 1.768 + }; 1.769 + 1.770 + static PerfLongVariable* create_long_variable(CounterNS ns, 1.771 + const char* name, 1.772 + PerfData::Units u, 1.773 + jlong ival, TRAPS); 1.774 + 1.775 + static PerfLongVariable* create_long_variable(CounterNS ns, 1.776 + const char* name, 1.777 + PerfData::Units u, TRAPS) { 1.778 + return create_long_variable(ns, name, u, (jlong)0, CHECK_NULL); 1.779 + }; 1.780 + 1.781 + static PerfLongVariable* create_long_variable(CounterNS, const char* name, 1.782 + PerfData::Units u, 1.783 + jlong* sp, TRAPS); 1.784 + 1.785 + static PerfLongVariable* create_long_variable(CounterNS ns, 1.786 + const char* name, 1.787 + PerfData::Units u, 1.788 + PerfLongSampleHelper* sh, 1.789 + TRAPS); 1.790 + 1.791 + 1.792 + // Counter Types 1.793 + static PerfLongCounter* create_long_counter(CounterNS ns, const char* name, 1.794 + PerfData::Units u, 1.795 + jlong ival, TRAPS); 1.796 + 1.797 + static PerfLongCounter* create_long_counter(CounterNS ns, const char* name, 1.798 + PerfData::Units u, TRAPS) { 1.799 + return create_long_counter(ns, name, u, (jlong)0, CHECK_NULL); 1.800 + }; 1.801 + 1.802 + static PerfLongCounter* create_long_counter(CounterNS ns, const char* name, 1.803 + PerfData::Units u, jlong* sp, 1.804 + TRAPS); 1.805 + 1.806 + static PerfLongCounter* create_long_counter(CounterNS ns, const char* name, 1.807 + PerfData::Units u, 1.808 + PerfLongSampleHelper* sh, 1.809 + TRAPS); 1.810 + 1.811 + 1.812 + // these creation methods are provided for ease of use. These allow 1.813 + // Long performance data types to be created with a shorthand syntax. 1.814 + 1.815 + static PerfConstant* create_constant(CounterNS ns, const char* name, 1.816 + PerfData::Units u, jlong val, TRAPS) { 1.817 + return create_long_constant(ns, name, u, val, CHECK_NULL); 1.818 + } 1.819 + 1.820 + static PerfVariable* create_variable(CounterNS ns, const char* name, 1.821 + PerfData::Units u, jlong ival, TRAPS) { 1.822 + return create_long_variable(ns, name, u, ival, CHECK_NULL); 1.823 + } 1.824 + 1.825 + static PerfVariable* create_variable(CounterNS ns, const char* name, 1.826 + PerfData::Units u, TRAPS) { 1.827 + return create_long_variable(ns, name, u, (jlong)0, CHECK_NULL); 1.828 + } 1.829 + 1.830 + static PerfVariable* create_variable(CounterNS ns, const char* name, 1.831 + PerfData::Units u, jlong* sp, TRAPS) { 1.832 + return create_long_variable(ns, name, u, sp, CHECK_NULL); 1.833 + } 1.834 + 1.835 + static PerfVariable* create_variable(CounterNS ns, const char* name, 1.836 + PerfData::Units u, 1.837 + PerfSampleHelper* sh, TRAPS) { 1.838 + return create_long_variable(ns, name, u, sh, CHECK_NULL); 1.839 + } 1.840 + 1.841 + static PerfCounter* create_counter(CounterNS ns, const char* name, 1.842 + PerfData::Units u, jlong ival, TRAPS) { 1.843 + return create_long_counter(ns, name, u, ival, CHECK_NULL); 1.844 + } 1.845 + 1.846 + static PerfCounter* create_counter(CounterNS ns, const char* name, 1.847 + PerfData::Units u, TRAPS) { 1.848 + return create_long_counter(ns, name, u, (jlong)0, CHECK_NULL); 1.849 + } 1.850 + 1.851 + static PerfCounter* create_counter(CounterNS ns, const char* name, 1.852 + PerfData::Units u, jlong* sp, TRAPS) { 1.853 + return create_long_counter(ns, name, u, sp, CHECK_NULL); 1.854 + } 1.855 + 1.856 + static PerfCounter* create_counter(CounterNS ns, const char* name, 1.857 + PerfData::Units u, 1.858 + PerfSampleHelper* sh, TRAPS) { 1.859 + return create_long_counter(ns, name, u, sh, CHECK_NULL); 1.860 + } 1.861 + 1.862 + static void destroy(); 1.863 +}; 1.864 + 1.865 +// Useful macros to create the performance counters 1.866 +#define NEWPERFTICKCOUNTER(counter, counter_ns, counter_name) \ 1.867 + {counter = PerfDataManager::create_counter(counter_ns, counter_name, \ 1.868 + PerfData::U_Ticks,CHECK);} 1.869 + 1.870 +#define NEWPERFEVENTCOUNTER(counter, counter_ns, counter_name) \ 1.871 + {counter = PerfDataManager::create_counter(counter_ns, counter_name, \ 1.872 + PerfData::U_Events,CHECK);} 1.873 + 1.874 +// Utility Classes 1.875 + 1.876 +/* 1.877 + * this class will administer a PerfCounter used as a time accumulator 1.878 + * for a basic block much like the TraceTime class. 1.879 + * 1.880 + * Example: 1.881 + * 1.882 + * static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, 0LL, CHECK); 1.883 + * 1.884 + * { 1.885 + * PerfTraceTime ptt(my_time_counter); 1.886 + * // perform the operation you want to measure 1.887 + * } 1.888 + * 1.889 + * Note: use of this class does not need to occur within a guarded 1.890 + * block. The UsePerfData guard is used with the implementation 1.891 + * of this class. 1.892 + */ 1.893 +class PerfTraceTime : public StackObj { 1.894 + 1.895 + protected: 1.896 + elapsedTimer _t; 1.897 + PerfLongCounter* _timerp; 1.898 + // pointer to thread-local or global recursion counter variable 1.899 + int* _recursion_counter; 1.900 + 1.901 + public: 1.902 + inline PerfTraceTime(PerfLongCounter* timerp) : _timerp(timerp), _recursion_counter(NULL) { 1.903 + if (!UsePerfData) return; 1.904 + _t.start(); 1.905 + } 1.906 + 1.907 + inline PerfTraceTime(PerfLongCounter* timerp, int* recursion_counter) : _timerp(timerp), _recursion_counter(recursion_counter) { 1.908 + if (!UsePerfData || (_recursion_counter != NULL && 1.909 + (*_recursion_counter)++ > 0)) return; 1.910 + _t.start(); 1.911 + } 1.912 + 1.913 + inline void suspend() { if (!UsePerfData) return; _t.stop(); } 1.914 + inline void resume() { if (!UsePerfData) return; _t.start(); } 1.915 + 1.916 + inline ~PerfTraceTime() { 1.917 + if (!UsePerfData || (_recursion_counter != NULL && 1.918 + --(*_recursion_counter) > 0)) return; 1.919 + _t.stop(); 1.920 + _timerp->inc(_t.ticks()); 1.921 + } 1.922 +}; 1.923 + 1.924 +/* The PerfTraceTimedEvent class is responsible for counting the 1.925 + * occurrence of some event and measuring the the elapsed time of 1.926 + * the event in two separate PerfCounter instances. 1.927 + * 1.928 + * Example: 1.929 + * 1.930 + * static PerfCounter* my_time_counter = PerfDataManager::create_counter("my.time.counter", PerfData::U_Ticks, CHECK); 1.931 + * static PerfCounter* my_event_counter = PerfDataManager::create_counter("my.event.counter", PerfData::U_Events, CHECK); 1.932 + * 1.933 + * { 1.934 + * PerfTraceTimedEvent ptte(my_time_counter, my_event_counter); 1.935 + * // perform the operation you want to count and measure 1.936 + * } 1.937 + * 1.938 + * Note: use of this class does not need to occur within a guarded 1.939 + * block. The UsePerfData guard is used with the implementation 1.940 + * of this class. 1.941 + * 1.942 + */ 1.943 +class PerfTraceTimedEvent : public PerfTraceTime { 1.944 + 1.945 + protected: 1.946 + PerfLongCounter* _eventp; 1.947 + 1.948 + public: 1.949 + inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp): PerfTraceTime(timerp), _eventp(eventp) { 1.950 + if (!UsePerfData) return; 1.951 + _eventp->inc(); 1.952 + } 1.953 + 1.954 + inline PerfTraceTimedEvent(PerfLongCounter* timerp, PerfLongCounter* eventp, int* recursion_counter): PerfTraceTime(timerp, recursion_counter), _eventp(eventp) { 1.955 + if (!UsePerfData) return; 1.956 + _eventp->inc(); 1.957 + } 1.958 +};