src/share/vm/runtime/statSampler.cpp

Wed, 06 Jan 2010 14:22:39 -0800

author
never
date
Wed, 06 Jan 2010 14:22:39 -0800
changeset 1577
4ce7240d622c
parent 772
9ee9cf798b59
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6914300: ciEnv should export all well known classes
Reviewed-by: kvn, twisti

     1 /*
     2  * Copyright 2001-2008 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.version",
   221   "java.home",
   222   NULL
   223 };
   225 // unstable interface, supported counters
   226 static const char* property_counters_us[] = {
   227   NULL
   228 };
   230 // unstable interface, unsupported counters
   231 static const char* property_counters_uu[] = {
   232   "sun.boot.class.path",
   233   "sun.boot.library.path",
   234   NULL
   235 };
   237 typedef struct {
   238   const char** property_list;
   239   CounterNS name_space;
   240 } PropertyCounters;
   242 static PropertyCounters property_counters[] = {
   243   { property_counters_ss, JAVA_PROPERTY },
   244   { property_counters_us, COM_PROPERTY },
   245   { property_counters_uu, SUN_PROPERTY },
   246   { NULL, SUN_PROPERTY }
   247 };
   250 /*
   251  * Method to create PerfData string instruments that contain the values
   252  * of various system properties. String instruments are created for each
   253  * property specified in the property lists provided in property_counters[].
   254  * Property counters have a counter name space prefix prepended to the
   255  * property name as indicated in property_counters[].
   256  */
   257 void StatSampler::create_system_property_instrumentation(TRAPS) {
   259   ResourceMark rm;
   261   for (int i = 0; property_counters[i].property_list != NULL; i++) {
   263     for (int j = 0; property_counters[i].property_list[j] != NULL; j++) {
   265       const char* property_name = property_counters[i].property_list[j];
   266       assert(property_name != NULL, "property name should not be NULL");
   268       const char* value = get_system_property(property_name, CHECK);
   270       // the property must exist
   271       assert(value != NULL, "property name should be valid");
   273       if (value != NULL) {
   274         // create the property counter
   275         PerfDataManager::create_string_constant(property_counters[i].name_space,
   276                                                 property_name, value, CHECK);
   277       }
   278     }
   279   }
   280 }
   282 /*
   283  * The create_misc_perfdata() method provides a place to create
   284  * PerfData instances that would otherwise have no better place
   285  * to exist.
   286  */
   287 void StatSampler::create_misc_perfdata() {
   289   ResourceMark rm;
   290   EXCEPTION_MARK;
   292   // numeric constants
   294   // frequency of the native high resolution timer
   295   PerfDataManager::create_constant(SUN_OS, "hrt.frequency",
   296                                    PerfData::U_Hertz, os::elapsed_frequency(),
   297                                    CHECK);
   299   // string constants
   301   // create string instrumentation for various Java properties.
   302   create_system_property_instrumentation(CHECK);
   304   // hotspot flags (from .hotspotrc) and args (from command line)
   305   //
   306   PerfDataManager::create_string_constant(JAVA_RT, "vmFlags",
   307                                           Arguments::jvm_flags(), CHECK);
   308   PerfDataManager::create_string_constant(JAVA_RT, "vmArgs",
   309                                           Arguments::jvm_args(), CHECK);
   311   // java class name/jar file and arguments to main class
   312   // note: name is cooridnated with launcher and Arguments.cpp
   313   PerfDataManager::create_string_constant(SUN_RT, "javaCommand",
   314                                           Arguments::java_command(), CHECK);
   316   // the Java VM Internal version string
   317   PerfDataManager::create_string_constant(SUN_RT, "internalVersion",
   318                                          VM_Version::internal_vm_info_string(),
   319                                          CHECK);
   321   // create sampled instrumentation objects
   322   create_sampled_perfdata();
   323 }
   325 /*
   326  * helper class to provide for sampling of the elapsed_counter value
   327  * maintained in the OS class.
   328  */
   329 class HighResTimeSampler : public PerfSampleHelper {
   330   public:
   331     jlong take_sample() { return os::elapsed_counter(); }
   332 };
   334 /*
   335  * the create_sampled_perdata() method provides a place to instantiate
   336  * sampled PerfData instances that would otherwise have no better place
   337  * to exist.
   338  */
   339 void StatSampler::create_sampled_perfdata() {
   341   EXCEPTION_MARK;
   343   // setup sampling of the elapsed time counter maintained in the
   344   // the os class. This counter can be used as either a time stamp
   345   // for each logged entry or as a liveness indicator for the VM.
   346   PerfSampleHelper* psh = new HighResTimeSampler();
   347   PerfDataManager::create_counter(SUN_OS, "hrt.ticks",
   348                                   PerfData::U_Ticks, psh, CHECK);
   349 }
   351 /*
   352  * the statSampler_exit() function is called from os_init.cpp on
   353  * exit of the vm.
   354  */
   355 void statSampler_exit() {
   357   if (!UsePerfData) return;
   359   StatSampler::destroy();
   360 }

mercurial