src/share/vm/runtime/perfData.cpp

Wed, 10 Oct 2012 14:35:58 -0400

author
jprovino
date
Wed, 10 Oct 2012 14:35:58 -0400
changeset 4165
fb19af007ffc
parent 4037
da91efe96a93
child 4465
203f64878aab
permissions
-rw-r--r--

7189254: Change makefiles for more flexibility to override defaults
Summary: Change makefiles so that targets and parameters can be overridden by alternate makefiles.
Reviewed-by: dholmes, coleenp

     1 /*
     2  * Copyright (c) 2001, 2012, 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/vmSymbols.hpp"
    27 #include "oops/oop.inline.hpp"
    28 #include "runtime/handles.inline.hpp"
    29 #include "runtime/java.hpp"
    30 #include "runtime/mutex.hpp"
    31 #include "runtime/mutexLocker.hpp"
    32 #include "runtime/os.hpp"
    33 #include "runtime/perfData.hpp"
    34 #include "utilities/exceptions.hpp"
    35 #include "utilities/globalDefinitions.hpp"
    37 PerfDataList*   PerfDataManager::_all = NULL;
    38 PerfDataList*   PerfDataManager::_sampled = NULL;
    39 PerfDataList*   PerfDataManager::_constants = NULL;
    41 /*
    42  * The jvmstat global and subsysem jvmstat counter name spaces. The top
    43  * level name spaces imply the interface stability level of the counter,
    44  * which generally follows the Java package, class, and property naming
    45  * conventions. The CounterNS enumeration values should be used to index
    46  * into this array.
    47  */
    48 const char* PerfDataManager::_name_spaces[] = {
    49   // top level name spaces
    50   "java",                   // stable and supported name space
    51   "com.sun",                // unstable but supported name space
    52   "sun",                    // unstable and unsupported name space
    53   // subsystem name spaces
    54   "java.gc",                // Garbage Collection name spaces
    55   "com.sun.gc",
    56   "sun.gc",
    57   "java.ci",                // Compiler name spaces
    58   "com.sun.ci",
    59   "sun.ci",
    60   "java.cls",               // Class Loader name spaces
    61   "com.sun.cls",
    62   "sun.cls",
    63   "java.rt",                // Runtime name spaces
    64   "com.sun.rt",
    65   "sun.rt",
    66   "java.os",                // Operating System name spaces
    67   "com.sun.os",
    68   "sun.os",
    69   "java.threads",           // Threads System name spaces
    70   "com.sun.threads",
    71   "sun.threads",
    72   "java.property",          // Java Property name spaces
    73   "com.sun.property",
    74   "sun.property",
    75   "",
    76 };
    78 PerfData::PerfData(CounterNS ns, const char* name, Units u, Variability v)
    79                   : _name(NULL), _u(u), _v(v), _valuep(NULL),
    80                     _on_c_heap(false) {
    82   const char* prefix = PerfDataManager::ns_to_string(ns);
    84   _name = NEW_C_HEAP_ARRAY(char, strlen(name) + strlen(prefix) + 2, mtInternal);
    85   assert(_name != NULL && strlen(name) != 0, "invalid name");
    87   if (ns == NULL_NS) {
    88      // No prefix is added to counters with the NULL_NS namespace.
    89      strcpy(_name, name);
    90      // set the F_Supported flag based on the counter name prefix.
    91      if (PerfDataManager::is_stable_supported(_name) ||
    92          PerfDataManager::is_unstable_supported(_name)) {
    93        _flags = F_Supported;
    94      }
    95      else {
    96        _flags = F_None;
    97      }
    98   }
    99   else {
   100     sprintf(_name, "%s.%s", prefix, name);
   101     // set the F_Supported flag based on the given namespace.
   102     if (PerfDataManager::is_stable_supported(ns) ||
   103         PerfDataManager::is_unstable_supported(ns)) {
   104       _flags = F_Supported;
   105     }
   106     else {
   107       _flags = F_None;
   108     }
   109   }
   110 }
   112 PerfData::~PerfData() {
   113   if (_name != NULL) {
   114     FREE_C_HEAP_ARRAY(char, _name, mtInternal);
   115   }
   116   if (is_on_c_heap()) {
   117     FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep, mtInternal);
   118   }
   119 }
   121 void PerfData::create_entry(BasicType dtype, size_t dsize, size_t vlen) {
   123   size_t dlen = vlen==0 ? 1 : vlen;
   125   size_t namelen = strlen(name()) + 1;  // include null terminator
   126   size_t size = sizeof(PerfDataEntry) + namelen;
   127   size_t pad_length = ((size % dsize) == 0) ? 0 : dsize - (size % dsize);
   128   size += pad_length;
   129   size_t data_start = size;
   130   size += (dsize * dlen);
   132   // align size to assure allocation in units of 8 bytes
   133   int align = sizeof(jlong) - 1;
   134   size = ((size + align) & ~align);
   135   char* psmp = PerfMemory::alloc(size);
   137   if (psmp == NULL) {
   138     // out of PerfMemory memory resources. allocate on the C heap
   139     // to avoid vm termination.
   140     psmp = NEW_C_HEAP_ARRAY(char, size, mtInternal);
   141     _on_c_heap = true;
   142   }
   144   // compute the addresses for the name and data
   145   char* cname = psmp + sizeof(PerfDataEntry);
   147   // data is in the last dsize*dlen bytes of the entry
   148   void* valuep = (void*) (psmp + data_start);
   150   assert(is_on_c_heap() || PerfMemory::contains(cname), "just checking");
   151   assert(is_on_c_heap() || PerfMemory::contains((char*)valuep), "just checking");
   153   // copy the name, including null terminator, into PerfData memory
   154   strcpy(cname, name());
   157   // set the header values in PerfData memory
   158   PerfDataEntry* pdep = (PerfDataEntry*)psmp;
   159   pdep->entry_length = (jint)size;
   160   pdep->name_offset = (jint) ((uintptr_t) cname - (uintptr_t) psmp);
   161   pdep->vector_length = (jint)vlen;
   162   pdep->data_type = (jbyte) type2char(dtype);
   163   pdep->data_units = units();
   164   pdep->data_variability = variability();
   165   pdep->flags = (jbyte)flags();
   166   pdep->data_offset = (jint) data_start;
   168   if (PerfTraceDataCreation) {
   169     tty->print("name = %s, dtype = %d, variability = %d,"
   170                " units = %d, dsize = %d, vlen = %d,"
   171                " pad_length = %d, size = %d, on_c_heap = %s,"
   172                " address = " INTPTR_FORMAT ","
   173                " data address = " INTPTR_FORMAT "\n",
   174                cname, dtype, variability(),
   175                units(), dsize, vlen,
   176                pad_length, size, is_on_c_heap() ? "TRUE":"FALSE",
   177                psmp, valuep);
   178   }
   180   // record the start of the entry and the location of the data field.
   181   _pdep = pdep;
   182   _valuep = valuep;
   184   // mark the PerfData memory region as having been updated.
   185   PerfMemory::mark_updated();
   186 }
   188 PerfLong::PerfLong(CounterNS ns, const char* namep, Units u, Variability v)
   189                  : PerfData(ns, namep, u, v) {
   191   create_entry(T_LONG, sizeof(jlong));
   192 }
   194 int PerfLong::format(char* buffer, int length) {
   195   return jio_snprintf(buffer, length,"%lld", *(jlong*)_valuep);
   196 }
   198 PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
   199                                  Variability v, jlong* sampled)
   200                                 : PerfLong(ns, namep, u, v),
   201                                   _sampled(sampled), _sample_helper(NULL) {
   203   sample();
   204 }
   206 PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
   207                                  Variability v, PerfLongSampleHelper* helper)
   208                                 : PerfLong(ns, namep, u, v),
   209                                   _sampled(NULL), _sample_helper(helper) {
   211   sample();
   212 }
   214 void PerfLongVariant::sample() {
   216   // JJJ - This should not happen.  Maybe the first sample is taken
   217   // while the _sample_helper is being null'ed out.
   218   // assert(_sample_helper != NULL || _sampled != NULL, "unexpected state");
   219   if (_sample_helper == NULL) return;
   221   if (_sample_helper != NULL) {
   222     *(jlong*)_valuep = _sample_helper->take_sample();
   223   }
   224   else if (_sampled != NULL) {
   225     *(jlong*)_valuep = *_sampled;
   226   }
   227 }
   229 PerfByteArray::PerfByteArray(CounterNS ns, const char* namep, Units u,
   230                              Variability v, jint length)
   231                             : PerfData(ns, namep, u, v), _length(length) {
   233   create_entry(T_BYTE, sizeof(jbyte), (size_t)_length);
   234 }
   236 void PerfString::set_string(const char* s2) {
   238   // copy n bytes of the string, assuring the null string is
   239   // copied if s2 == NULL.
   240   strncpy((char *)_valuep, s2 == NULL ? "" : s2, _length);
   242   // assure the string is null terminated when strlen(s2) >= _length
   243   ((char*)_valuep)[_length-1] = '\0';
   244 }
   246 int PerfString::format(char* buffer, int length) {
   247   return jio_snprintf(buffer, length, "%s", (char*)_valuep);
   248 }
   250 PerfStringConstant::PerfStringConstant(CounterNS ns, const char* namep,
   251                                        const char* initial_value)
   252                      : PerfString(ns, namep, V_Constant,
   253                                   initial_value == NULL ? 1 :
   254                                   MIN2((jint)(strlen((char*)initial_value)+1),
   255                                        (jint)(PerfMaxStringConstLength+1)),
   256                                   initial_value) {
   258   if (PrintMiscellaneous && Verbose) {
   259     if (is_valid() && initial_value != NULL &&
   260         ((jint)strlen(initial_value) > (jint)PerfMaxStringConstLength)) {
   262       warning("Truncating PerfStringConstant: name = %s,"
   263               " length = " INT32_FORMAT ","
   264               " PerfMaxStringConstLength = " INT32_FORMAT "\n",
   265               namep,
   266               (jint)strlen(initial_value),
   267               (jint)PerfMaxStringConstLength);
   268     }
   269   }
   270 }
   277 void PerfDataManager::destroy() {
   279   if (_all == NULL)
   280     // destroy already called, or initialization never happened
   281     return;
   283   for (int index = 0; index < _all->length(); index++) {
   284     PerfData* p = _all->at(index);
   285     delete p;
   286   }
   288   delete(_all);
   289   delete(_sampled);
   290   delete(_constants);
   292   _all = NULL;
   293   _sampled = NULL;
   294   _constants = NULL;
   295 }
   297 void PerfDataManager::add_item(PerfData* p, bool sampled) {
   299   MutexLocker ml(PerfDataManager_lock);
   301   if (_all == NULL) {
   302     _all = new PerfDataList(100);
   303   }
   305   assert(!_all->contains(p->name()), "duplicate name added");
   307   // add to the list of all perf data items
   308   _all->append(p);
   310   if (p->variability() == PerfData::V_Constant) {
   311     if (_constants == NULL) {
   312       _constants = new PerfDataList(25);
   313     }
   314     _constants->append(p);
   315     return;
   316   }
   318   if (sampled) {
   319     if (_sampled == NULL) {
   320       _sampled = new PerfDataList(25);
   321     }
   322     _sampled->append(p);
   323   }
   324 }
   326 PerfDataList* PerfDataManager::all() {
   328   MutexLocker ml(PerfDataManager_lock);
   330   if (_all == NULL)
   331     return NULL;
   333   PerfDataList* clone = _all->clone();
   334   return clone;
   335 }
   337 PerfDataList* PerfDataManager::sampled() {
   339   MutexLocker ml(PerfDataManager_lock);
   341   if (_sampled == NULL)
   342     return NULL;
   344   PerfDataList* clone = _sampled->clone();
   345   return clone;
   346 }
   348 PerfDataList* PerfDataManager::constants() {
   350   MutexLocker ml(PerfDataManager_lock);
   352   if (_constants == NULL)
   353     return NULL;
   355   PerfDataList* clone = _constants->clone();
   356   return clone;
   357 }
   359 char* PerfDataManager::counter_name(const char* ns, const char* name) {
   360    assert(ns != NULL, "ns string required");
   361    assert(name != NULL, "name string required");
   363    size_t len = strlen(ns) + strlen(name) + 2;
   364    char* result = NEW_RESOURCE_ARRAY(char, len);
   365    sprintf(result, "%s.%s", ns, name);
   366    return result;
   367 }
   369 char* PerfDataManager::name_space(const char* ns, const char* sub,
   370                                   int instance) {
   371    char intbuf[40];
   372    jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
   373    return name_space(ns, name_space(sub, intbuf));
   374 }
   376 char *PerfDataManager::name_space(const char* ns, int instance) {
   377    char intbuf[40];
   378    jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
   379    return name_space(ns, intbuf);
   380 }
   382 PerfStringConstant* PerfDataManager::create_string_constant(CounterNS ns,
   383                                                             const char* name,
   384                                                             const char* s,
   385                                                             TRAPS) {
   387   PerfStringConstant* p = new PerfStringConstant(ns, name, s);
   389   if (!p->is_valid()) {
   390     // allocation of native resources failed.
   391     delete p;
   392     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   393   }
   395   add_item(p, false);
   397   return p;
   398 }
   400 PerfLongConstant* PerfDataManager::create_long_constant(CounterNS ns,
   401                                                         const char* name,
   402                                                         PerfData::Units u,
   403                                                         jlong val, TRAPS) {
   405   PerfLongConstant* p = new PerfLongConstant(ns, name, u, val);
   407   if (!p->is_valid()) {
   408     // allocation of native resources failed.
   409     delete p;
   410     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   411   }
   413   add_item(p, false);
   415   return p;
   416 }
   418 PerfStringVariable* PerfDataManager::create_string_variable(CounterNS ns,
   419                                                             const char* name,
   420                                                             jint max_length,
   421                                                             const char* s,
   422                                                             TRAPS) {
   424   if (max_length == 0 && s != NULL) max_length = (jint)strlen(s);
   426   assert(max_length != 0, "PerfStringVariable with length 0");
   428   PerfStringVariable* p = new PerfStringVariable(ns, name, max_length, s);
   430   if (!p->is_valid()) {
   431     // allocation of native resources failed.
   432     delete p;
   433     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   434   }
   436   add_item(p, false);
   438   return p;
   439 }
   441 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   442                                                         const char* name,
   443                                                         PerfData::Units u,
   444                                                         jlong ival, TRAPS) {
   446   PerfLongVariable* p = new PerfLongVariable(ns, name, u, ival);
   448   if (!p->is_valid()) {
   449     // allocation of native resources failed.
   450     delete p;
   451     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   452   }
   454   add_item(p, false);
   456   return p;
   457 }
   459 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   460                                                         const char* name,
   461                                                         PerfData::Units u,
   462                                                         jlong* sp, TRAPS) {
   464   // Sampled counters not supported if UsePerfData is false
   465   if (!UsePerfData) return NULL;
   467   PerfLongVariable* p = new PerfLongVariable(ns, name, u, sp);
   469   if (!p->is_valid()) {
   470     // allocation of native resources failed.
   471     delete p;
   472     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   473   }
   475   add_item(p, true);
   477   return p;
   478 }
   480 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   481                                                         const char* name,
   482                                                         PerfData::Units u,
   483                                                         PerfSampleHelper* sh,
   484                                                         TRAPS) {
   486   // Sampled counters not supported if UsePerfData is false
   487   if (!UsePerfData) return NULL;
   489   PerfLongVariable* p = new PerfLongVariable(ns, name, u, sh);
   491   if (!p->is_valid()) {
   492     // allocation of native resources failed.
   493     delete p;
   494     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   495   }
   497   add_item(p, true);
   499   return p;
   500 }
   502 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   503                                                       const char* name,
   504                                                       PerfData::Units u,
   505                                                       jlong ival, TRAPS) {
   507   PerfLongCounter* p = new PerfLongCounter(ns, name, u, ival);
   509   if (!p->is_valid()) {
   510     // allocation of native resources failed.
   511     delete p;
   512     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   513   }
   515   add_item(p, false);
   517   return p;
   518 }
   520 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   521                                                       const char* name,
   522                                                       PerfData::Units u,
   523                                                       jlong* sp, TRAPS) {
   525   // Sampled counters not supported if UsePerfData is false
   526   if (!UsePerfData) return NULL;
   528   PerfLongCounter* p = new PerfLongCounter(ns, name, u, sp);
   530   if (!p->is_valid()) {
   531     // allocation of native resources failed.
   532     delete p;
   533     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   534   }
   536   add_item(p, true);
   538   return p;
   539 }
   541 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   542                                                       const char* name,
   543                                                       PerfData::Units u,
   544                                                       PerfSampleHelper* sh,
   545                                                       TRAPS) {
   547   // Sampled counters not supported if UsePerfData is false
   548   if (!UsePerfData) return NULL;
   550   PerfLongCounter* p = new PerfLongCounter(ns, name, u, sh);
   552   if (!p->is_valid()) {
   553     // allocation of native resources failed.
   554     delete p;
   555     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   556   }
   558   add_item(p, true);
   560   return p;
   561 }
   563 PerfDataList::PerfDataList(int length) {
   565   _set = new(ResourceObj::C_HEAP, mtInternal) PerfDataArray(length, true);
   566 }
   568 PerfDataList::PerfDataList(PerfDataList* p) {
   570   _set = new(ResourceObj::C_HEAP, mtInternal) PerfDataArray(p->length(), true);
   572   _set->appendAll(p->get_impl());
   573 }
   575 PerfDataList::~PerfDataList() {
   577   delete _set;
   579 }
   581 bool PerfDataList::by_name(void* name, PerfData* pd) {
   583   if (pd == NULL)
   584     return false;
   586   return strcmp((const char*)name, pd->name()) == 0;
   587 }
   589 PerfData* PerfDataList::find_by_name(const char* name) {
   591   // if add_item hasn't been called the list won't be initialized
   592   if (this == NULL)
   593     return NULL;
   595   int i = _set->find((void*)name, PerfDataList::by_name);
   597   if (i >= 0 && i <= _set->length())
   598     return _set->at(i);
   599   else
   600     return NULL;
   601 }
   603 PerfDataList* PerfDataList::clone() {
   605   PerfDataList* copy = new PerfDataList(this);
   607   assert(copy != NULL, "just checking");
   609   return copy;
   610 }

mercurial