src/share/vm/runtime/perfData.cpp

Tue, 23 Nov 2010 13:22:55 -0800

author
stefank
date
Tue, 23 Nov 2010 13:22:55 -0800
changeset 2314
f95d63e2154a
parent 1907
c18cbe5936b8
child 3900
d2a62e0f25eb
permissions
-rw-r--r--

6989984: Use standard include model for Hospot
Summary: Replaced MakeDeps and the includeDB files with more standardized solutions.
Reviewed-by: coleenp, kvn, kamg

     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/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);
    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);
   115   }
   116   if (is_on_c_heap()) {
   117     FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep);
   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);
   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   assert(_sample_helper != NULL || _sampled != NULL, "unexpected state");
   218   if (_sample_helper != NULL) {
   219     *(jlong*)_valuep = _sample_helper->take_sample();
   220   }
   221   else if (_sampled != NULL) {
   222     *(jlong*)_valuep = *_sampled;
   223   }
   224 }
   226 PerfByteArray::PerfByteArray(CounterNS ns, const char* namep, Units u,
   227                              Variability v, jint length)
   228                             : PerfData(ns, namep, u, v), _length(length) {
   230   create_entry(T_BYTE, sizeof(jbyte), (size_t)_length);
   231 }
   233 void PerfString::set_string(const char* s2) {
   235   // copy n bytes of the string, assuring the null string is
   236   // copied if s2 == NULL.
   237   strncpy((char *)_valuep, s2 == NULL ? "" : s2, _length);
   239   // assure the string is null terminated when strlen(s2) >= _length
   240   ((char*)_valuep)[_length-1] = '\0';
   241 }
   243 int PerfString::format(char* buffer, int length) {
   244   return jio_snprintf(buffer, length, "%s", (char*)_valuep);
   245 }
   247 PerfStringConstant::PerfStringConstant(CounterNS ns, const char* namep,
   248                                        const char* initial_value)
   249                      : PerfString(ns, namep, V_Constant,
   250                                   initial_value == NULL ? 1 :
   251                                   MIN2((jint)(strlen((char*)initial_value)+1),
   252                                        (jint)(PerfMaxStringConstLength+1)),
   253                                   initial_value) {
   255   if (PrintMiscellaneous && Verbose) {
   256     if (is_valid() && initial_value != NULL &&
   257         ((jint)strlen(initial_value) > (jint)PerfMaxStringConstLength)) {
   259       warning("Truncating PerfStringConstant: name = %s,"
   260               " length = " INT32_FORMAT ","
   261               " PerfMaxStringConstLength = " INT32_FORMAT "\n",
   262               namep,
   263               (jint)strlen(initial_value),
   264               (jint)PerfMaxStringConstLength);
   265     }
   266   }
   267 }
   274 void PerfDataManager::destroy() {
   276   if (_all == NULL)
   277     // destroy already called, or initialization never happened
   278     return;
   280   for (int index = 0; index < _all->length(); index++) {
   281     PerfData* p = _all->at(index);
   282     delete p;
   283   }
   285   delete(_all);
   286   delete(_sampled);
   287   delete(_constants);
   289   _all = NULL;
   290   _sampled = NULL;
   291   _constants = NULL;
   292 }
   294 void PerfDataManager::add_item(PerfData* p, bool sampled) {
   296   MutexLocker ml(PerfDataManager_lock);
   298   if (_all == NULL) {
   299     _all = new PerfDataList(100);
   300   }
   302   assert(!_all->contains(p->name()), "duplicate name added");
   304   // add to the list of all perf data items
   305   _all->append(p);
   307   if (p->variability() == PerfData::V_Constant) {
   308     if (_constants == NULL) {
   309       _constants = new PerfDataList(25);
   310     }
   311     _constants->append(p);
   312     return;
   313   }
   315   if (sampled) {
   316     if (_sampled == NULL) {
   317       _sampled = new PerfDataList(25);
   318     }
   319     _sampled->append(p);
   320   }
   321 }
   323 PerfDataList* PerfDataManager::all() {
   325   MutexLocker ml(PerfDataManager_lock);
   327   if (_all == NULL)
   328     return NULL;
   330   PerfDataList* clone = _all->clone();
   331   return clone;
   332 }
   334 PerfDataList* PerfDataManager::sampled() {
   336   MutexLocker ml(PerfDataManager_lock);
   338   if (_sampled == NULL)
   339     return NULL;
   341   PerfDataList* clone = _sampled->clone();
   342   return clone;
   343 }
   345 PerfDataList* PerfDataManager::constants() {
   347   MutexLocker ml(PerfDataManager_lock);
   349   if (_constants == NULL)
   350     return NULL;
   352   PerfDataList* clone = _constants->clone();
   353   return clone;
   354 }
   356 char* PerfDataManager::counter_name(const char* ns, const char* name) {
   357    assert(ns != NULL, "ns string required");
   358    assert(name != NULL, "name string required");
   360    size_t len = strlen(ns) + strlen(name) + 2;
   361    char* result = NEW_RESOURCE_ARRAY(char, len);
   362    sprintf(result, "%s.%s", ns, name);
   363    return result;
   364 }
   366 char* PerfDataManager::name_space(const char* ns, const char* sub,
   367                                   int instance) {
   368    char intbuf[40];
   369    jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
   370    return name_space(ns, name_space(sub, intbuf));
   371 }
   373 char *PerfDataManager::name_space(const char* ns, int instance) {
   374    char intbuf[40];
   375    jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
   376    return name_space(ns, intbuf);
   377 }
   379 PerfStringConstant* PerfDataManager::create_string_constant(CounterNS ns,
   380                                                             const char* name,
   381                                                             const char* s,
   382                                                             TRAPS) {
   384   PerfStringConstant* p = new PerfStringConstant(ns, name, s);
   386   if (!p->is_valid()) {
   387     // allocation of native resources failed.
   388     delete p;
   389     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   390   }
   392   add_item(p, false);
   394   return p;
   395 }
   397 PerfLongConstant* PerfDataManager::create_long_constant(CounterNS ns,
   398                                                         const char* name,
   399                                                         PerfData::Units u,
   400                                                         jlong val, TRAPS) {
   402   PerfLongConstant* p = new PerfLongConstant(ns, name, u, val);
   404   if (!p->is_valid()) {
   405     // allocation of native resources failed.
   406     delete p;
   407     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   408   }
   410   add_item(p, false);
   412   return p;
   413 }
   415 PerfStringVariable* PerfDataManager::create_string_variable(CounterNS ns,
   416                                                             const char* name,
   417                                                             jint max_length,
   418                                                             const char* s,
   419                                                             TRAPS) {
   421   if (max_length == 0 && s != NULL) max_length = (jint)strlen(s);
   423   assert(max_length != 0, "PerfStringVariable with length 0");
   425   PerfStringVariable* p = new PerfStringVariable(ns, name, max_length, s);
   427   if (!p->is_valid()) {
   428     // allocation of native resources failed.
   429     delete p;
   430     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   431   }
   433   add_item(p, false);
   435   return p;
   436 }
   438 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   439                                                         const char* name,
   440                                                         PerfData::Units u,
   441                                                         jlong ival, TRAPS) {
   443   PerfLongVariable* p = new PerfLongVariable(ns, name, u, ival);
   445   if (!p->is_valid()) {
   446     // allocation of native resources failed.
   447     delete p;
   448     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   449   }
   451   add_item(p, false);
   453   return p;
   454 }
   456 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   457                                                         const char* name,
   458                                                         PerfData::Units u,
   459                                                         jlong* sp, TRAPS) {
   461   // Sampled counters not supported if UsePerfData is false
   462   if (!UsePerfData) return NULL;
   464   PerfLongVariable* p = new PerfLongVariable(ns, name, u, sp);
   466   if (!p->is_valid()) {
   467     // allocation of native resources failed.
   468     delete p;
   469     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   470   }
   472   add_item(p, true);
   474   return p;
   475 }
   477 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   478                                                         const char* name,
   479                                                         PerfData::Units u,
   480                                                         PerfSampleHelper* sh,
   481                                                         TRAPS) {
   483   // Sampled counters not supported if UsePerfData is false
   484   if (!UsePerfData) return NULL;
   486   PerfLongVariable* p = new PerfLongVariable(ns, name, u, sh);
   488   if (!p->is_valid()) {
   489     // allocation of native resources failed.
   490     delete p;
   491     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   492   }
   494   add_item(p, true);
   496   return p;
   497 }
   499 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   500                                                       const char* name,
   501                                                       PerfData::Units u,
   502                                                       jlong ival, TRAPS) {
   504   PerfLongCounter* p = new PerfLongCounter(ns, name, u, ival);
   506   if (!p->is_valid()) {
   507     // allocation of native resources failed.
   508     delete p;
   509     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   510   }
   512   add_item(p, false);
   514   return p;
   515 }
   517 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   518                                                       const char* name,
   519                                                       PerfData::Units u,
   520                                                       jlong* sp, TRAPS) {
   522   // Sampled counters not supported if UsePerfData is false
   523   if (!UsePerfData) return NULL;
   525   PerfLongCounter* p = new PerfLongCounter(ns, name, u, sp);
   527   if (!p->is_valid()) {
   528     // allocation of native resources failed.
   529     delete p;
   530     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   531   }
   533   add_item(p, true);
   535   return p;
   536 }
   538 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   539                                                       const char* name,
   540                                                       PerfData::Units u,
   541                                                       PerfSampleHelper* sh,
   542                                                       TRAPS) {
   544   // Sampled counters not supported if UsePerfData is false
   545   if (!UsePerfData) return NULL;
   547   PerfLongCounter* p = new PerfLongCounter(ns, name, u, sh);
   549   if (!p->is_valid()) {
   550     // allocation of native resources failed.
   551     delete p;
   552     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   553   }
   555   add_item(p, true);
   557   return p;
   558 }
   560 PerfDataList::PerfDataList(int length) {
   562   _set = new(ResourceObj::C_HEAP) PerfDataArray(length, true);
   563 }
   565 PerfDataList::PerfDataList(PerfDataList* p) {
   567   _set = new(ResourceObj::C_HEAP) PerfDataArray(p->length(), true);
   569   _set->appendAll(p->get_impl());
   570 }
   572 PerfDataList::~PerfDataList() {
   574   delete _set;
   576 }
   578 bool PerfDataList::by_name(void* name, PerfData* pd) {
   580   if (pd == NULL)
   581     return false;
   583   return strcmp((const char*)name, pd->name()) == 0;
   584 }
   586 PerfData* PerfDataList::find_by_name(const char* name) {
   588   int i = _set->find((void*)name, PerfDataList::by_name);
   590   if (i >= 0 && i <= _set->length())
   591     return _set->at(i);
   592   else
   593     return NULL;
   594 }
   596 PerfDataList* PerfDataList::clone() {
   598   PerfDataList* copy = new PerfDataList(this);
   600   assert(copy != NULL, "just checking");
   602   return copy;
   603 }

mercurial