src/share/vm/runtime/statSampler.cpp

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 435
a61af66fc99e
child 714
f3a650d8df24
permissions
-rw-r--r--

Initial load

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

mercurial