src/share/vm/runtime/statSampler.cpp

Fri, 29 Apr 2016 00:06:10 +0800

author
aoqi
date
Fri, 29 Apr 2016 00:06:10 +0800
changeset 1
2d8a650513c2
parent 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Added MIPS 64-bit port.

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@1 25 /*
aoqi@1 26 * This file has been modified by Loongson Technology in 2015. These
aoqi@1 27 * modifications are Copyright (c) 2015 Loongson Technology, and are made
aoqi@1 28 * available on the same license terms set forth above.
aoqi@1 29 */
aoqi@1 30
aoqi@0 31 #include "precompiled.hpp"
aoqi@0 32 #include "classfile/systemDictionary.hpp"
aoqi@0 33 #include "classfile/vmSymbols.hpp"
aoqi@0 34 #include "memory/allocation.inline.hpp"
aoqi@0 35 #include "memory/resourceArea.hpp"
aoqi@0 36 #include "oops/oop.inline.hpp"
aoqi@0 37 #include "runtime/arguments.hpp"
aoqi@0 38 #include "runtime/java.hpp"
aoqi@0 39 #include "runtime/javaCalls.hpp"
aoqi@0 40 #include "runtime/os.hpp"
aoqi@0 41 #include "runtime/statSampler.hpp"
aoqi@0 42 #ifdef TARGET_ARCH_x86
aoqi@0 43 # include "vm_version_x86.hpp"
aoqi@0 44 #endif
aoqi@0 45 #ifdef TARGET_ARCH_sparc
aoqi@0 46 # include "vm_version_sparc.hpp"
aoqi@0 47 #endif
aoqi@0 48 #ifdef TARGET_ARCH_zero
aoqi@0 49 # include "vm_version_zero.hpp"
aoqi@0 50 #endif
aoqi@0 51 #ifdef TARGET_ARCH_arm
aoqi@0 52 # include "vm_version_arm.hpp"
aoqi@0 53 #endif
aoqi@0 54 #ifdef TARGET_ARCH_ppc
aoqi@0 55 # include "vm_version_ppc.hpp"
aoqi@0 56 #endif
aoqi@1 57 #ifdef TARGET_ARCH_mips
aoqi@1 58 # include "vm_version_mips.hpp"
aoqi@1 59 #endif
aoqi@0 60
aoqi@0 61 // --------------------------------------------------------
aoqi@0 62 // StatSamplerTask
aoqi@0 63
aoqi@0 64 class StatSamplerTask : public PeriodicTask {
aoqi@0 65 public:
aoqi@0 66 StatSamplerTask(int interval_time) : PeriodicTask(interval_time) {}
aoqi@0 67 void task() { StatSampler::collect_sample(); }
aoqi@0 68 };
aoqi@0 69
aoqi@0 70
aoqi@0 71 //----------------------------------------------------------
aoqi@0 72 // Implementation of StatSampler
aoqi@0 73
aoqi@0 74 StatSamplerTask* StatSampler::_task = NULL;
aoqi@0 75 PerfDataList* StatSampler::_sampled = NULL;
aoqi@0 76
aoqi@0 77 /*
aoqi@0 78 * the initialize method is called from the engage() method
aoqi@0 79 * and is responsible for initializing various global variables.
aoqi@0 80 */
aoqi@0 81 void StatSampler::initialize() {
aoqi@0 82
aoqi@0 83 if (!UsePerfData) return;
aoqi@0 84
aoqi@0 85 // create performance data that could not be created prior
aoqi@0 86 // to vm_init_globals() or otherwise have no logical home.
aoqi@0 87
aoqi@0 88 create_misc_perfdata();
aoqi@0 89
aoqi@0 90 // get copy of the sampled list
aoqi@0 91 _sampled = PerfDataManager::sampled();
aoqi@0 92
aoqi@0 93 }
aoqi@0 94
aoqi@0 95 /*
aoqi@0 96 * The engage() method is called at initialization time via
aoqi@0 97 * Thread::create_vm() to initialize the StatSampler and
aoqi@0 98 * register it with the WatcherThread as a periodic task.
aoqi@0 99 */
aoqi@0 100 void StatSampler::engage() {
aoqi@0 101
aoqi@0 102 if (!UsePerfData) return;
aoqi@0 103
aoqi@0 104 if (!is_active()) {
aoqi@0 105
aoqi@0 106 initialize();
aoqi@0 107
aoqi@0 108 // start up the periodic task
aoqi@0 109 _task = new StatSamplerTask(PerfDataSamplingInterval);
aoqi@0 110 _task->enroll();
aoqi@0 111 }
aoqi@0 112 }
aoqi@0 113
aoqi@0 114
aoqi@0 115 /*
aoqi@0 116 * the disengage() method is responsible for deactivating the periodic
aoqi@0 117 * task and, if logging was enabled, for logging the final sample. This
aoqi@0 118 * method is called from before_exit() in java.cpp and is only called
aoqi@0 119 * after the WatcherThread has been stopped.
aoqi@0 120 */
aoqi@0 121 void StatSampler::disengage() {
aoqi@0 122
aoqi@0 123 if (!UsePerfData) return;
aoqi@0 124
aoqi@0 125 if (!is_active())
aoqi@0 126 return;
aoqi@0 127
aoqi@0 128 // remove StatSamplerTask
aoqi@0 129 _task->disenroll();
aoqi@0 130 delete _task;
aoqi@0 131 _task = NULL;
aoqi@0 132
aoqi@0 133 // force a final sample
aoqi@0 134 sample_data(_sampled);
aoqi@0 135 }
aoqi@0 136
aoqi@0 137 /*
aoqi@0 138 * the destroy method is responsible for releasing any resources used by
aoqi@0 139 * the StatSampler prior to shutdown of the VM. this method is called from
aoqi@0 140 * before_exit() in java.cpp and is only called after the WatcherThread
aoqi@0 141 * has stopped.
aoqi@0 142 */
aoqi@0 143 void StatSampler::destroy() {
aoqi@0 144
aoqi@0 145 if (!UsePerfData) return;
aoqi@0 146
aoqi@0 147 if (_sampled != NULL) {
aoqi@0 148 delete(_sampled);
aoqi@0 149 _sampled = NULL;
aoqi@0 150 }
aoqi@0 151 }
aoqi@0 152
aoqi@0 153 /*
aoqi@0 154 * The sample_data() method is responsible for sampling the
aoqi@0 155 * the data value for each PerfData instance in the given list.
aoqi@0 156 */
aoqi@0 157 void StatSampler::sample_data(PerfDataList* list) {
aoqi@0 158
aoqi@0 159 assert(list != NULL, "null list unexpected");
aoqi@0 160
aoqi@0 161 for (int index = 0; index < list->length(); index++) {
aoqi@0 162 PerfData* item = list->at(index);
aoqi@0 163 item->sample();
aoqi@0 164 }
aoqi@0 165 }
aoqi@0 166
aoqi@0 167 /*
aoqi@0 168 * the collect_sample() method is the method invoked by the
aoqi@0 169 * WatcherThread via the PeriodicTask::task() method. This method
aoqi@0 170 * is responsible for collecting data samples from sampled
aoqi@0 171 * PerfData instances every PerfDataSamplingInterval milliseconds.
aoqi@0 172 * It is also responsible for logging the requested set of
aoqi@0 173 * PerfData instances every _sample_count milliseconds. While
aoqi@0 174 * logging data, it will output a column header after every _print_header
aoqi@0 175 * rows of data have been logged.
aoqi@0 176 */
aoqi@0 177 void StatSampler::collect_sample() {
aoqi@0 178
aoqi@0 179 // future - check for new PerfData objects. PerfData objects might
aoqi@0 180 // get added to the PerfDataManager lists after we have already
aoqi@0 181 // built our local copies.
aoqi@0 182 //
aoqi@0 183 // if (PerfDataManager::count() > previous) {
aoqi@0 184 // // get a new copy of the sampled list
aoqi@0 185 // if (_sampled != NULL) {
aoqi@0 186 // delete(_sampled);
aoqi@0 187 // _sampled = NULL;
aoqi@0 188 // }
aoqi@0 189 // _sampled = PerfDataManager::sampled();
aoqi@0 190 // }
aoqi@0 191
aoqi@0 192 assert(_sampled != NULL, "list not initialized");
aoqi@0 193
aoqi@0 194 sample_data(_sampled);
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 /*
aoqi@0 198 * method to upcall into Java to return the value of the specified
aoqi@0 199 * property as a utf8 string, or NULL if does not exist. The caller
aoqi@0 200 * is responsible for setting a ResourceMark for proper cleanup of
aoqi@0 201 * the utf8 strings.
aoqi@0 202 */
aoqi@0 203 const char* StatSampler::get_system_property(const char* name, TRAPS) {
aoqi@0 204
aoqi@0 205 // setup the arguments to getProperty
aoqi@0 206 Handle key_str = java_lang_String::create_from_str(name, CHECK_NULL);
aoqi@0 207
aoqi@0 208 // return value
aoqi@0 209 JavaValue result(T_OBJECT);
aoqi@0 210
aoqi@0 211 // public static String getProperty(String key, String def);
aoqi@0 212 JavaCalls::call_static(&result,
aoqi@0 213 KlassHandle(THREAD, SystemDictionary::System_klass()),
aoqi@0 214 vmSymbols::getProperty_name(),
aoqi@0 215 vmSymbols::string_string_signature(),
aoqi@0 216 key_str,
aoqi@0 217 CHECK_NULL);
aoqi@0 218
aoqi@0 219 oop value_oop = (oop)result.get_jobject();
aoqi@0 220 if (value_oop == NULL) {
aoqi@0 221 return NULL;
aoqi@0 222 }
aoqi@0 223
aoqi@0 224 // convert Java String to utf8 string
aoqi@0 225 char* value = java_lang_String::as_utf8_string(value_oop);
aoqi@0 226
aoqi@0 227 return value;
aoqi@0 228 }
aoqi@0 229
aoqi@0 230 /*
aoqi@0 231 * The list of System Properties that have corresponding PerfData
aoqi@0 232 * string instrumentation created by retrieving the named property's
aoqi@0 233 * value from System.getProperty() and unconditionally creating a
aoqi@0 234 * PerfStringConstant object initialized to the retreived value. This
aoqi@0 235 * is not an exhustive list of Java properties with corresponding string
aoqi@0 236 * instrumentation as the create_system_property_instrumentation() method
aoqi@0 237 * creates other property based instrumentation conditionally.
aoqi@0 238 */
aoqi@0 239
aoqi@0 240 // stable interface, supported counters
aoqi@0 241 static const char* property_counters_ss[] = {
aoqi@0 242 "java.vm.specification.version",
aoqi@0 243 "java.vm.specification.name",
aoqi@0 244 "java.vm.specification.vendor",
aoqi@0 245 "java.vm.version",
aoqi@0 246 "java.vm.name",
aoqi@0 247 "java.vm.vendor",
aoqi@0 248 "java.vm.info",
aoqi@0 249 "java.library.path",
aoqi@0 250 "java.class.path",
aoqi@0 251 "java.endorsed.dirs",
aoqi@0 252 "java.ext.dirs",
aoqi@0 253 "java.version",
aoqi@0 254 "java.home",
aoqi@0 255 NULL
aoqi@0 256 };
aoqi@0 257
aoqi@0 258 // unstable interface, supported counters
aoqi@0 259 static const char* property_counters_us[] = {
aoqi@0 260 NULL
aoqi@0 261 };
aoqi@0 262
aoqi@0 263 // unstable interface, unsupported counters
aoqi@0 264 static const char* property_counters_uu[] = {
aoqi@0 265 "sun.boot.class.path",
aoqi@0 266 "sun.boot.library.path",
aoqi@0 267 NULL
aoqi@0 268 };
aoqi@0 269
aoqi@0 270 typedef struct {
aoqi@0 271 const char** property_list;
aoqi@0 272 CounterNS name_space;
aoqi@0 273 } PropertyCounters;
aoqi@0 274
aoqi@0 275 static PropertyCounters property_counters[] = {
aoqi@0 276 { property_counters_ss, JAVA_PROPERTY },
aoqi@0 277 { property_counters_us, COM_PROPERTY },
aoqi@0 278 { property_counters_uu, SUN_PROPERTY },
aoqi@0 279 { NULL, SUN_PROPERTY }
aoqi@0 280 };
aoqi@0 281
aoqi@0 282
aoqi@0 283 /*
aoqi@0 284 * Method to create PerfData string instruments that contain the values
aoqi@0 285 * of various system properties. String instruments are created for each
aoqi@0 286 * property specified in the property lists provided in property_counters[].
aoqi@0 287 * Property counters have a counter name space prefix prepended to the
aoqi@0 288 * property name as indicated in property_counters[].
aoqi@0 289 */
aoqi@0 290 void StatSampler::create_system_property_instrumentation(TRAPS) {
aoqi@0 291
aoqi@0 292 ResourceMark rm;
aoqi@0 293
aoqi@0 294 for (int i = 0; property_counters[i].property_list != NULL; i++) {
aoqi@0 295
aoqi@0 296 for (int j = 0; property_counters[i].property_list[j] != NULL; j++) {
aoqi@0 297
aoqi@0 298 const char* property_name = property_counters[i].property_list[j];
aoqi@0 299 assert(property_name != NULL, "property name should not be NULL");
aoqi@0 300
aoqi@0 301 const char* value = get_system_property(property_name, CHECK);
aoqi@0 302
aoqi@0 303 // the property must exist
aoqi@0 304 assert(value != NULL, "property name should be valid");
aoqi@0 305
aoqi@0 306 if (value != NULL) {
aoqi@0 307 // create the property counter
aoqi@0 308 PerfDataManager::create_string_constant(property_counters[i].name_space,
aoqi@0 309 property_name, value, CHECK);
aoqi@0 310 }
aoqi@0 311 }
aoqi@0 312 }
aoqi@0 313 }
aoqi@0 314
aoqi@0 315 /*
aoqi@0 316 * The create_misc_perfdata() method provides a place to create
aoqi@0 317 * PerfData instances that would otherwise have no better place
aoqi@0 318 * to exist.
aoqi@0 319 */
aoqi@0 320 void StatSampler::create_misc_perfdata() {
aoqi@0 321
aoqi@0 322 ResourceMark rm;
aoqi@0 323 EXCEPTION_MARK;
aoqi@0 324
aoqi@0 325 // numeric constants
aoqi@0 326
aoqi@0 327 // frequency of the native high resolution timer
aoqi@0 328 PerfDataManager::create_constant(SUN_OS, "hrt.frequency",
aoqi@0 329 PerfData::U_Hertz, os::elapsed_frequency(),
aoqi@0 330 CHECK);
aoqi@0 331
aoqi@0 332 // string constants
aoqi@0 333
aoqi@0 334 // create string instrumentation for various Java properties.
aoqi@0 335 create_system_property_instrumentation(CHECK);
aoqi@0 336
aoqi@0 337 // hotspot flags (from .hotspotrc) and args (from command line)
aoqi@0 338 //
aoqi@0 339 PerfDataManager::create_string_constant(JAVA_RT, "vmFlags",
aoqi@0 340 Arguments::jvm_flags(), CHECK);
aoqi@0 341 PerfDataManager::create_string_constant(JAVA_RT, "vmArgs",
aoqi@0 342 Arguments::jvm_args(), CHECK);
aoqi@0 343
aoqi@0 344 // java class name/jar file and arguments to main class
aoqi@0 345 // note: name is cooridnated with launcher and Arguments.cpp
aoqi@0 346 PerfDataManager::create_string_constant(SUN_RT, "javaCommand",
aoqi@0 347 Arguments::java_command(), CHECK);
aoqi@0 348
aoqi@0 349 // the Java VM Internal version string
aoqi@0 350 PerfDataManager::create_string_constant(SUN_RT, "internalVersion",
aoqi@0 351 VM_Version::internal_vm_info_string(),
aoqi@0 352 CHECK);
aoqi@0 353
aoqi@0 354 // create sampled instrumentation objects
aoqi@0 355 create_sampled_perfdata();
aoqi@0 356 }
aoqi@0 357
aoqi@0 358 /*
aoqi@0 359 * helper class to provide for sampling of the elapsed_counter value
aoqi@0 360 * maintained in the OS class.
aoqi@0 361 */
aoqi@0 362 class HighResTimeSampler : public PerfSampleHelper {
aoqi@0 363 public:
aoqi@0 364 jlong take_sample() { return os::elapsed_counter(); }
aoqi@0 365 };
aoqi@0 366
aoqi@0 367 /*
aoqi@0 368 * the create_sampled_perdata() method provides a place to instantiate
aoqi@0 369 * sampled PerfData instances that would otherwise have no better place
aoqi@0 370 * to exist.
aoqi@0 371 */
aoqi@0 372 void StatSampler::create_sampled_perfdata() {
aoqi@0 373
aoqi@0 374 EXCEPTION_MARK;
aoqi@0 375
aoqi@0 376 // setup sampling of the elapsed time counter maintained in the
aoqi@0 377 // the os class. This counter can be used as either a time stamp
aoqi@0 378 // for each logged entry or as a liveness indicator for the VM.
aoqi@0 379 PerfSampleHelper* psh = new HighResTimeSampler();
aoqi@0 380 PerfDataManager::create_counter(SUN_OS, "hrt.ticks",
aoqi@0 381 PerfData::U_Ticks, psh, CHECK);
aoqi@0 382 }
aoqi@0 383
aoqi@0 384 /*
aoqi@0 385 * the statSampler_exit() function is called from os_init.cpp on
aoqi@0 386 * exit of the vm.
aoqi@0 387 */
aoqi@0 388 void statSampler_exit() {
aoqi@0 389
aoqi@0 390 if (!UsePerfData) return;
aoqi@0 391
aoqi@0 392 StatSampler::destroy();
aoqi@0 393 }

mercurial