src/share/vm/runtime/statSampler.cpp

Wed, 01 Dec 2010 15:04:06 +0100

author
stefank
date
Wed, 01 Dec 2010 15:04:06 +0100
changeset 2325
c760f78e0a53
parent 2314
f95d63e2154a
child 2497
3582bf76420e
permissions
-rw-r--r--

7003125: precompiled.hpp is included when precompiled headers are not used
Summary: Added an ifndef DONT_USE_PRECOMPILED_HEADER to precompiled.hpp. Set up DONT_USE_PRECOMPILED_HEADER when compiling with Sun Studio or when the user specifies USE_PRECOMPILED_HEADER=0. Fixed broken include dependencies.
Reviewed-by: coleenp, kvn

     1 /*
     2  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "classfile/systemDictionary.hpp"
    27 #include "classfile/vmSymbols.hpp"
    28 #include "memory/allocation.inline.hpp"
    29 #include "memory/resourceArea.hpp"
    30 #include "oops/oop.inline.hpp"
    31 #include "runtime/arguments.hpp"
    32 #include "runtime/java.hpp"
    33 #include "runtime/javaCalls.hpp"
    34 #include "runtime/os.hpp"
    35 #include "runtime/statSampler.hpp"
    36 #ifdef TARGET_ARCH_x86
    37 # include "vm_version_x86.hpp"
    38 #endif
    39 #ifdef TARGET_ARCH_sparc
    40 # include "vm_version_sparc.hpp"
    41 #endif
    42 #ifdef TARGET_ARCH_zero
    43 # include "vm_version_zero.hpp"
    44 #endif
    46 // --------------------------------------------------------
    47 // StatSamplerTask
    49 class StatSamplerTask : public PeriodicTask {
    50   public:
    51     StatSamplerTask(int interval_time) : PeriodicTask(interval_time) {}
    52     void task() { StatSampler::collect_sample(); }
    53 };
    56 //----------------------------------------------------------
    57 // Implementation of StatSampler
    59 StatSamplerTask*              StatSampler::_task   = NULL;
    60 PerfDataList*                 StatSampler::_sampled = NULL;
    62 /*
    63  * the initialize method is called from the engage() method
    64  * and is responsible for initializing various global variables.
    65  */
    66 void StatSampler::initialize() {
    68   if (!UsePerfData) return;
    70   // create performance data that could not be created prior
    71   // to vm_init_globals() or otherwise have no logical home.
    73   create_misc_perfdata();
    75   // get copy of the sampled list
    76   _sampled = PerfDataManager::sampled();
    78 }
    80 /*
    81  * The engage() method is called at initialization time via
    82  * Thread::create_vm() to initialize the StatSampler and
    83  * register it with the WatcherThread as a periodic task.
    84  */
    85 void StatSampler::engage() {
    87   if (!UsePerfData) return;
    89   if (!is_active()) {
    91     initialize();
    93     // start up the periodic task
    94     _task = new StatSamplerTask(PerfDataSamplingInterval);
    95     _task->enroll();
    96   }
    97 }
   100 /*
   101  * the disengage() method is responsible for deactivating the periodic
   102  * task and, if logging was enabled, for logging the final sample. This
   103  * method is called from before_exit() in java.cpp and is only called
   104  * after the WatcherThread has been stopped.
   105  */
   106 void StatSampler::disengage() {
   108   if (!UsePerfData) return;
   110   if (!is_active())
   111     return;
   113   // remove StatSamplerTask
   114   _task->disenroll();
   115   delete _task;
   116   _task = NULL;
   118   // force a final sample
   119   sample_data(_sampled);
   120 }
   122 /*
   123  * the destroy method is responsible for releasing any resources used by
   124  * the StatSampler prior to shutdown of the VM. this method is called from
   125  * before_exit() in java.cpp and is only called after the WatcherThread
   126  * has stopped.
   127  */
   128 void StatSampler::destroy() {
   130   if (!UsePerfData) return;
   132   if (_sampled != NULL) {
   133     delete(_sampled);
   134     _sampled = NULL;
   135   }
   136 }
   138 /*
   139  * The sample_data() method is responsible for sampling the
   140  * the data value for each PerfData instance in the given list.
   141  */
   142 void StatSampler::sample_data(PerfDataList* list) {
   144   assert(list != NULL, "null list unexpected");
   146   for (int index = 0; index < list->length(); index++) {
   147     PerfData* item = list->at(index);
   148     item->sample();
   149   }
   150 }
   152 /*
   153  * the collect_sample() method is the method invoked by the
   154  * WatcherThread via the PeriodicTask::task() method. This method
   155  * is responsible for collecting data samples from sampled
   156  * PerfData instances every PerfDataSamplingInterval milliseconds.
   157  * It is also responsible for logging the requested set of
   158  * PerfData instances every _sample_count milliseconds. While
   159  * logging data, it will output a column header after every _print_header
   160  * rows of data have been logged.
   161  */
   162 void StatSampler::collect_sample() {
   164   // future - check for new PerfData objects. PerfData objects might
   165   // get added to the PerfDataManager lists after we have already
   166   // built our local copies.
   167   //
   168   // if (PerfDataManager::count() > previous) {
   169   //   // get a new copy of the sampled list
   170   //   if (_sampled != NULL) {
   171   //     delete(_sampled);
   172   //     _sampled = NULL;
   173   //   }
   174   //   _sampled = PerfDataManager::sampled();
   175   // }
   177   assert(_sampled != NULL, "list not initialized");
   179   sample_data(_sampled);
   180 }
   182 /*
   183  * method to upcall into Java to return the value of the specified
   184  * property as a utf8 string, or NULL if does not exist. The caller
   185  * is responsible for setting a ResourceMark for proper cleanup of
   186  * the utf8 strings.
   187  */
   188 const char* StatSampler::get_system_property(const char* name, TRAPS) {
   190   // setup the arguments to getProperty
   191   Handle key_str   = java_lang_String::create_from_str(name, CHECK_NULL);
   193   // return value
   194   JavaValue result(T_OBJECT);
   196   // public static String getProperty(String key, String def);
   197   JavaCalls::call_static(&result,
   198                          KlassHandle(THREAD, SystemDictionary::System_klass()),
   199                          vmSymbolHandles::getProperty_name(),
   200                          vmSymbolHandles::string_string_signature(),
   201                          key_str,
   202                          CHECK_NULL);
   204   oop value_oop = (oop)result.get_jobject();
   205   if (value_oop == NULL) {
   206     return NULL;
   207   }
   209   // convert Java String to utf8 string
   210   char* value = java_lang_String::as_utf8_string(value_oop);
   212   return value;
   213 }
   215 /*
   216  * The list of System Properties that have corresponding PerfData
   217  * string instrumentation created by retrieving the named property's
   218  * value from System.getProperty() and unconditionally creating a
   219  * PerfStringConstant object initialized to the retreived value. This
   220  * is not an exhustive list of Java properties with corresponding string
   221  * instrumentation as the create_system_property_instrumentation() method
   222  * creates other property based instrumentation conditionally.
   223  */
   225 // stable interface, supported counters
   226 static const char* property_counters_ss[] = {
   227   "java.vm.specification.version",
   228   "java.vm.specification.name",
   229   "java.vm.specification.vendor",
   230   "java.vm.version",
   231   "java.vm.name",
   232   "java.vm.vendor",
   233   "java.vm.info",
   234   "java.library.path",
   235   "java.class.path",
   236   "java.endorsed.dirs",
   237   "java.ext.dirs",
   238   "java.version",
   239   "java.home",
   240   NULL
   241 };
   243 // unstable interface, supported counters
   244 static const char* property_counters_us[] = {
   245   NULL
   246 };
   248 // unstable interface, unsupported counters
   249 static const char* property_counters_uu[] = {
   250   "sun.boot.class.path",
   251   "sun.boot.library.path",
   252   NULL
   253 };
   255 typedef struct {
   256   const char** property_list;
   257   CounterNS name_space;
   258 } PropertyCounters;
   260 static PropertyCounters property_counters[] = {
   261   { property_counters_ss, JAVA_PROPERTY },
   262   { property_counters_us, COM_PROPERTY },
   263   { property_counters_uu, SUN_PROPERTY },
   264   { NULL, SUN_PROPERTY }
   265 };
   268 /*
   269  * Method to create PerfData string instruments that contain the values
   270  * of various system properties. String instruments are created for each
   271  * property specified in the property lists provided in property_counters[].
   272  * Property counters have a counter name space prefix prepended to the
   273  * property name as indicated in property_counters[].
   274  */
   275 void StatSampler::create_system_property_instrumentation(TRAPS) {
   277   ResourceMark rm;
   279   for (int i = 0; property_counters[i].property_list != NULL; i++) {
   281     for (int j = 0; property_counters[i].property_list[j] != NULL; j++) {
   283       const char* property_name = property_counters[i].property_list[j];
   284       assert(property_name != NULL, "property name should not be NULL");
   286       const char* value = get_system_property(property_name, CHECK);
   288       // the property must exist
   289       assert(value != NULL, "property name should be valid");
   291       if (value != NULL) {
   292         // create the property counter
   293         PerfDataManager::create_string_constant(property_counters[i].name_space,
   294                                                 property_name, value, CHECK);
   295       }
   296     }
   297   }
   298 }
   300 /*
   301  * The create_misc_perfdata() method provides a place to create
   302  * PerfData instances that would otherwise have no better place
   303  * to exist.
   304  */
   305 void StatSampler::create_misc_perfdata() {
   307   ResourceMark rm;
   308   EXCEPTION_MARK;
   310   // numeric constants
   312   // frequency of the native high resolution timer
   313   PerfDataManager::create_constant(SUN_OS, "hrt.frequency",
   314                                    PerfData::U_Hertz, os::elapsed_frequency(),
   315                                    CHECK);
   317   // string constants
   319   // create string instrumentation for various Java properties.
   320   create_system_property_instrumentation(CHECK);
   322   // hotspot flags (from .hotspotrc) and args (from command line)
   323   //
   324   PerfDataManager::create_string_constant(JAVA_RT, "vmFlags",
   325                                           Arguments::jvm_flags(), CHECK);
   326   PerfDataManager::create_string_constant(JAVA_RT, "vmArgs",
   327                                           Arguments::jvm_args(), CHECK);
   329   // java class name/jar file and arguments to main class
   330   // note: name is cooridnated with launcher and Arguments.cpp
   331   PerfDataManager::create_string_constant(SUN_RT, "javaCommand",
   332                                           Arguments::java_command(), CHECK);
   334   // the Java VM Internal version string
   335   PerfDataManager::create_string_constant(SUN_RT, "internalVersion",
   336                                          VM_Version::internal_vm_info_string(),
   337                                          CHECK);
   339   // create sampled instrumentation objects
   340   create_sampled_perfdata();
   341 }
   343 /*
   344  * helper class to provide for sampling of the elapsed_counter value
   345  * maintained in the OS class.
   346  */
   347 class HighResTimeSampler : public PerfSampleHelper {
   348   public:
   349     jlong take_sample() { return os::elapsed_counter(); }
   350 };
   352 /*
   353  * the create_sampled_perdata() method provides a place to instantiate
   354  * sampled PerfData instances that would otherwise have no better place
   355  * to exist.
   356  */
   357 void StatSampler::create_sampled_perfdata() {
   359   EXCEPTION_MARK;
   361   // setup sampling of the elapsed time counter maintained in the
   362   // the os class. This counter can be used as either a time stamp
   363   // for each logged entry or as a liveness indicator for the VM.
   364   PerfSampleHelper* psh = new HighResTimeSampler();
   365   PerfDataManager::create_counter(SUN_OS, "hrt.ticks",
   366                                   PerfData::U_Ticks, psh, CHECK);
   367 }
   369 /*
   370  * the statSampler_exit() function is called from os_init.cpp on
   371  * exit of the vm.
   372  */
   373 void statSampler_exit() {
   375   if (!UsePerfData) return;
   377   StatSampler::destroy();
   378 }

mercurial