src/share/vm/runtime/perfData.cpp

Tue, 04 Mar 2008 09:44:24 -0500

author
sbohne
date
Tue, 04 Mar 2008 09:44:24 -0500
changeset 493
7ee622712fcf
parent 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6666698: EnableBiasedLocking with BiasedLockingStartupDelay can block Watcher thread
Summary: Enqueue VM_EnableBiasedLocking operation asynchronously
Reviewed-by: never, xlu, kbr, acorn

     1 /*
     2  * Copyright 2001-2005 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/_perfData.cpp.incl"
    28 PerfDataList*   PerfDataManager::_all = NULL;
    29 PerfDataList*   PerfDataManager::_sampled = NULL;
    30 PerfDataList*   PerfDataManager::_constants = NULL;
    32 /*
    33  * The jvmstat global and subsysem jvmstat counter name spaces. The top
    34  * level name spaces imply the interface stability level of the counter,
    35  * which generally follows the Java package, class, and property naming
    36  * conventions. The CounterNS enumeration values should be used to index
    37  * into this array.
    38  */
    39 const char* PerfDataManager::_name_spaces[] = {
    40   // top level name spaces
    41   "java",                   // stable and supported name space
    42   "com.sun",                // unstable but supported name space
    43   "sun",                    // unstable and unsupported name space
    44   // subsystem name spaces
    45   "java.gc",                // Garbage Collection name spaces
    46   "com.sun.gc",
    47   "sun.gc",
    48   "java.ci",                // Compiler name spaces
    49   "com.sun.ci",
    50   "sun.ci",
    51   "java.cls",               // Class Loader name spaces
    52   "com.sun.cls",
    53   "sun.cls",
    54   "java.rt",                // Runtime name spaces
    55   "com.sun.rt",
    56   "sun.rt",
    57   "java.os",                // Operating System name spaces
    58   "com.sun.os",
    59   "sun.os",
    60   "java.threads",           // Threads System name spaces
    61   "com.sun.threads",
    62   "sun.threads",
    63   "java.property",          // Java Property name spaces
    64   "com.sun.property",
    65   "sun.property",
    66   "",
    67 };
    69 PerfData::PerfData(CounterNS ns, const char* name, Units u, Variability v)
    70                   : _name(NULL), _u(u), _v(v), _valuep(NULL),
    71                     _on_c_heap(false) {
    73   const char* prefix = PerfDataManager::ns_to_string(ns);
    75   _name = NEW_C_HEAP_ARRAY(char, strlen(name) + strlen(prefix) + 2);
    76   assert(_name != NULL && strlen(name) != 0, "invalid name");
    78   if (ns == NULL_NS) {
    79      // No prefix is added to counters with the NULL_NS namespace.
    80      strcpy(_name, name);
    81      // set the F_Supported flag based on the counter name prefix.
    82      if (PerfDataManager::is_stable_supported(_name) ||
    83          PerfDataManager::is_unstable_supported(_name)) {
    84        _flags = F_Supported;
    85      }
    86      else {
    87        _flags = F_None;
    88      }
    89   }
    90   else {
    91     sprintf(_name, "%s.%s", prefix, name);
    92     // set the F_Supported flag based on the given namespace.
    93     if (PerfDataManager::is_stable_supported(ns) ||
    94         PerfDataManager::is_unstable_supported(ns)) {
    95       _flags = F_Supported;
    96     }
    97     else {
    98       _flags = F_None;
    99     }
   100   }
   101 }
   103 PerfData::~PerfData() {
   104   if (_name != NULL) {
   105     FREE_C_HEAP_ARRAY(char, _name);
   106   }
   107   if (is_on_c_heap()) {
   108     FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep);
   109   }
   110 }
   112 void PerfData::create_entry(BasicType dtype, size_t dsize, size_t vlen) {
   114   size_t dlen = vlen==0 ? 1 : vlen;
   116   size_t namelen = strlen(name()) + 1;  // include null terminator
   117   size_t size = sizeof(PerfDataEntry) + namelen;
   118   size_t pad_length = ((size % dsize) == 0) ? 0 : dsize - (size % dsize);
   119   size += pad_length;
   120   size_t data_start = size;
   121   size += (dsize * dlen);
   123   // align size to assure allocation in units of 8 bytes
   124   int align = sizeof(jlong) - 1;
   125   size = ((size + align) & ~align);
   126   char* psmp = PerfMemory::alloc(size);
   128   if (psmp == NULL) {
   129     // out of PerfMemory memory resources. allocate on the C heap
   130     // to avoid vm termination.
   131     psmp = NEW_C_HEAP_ARRAY(char, size);
   132     _on_c_heap = true;
   133   }
   135   // compute the addresses for the name and data
   136   char* cname = psmp + sizeof(PerfDataEntry);
   138   // data is in the last dsize*dlen bytes of the entry
   139   void* valuep = (void*) (psmp + data_start);
   141   assert(is_on_c_heap() || PerfMemory::contains(cname), "just checking");
   142   assert(is_on_c_heap() || PerfMemory::contains((char*)valuep), "just checking");
   144   // copy the name, including null terminator, into PerfData memory
   145   strcpy(cname, name());
   148   // set the header values in PerfData memory
   149   PerfDataEntry* pdep = (PerfDataEntry*)psmp;
   150   pdep->entry_length = (jint)size;
   151   pdep->name_offset = (jint) ((uintptr_t) cname - (uintptr_t) psmp);
   152   pdep->vector_length = (jint)vlen;
   153   pdep->data_type = (jbyte) type2char(dtype);
   154   pdep->data_units = units();
   155   pdep->data_variability = variability();
   156   pdep->flags = (jbyte)flags();
   157   pdep->data_offset = (jint) data_start;
   159   if (PerfTraceDataCreation) {
   160     tty->print("name = %s, dtype = %d, variability = %d,"
   161                " units = %d, dsize = %d, vlen = %d,"
   162                " pad_length = %d, size = %d, on_c_heap = %s,"
   163                " address = " INTPTR_FORMAT ","
   164                " data address = " INTPTR_FORMAT "\n",
   165                cname, dtype, variability(),
   166                units(), dsize, vlen,
   167                pad_length, size, is_on_c_heap() ? "TRUE":"FALSE",
   168                psmp, valuep);
   169   }
   171   // record the start of the entry and the location of the data field.
   172   _pdep = pdep;
   173   _valuep = valuep;
   175   // mark the PerfData memory region as having been updated.
   176   PerfMemory::mark_updated();
   177 }
   179 PerfLong::PerfLong(CounterNS ns, const char* namep, Units u, Variability v)
   180                  : PerfData(ns, namep, u, v) {
   182   create_entry(T_LONG, sizeof(jlong));
   183 }
   185 int PerfLong::format(char* buffer, int length) {
   186   return jio_snprintf(buffer, length,"%lld", *(jlong*)_valuep);
   187 }
   189 PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
   190                                  Variability v, jlong* sampled)
   191                                 : PerfLong(ns, namep, u, v),
   192                                   _sampled(sampled), _sample_helper(NULL) {
   194   sample();
   195 }
   197 PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
   198                                  Variability v, PerfLongSampleHelper* helper)
   199                                 : PerfLong(ns, namep, u, v),
   200                                   _sampled(NULL), _sample_helper(helper) {
   202   sample();
   203 }
   205 void PerfLongVariant::sample() {
   207   assert(_sample_helper != NULL || _sampled != NULL, "unexpected state");
   209   if (_sample_helper != NULL) {
   210     *(jlong*)_valuep = _sample_helper->take_sample();
   211   }
   212   else if (_sampled != NULL) {
   213     *(jlong*)_valuep = *_sampled;
   214   }
   215 }
   217 PerfByteArray::PerfByteArray(CounterNS ns, const char* namep, Units u,
   218                              Variability v, jint length)
   219                             : PerfData(ns, namep, u, v), _length(length) {
   221   create_entry(T_BYTE, sizeof(jbyte), (size_t)_length);
   222 }
   224 void PerfString::set_string(const char* s2) {
   226   // copy n bytes of the string, assuring the null string is
   227   // copied if s2 == NULL.
   228   strncpy((char *)_valuep, s2 == NULL ? "" : s2, _length);
   230   // assure the string is null terminated when strlen(s2) >= _length
   231   ((char*)_valuep)[_length-1] = '\0';
   232 }
   234 int PerfString::format(char* buffer, int length) {
   235   return jio_snprintf(buffer, length, "%s", (char*)_valuep);
   236 }
   238 PerfStringConstant::PerfStringConstant(CounterNS ns, const char* namep,
   239                                        const char* initial_value)
   240                      : PerfString(ns, namep, V_Constant,
   241                                   initial_value == NULL ? 1 :
   242                                   MIN2((jint)(strlen((char*)initial_value)+1),
   243                                        (jint)(PerfMaxStringConstLength+1)),
   244                                   initial_value) {
   246   if (PrintMiscellaneous && Verbose) {
   247     if (is_valid() && initial_value != NULL &&
   248         ((jint)strlen(initial_value) > (jint)PerfMaxStringConstLength)) {
   250       warning("Truncating PerfStringConstant: name = %s,"
   251               " length = " INT32_FORMAT ","
   252               " PerfMaxStringConstLength = " INT32_FORMAT "\n",
   253               namep,
   254               (jint)strlen(initial_value),
   255               (jint)PerfMaxStringConstLength);
   256     }
   257   }
   258 }
   265 void PerfDataManager::destroy() {
   267   if (_all == NULL)
   268     // destroy already called, or initialization never happened
   269     return;
   271   for (int index = 0; index < _all->length(); index++) {
   272     PerfData* p = _all->at(index);
   273     delete p;
   274   }
   276   delete(_all);
   277   delete(_sampled);
   278   delete(_constants);
   280   _all = NULL;
   281   _sampled = NULL;
   282   _constants = NULL;
   283 }
   285 void PerfDataManager::add_item(PerfData* p, bool sampled) {
   287   MutexLocker ml(PerfDataManager_lock);
   289   if (_all == NULL) {
   290     _all = new PerfDataList(100);
   291   }
   293   assert(!_all->contains(p->name()), "duplicate name added");
   295   // add to the list of all perf data items
   296   _all->append(p);
   298   if (p->variability() == PerfData::V_Constant) {
   299     if (_constants == NULL) {
   300       _constants = new PerfDataList(25);
   301     }
   302     _constants->append(p);
   303     return;
   304   }
   306   if (sampled) {
   307     if (_sampled == NULL) {
   308       _sampled = new PerfDataList(25);
   309     }
   310     _sampled->append(p);
   311   }
   312 }
   314 PerfDataList* PerfDataManager::all() {
   316   MutexLocker ml(PerfDataManager_lock);
   318   if (_all == NULL)
   319     return NULL;
   321   PerfDataList* clone = _all->clone();
   322   return clone;
   323 }
   325 PerfDataList* PerfDataManager::sampled() {
   327   MutexLocker ml(PerfDataManager_lock);
   329   if (_sampled == NULL)
   330     return NULL;
   332   PerfDataList* clone = _sampled->clone();
   333   return clone;
   334 }
   336 PerfDataList* PerfDataManager::constants() {
   338   MutexLocker ml(PerfDataManager_lock);
   340   if (_constants == NULL)
   341     return NULL;
   343   PerfDataList* clone = _constants->clone();
   344   return clone;
   345 }
   347 char* PerfDataManager::counter_name(const char* ns, const char* name) {
   348    assert(ns != NULL, "ns string required");
   349    assert(name != NULL, "name string required");
   351    size_t len = strlen(ns) + strlen(name) + 2;
   352    char* result = NEW_RESOURCE_ARRAY(char, len);
   353    sprintf(result, "%s.%s", ns, name);
   354    return result;
   355 }
   357 char* PerfDataManager::name_space(const char* ns, const char* sub,
   358                                   int instance) {
   359    char intbuf[40];
   360    jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
   361    return name_space(ns, name_space(sub, intbuf));
   362 }
   364 char *PerfDataManager::name_space(const char* ns, int instance) {
   365    char intbuf[40];
   366    jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
   367    return name_space(ns, intbuf);
   368 }
   370 PerfStringConstant* PerfDataManager::create_string_constant(CounterNS ns,
   371                                                             const char* name,
   372                                                             const char* s,
   373                                                             TRAPS) {
   375   PerfStringConstant* p = new PerfStringConstant(ns, name, s);
   377   if (!p->is_valid()) {
   378     // allocation of native resources failed.
   379     delete p;
   380     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   381   }
   383   add_item(p, false);
   385   return p;
   386 }
   388 PerfLongConstant* PerfDataManager::create_long_constant(CounterNS ns,
   389                                                         const char* name,
   390                                                         PerfData::Units u,
   391                                                         jlong val, TRAPS) {
   393   PerfLongConstant* p = new PerfLongConstant(ns, name, u, val);
   395   if (!p->is_valid()) {
   396     // allocation of native resources failed.
   397     delete p;
   398     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   399   }
   401   add_item(p, false);
   403   return p;
   404 }
   406 PerfStringVariable* PerfDataManager::create_string_variable(CounterNS ns,
   407                                                             const char* name,
   408                                                             jint max_length,
   409                                                             const char* s,
   410                                                             TRAPS) {
   412   if (max_length == 0 && s != NULL) max_length = (jint)strlen(s);
   414   assert(max_length != 0, "PerfStringVariable with length 0");
   416   PerfStringVariable* p = new PerfStringVariable(ns, name, max_length, s);
   418   if (!p->is_valid()) {
   419     // allocation of native resources failed.
   420     delete p;
   421     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   422   }
   424   add_item(p, false);
   426   return p;
   427 }
   429 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   430                                                         const char* name,
   431                                                         PerfData::Units u,
   432                                                         jlong ival, TRAPS) {
   434   PerfLongVariable* p = new PerfLongVariable(ns, name, u, ival);
   436   if (!p->is_valid()) {
   437     // allocation of native resources failed.
   438     delete p;
   439     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   440   }
   442   add_item(p, false);
   444   return p;
   445 }
   447 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   448                                                         const char* name,
   449                                                         PerfData::Units u,
   450                                                         jlong* sp, TRAPS) {
   452   // Sampled counters not supported if UsePerfData is false
   453   if (!UsePerfData) return NULL;
   455   PerfLongVariable* p = new PerfLongVariable(ns, name, u, sp);
   457   if (!p->is_valid()) {
   458     // allocation of native resources failed.
   459     delete p;
   460     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   461   }
   463   add_item(p, true);
   465   return p;
   466 }
   468 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
   469                                                         const char* name,
   470                                                         PerfData::Units u,
   471                                                         PerfSampleHelper* sh,
   472                                                         TRAPS) {
   474   // Sampled counters not supported if UsePerfData is false
   475   if (!UsePerfData) return NULL;
   477   PerfLongVariable* p = new PerfLongVariable(ns, name, u, sh);
   479   if (!p->is_valid()) {
   480     // allocation of native resources failed.
   481     delete p;
   482     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   483   }
   485   add_item(p, true);
   487   return p;
   488 }
   490 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   491                                                       const char* name,
   492                                                       PerfData::Units u,
   493                                                       jlong ival, TRAPS) {
   495   PerfLongCounter* p = new PerfLongCounter(ns, name, u, ival);
   497   if (!p->is_valid()) {
   498     // allocation of native resources failed.
   499     delete p;
   500     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   501   }
   503   add_item(p, false);
   505   return p;
   506 }
   508 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   509                                                       const char* name,
   510                                                       PerfData::Units u,
   511                                                       jlong* sp, TRAPS) {
   513   // Sampled counters not supported if UsePerfData is false
   514   if (!UsePerfData) return NULL;
   516   PerfLongCounter* p = new PerfLongCounter(ns, name, u, sp);
   518   if (!p->is_valid()) {
   519     // allocation of native resources failed.
   520     delete p;
   521     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   522   }
   524   add_item(p, true);
   526   return p;
   527 }
   529 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
   530                                                       const char* name,
   531                                                       PerfData::Units u,
   532                                                       PerfSampleHelper* sh,
   533                                                       TRAPS) {
   535   // Sampled counters not supported if UsePerfData is false
   536   if (!UsePerfData) return NULL;
   538   PerfLongCounter* p = new PerfLongCounter(ns, name, u, sh);
   540   if (!p->is_valid()) {
   541     // allocation of native resources failed.
   542     delete p;
   543     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   544   }
   546   add_item(p, true);
   548   return p;
   549 }
   551 PerfDataList::PerfDataList(int length) {
   553   _set = new(ResourceObj::C_HEAP) PerfDataArray(length, true);
   554 }
   556 PerfDataList::PerfDataList(PerfDataList* p) {
   558   _set = new(ResourceObj::C_HEAP) PerfDataArray(p->length(), true);
   560   _set->appendAll(p->get_impl());
   561 }
   563 PerfDataList::~PerfDataList() {
   565   delete _set;
   567 }
   569 bool PerfDataList::by_name(void* name, PerfData* pd) {
   571   if (pd == NULL)
   572     return false;
   574   return strcmp((const char*)name, pd->name()) == 0;
   575 }
   577 PerfData* PerfDataList::find_by_name(const char* name) {
   579   int i = _set->find((void*)name, PerfDataList::by_name);
   581   if (i >= 0 && i <= _set->length())
   582     return _set->at(i);
   583   else
   584     return NULL;
   585 }
   587 PerfDataList* PerfDataList::clone() {
   589   PerfDataList* copy = new PerfDataList(this);
   591   assert(copy != NULL, "just checking");
   593   return copy;
   594 }

mercurial