src/share/vm/runtime/perfData.cpp

Thu, 24 Nov 2016 11:27:57 +0100

author
tschatzl
date
Thu, 24 Nov 2016 11:27:57 +0100
changeset 9982
72053ed6f8d4
parent 6680
78bbf4d43a14
child 6876
710a3c8b516e
permissions
-rw-r--r--

8057003: Large reference arrays cause extremely long synchronization times
Summary: Slice large object arrays into parts so that the synchronization of marking threads with an STW pause request does not take long.
Reviewed-by: ehelin, pliden
Contributed-by: maoliang.ml@alibaba-inc.com

duke@435 1 /*
drchase@6680 2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "classfile/vmSymbols.hpp"
stefank@2314 27 #include "oops/oop.inline.hpp"
stefank@2314 28 #include "runtime/handles.inline.hpp"
stefank@2314 29 #include "runtime/java.hpp"
stefank@2314 30 #include "runtime/mutex.hpp"
stefank@2314 31 #include "runtime/mutexLocker.hpp"
stefank@2314 32 #include "runtime/os.hpp"
stefank@2314 33 #include "runtime/perfData.hpp"
stefank@2314 34 #include "utilities/exceptions.hpp"
stefank@2314 35 #include "utilities/globalDefinitions.hpp"
duke@435 36
drchase@6680 37 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
drchase@6680 38
duke@435 39 PerfDataList* PerfDataManager::_all = NULL;
duke@435 40 PerfDataList* PerfDataManager::_sampled = NULL;
duke@435 41 PerfDataList* PerfDataManager::_constants = NULL;
duke@435 42
duke@435 43 /*
duke@435 44 * The jvmstat global and subsysem jvmstat counter name spaces. The top
duke@435 45 * level name spaces imply the interface stability level of the counter,
duke@435 46 * which generally follows the Java package, class, and property naming
duke@435 47 * conventions. The CounterNS enumeration values should be used to index
duke@435 48 * into this array.
duke@435 49 */
duke@435 50 const char* PerfDataManager::_name_spaces[] = {
duke@435 51 // top level name spaces
duke@435 52 "java", // stable and supported name space
duke@435 53 "com.sun", // unstable but supported name space
duke@435 54 "sun", // unstable and unsupported name space
duke@435 55 // subsystem name spaces
duke@435 56 "java.gc", // Garbage Collection name spaces
duke@435 57 "com.sun.gc",
duke@435 58 "sun.gc",
duke@435 59 "java.ci", // Compiler name spaces
duke@435 60 "com.sun.ci",
duke@435 61 "sun.ci",
duke@435 62 "java.cls", // Class Loader name spaces
duke@435 63 "com.sun.cls",
duke@435 64 "sun.cls",
duke@435 65 "java.rt", // Runtime name spaces
duke@435 66 "com.sun.rt",
duke@435 67 "sun.rt",
duke@435 68 "java.os", // Operating System name spaces
duke@435 69 "com.sun.os",
duke@435 70 "sun.os",
duke@435 71 "java.threads", // Threads System name spaces
duke@435 72 "com.sun.threads",
duke@435 73 "sun.threads",
duke@435 74 "java.property", // Java Property name spaces
duke@435 75 "com.sun.property",
duke@435 76 "sun.property",
duke@435 77 "",
duke@435 78 };
duke@435 79
duke@435 80 PerfData::PerfData(CounterNS ns, const char* name, Units u, Variability v)
duke@435 81 : _name(NULL), _u(u), _v(v), _valuep(NULL),
duke@435 82 _on_c_heap(false) {
duke@435 83
duke@435 84 const char* prefix = PerfDataManager::ns_to_string(ns);
duke@435 85
zgu@3900 86 _name = NEW_C_HEAP_ARRAY(char, strlen(name) + strlen(prefix) + 2, mtInternal);
duke@435 87 assert(_name != NULL && strlen(name) != 0, "invalid name");
duke@435 88
duke@435 89 if (ns == NULL_NS) {
duke@435 90 // No prefix is added to counters with the NULL_NS namespace.
duke@435 91 strcpy(_name, name);
duke@435 92 // set the F_Supported flag based on the counter name prefix.
duke@435 93 if (PerfDataManager::is_stable_supported(_name) ||
duke@435 94 PerfDataManager::is_unstable_supported(_name)) {
duke@435 95 _flags = F_Supported;
duke@435 96 }
duke@435 97 else {
duke@435 98 _flags = F_None;
duke@435 99 }
duke@435 100 }
duke@435 101 else {
duke@435 102 sprintf(_name, "%s.%s", prefix, name);
duke@435 103 // set the F_Supported flag based on the given namespace.
duke@435 104 if (PerfDataManager::is_stable_supported(ns) ||
duke@435 105 PerfDataManager::is_unstable_supported(ns)) {
duke@435 106 _flags = F_Supported;
duke@435 107 }
duke@435 108 else {
duke@435 109 _flags = F_None;
duke@435 110 }
duke@435 111 }
duke@435 112 }
duke@435 113
duke@435 114 PerfData::~PerfData() {
duke@435 115 if (_name != NULL) {
zgu@3900 116 FREE_C_HEAP_ARRAY(char, _name, mtInternal);
duke@435 117 }
duke@435 118 if (is_on_c_heap()) {
zgu@3900 119 FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep, mtInternal);
duke@435 120 }
duke@435 121 }
duke@435 122
duke@435 123 void PerfData::create_entry(BasicType dtype, size_t dsize, size_t vlen) {
duke@435 124
duke@435 125 size_t dlen = vlen==0 ? 1 : vlen;
duke@435 126
duke@435 127 size_t namelen = strlen(name()) + 1; // include null terminator
duke@435 128 size_t size = sizeof(PerfDataEntry) + namelen;
duke@435 129 size_t pad_length = ((size % dsize) == 0) ? 0 : dsize - (size % dsize);
duke@435 130 size += pad_length;
duke@435 131 size_t data_start = size;
duke@435 132 size += (dsize * dlen);
duke@435 133
duke@435 134 // align size to assure allocation in units of 8 bytes
duke@435 135 int align = sizeof(jlong) - 1;
duke@435 136 size = ((size + align) & ~align);
duke@435 137 char* psmp = PerfMemory::alloc(size);
duke@435 138
duke@435 139 if (psmp == NULL) {
duke@435 140 // out of PerfMemory memory resources. allocate on the C heap
duke@435 141 // to avoid vm termination.
zgu@3900 142 psmp = NEW_C_HEAP_ARRAY(char, size, mtInternal);
duke@435 143 _on_c_heap = true;
duke@435 144 }
duke@435 145
duke@435 146 // compute the addresses for the name and data
duke@435 147 char* cname = psmp + sizeof(PerfDataEntry);
duke@435 148
duke@435 149 // data is in the last dsize*dlen bytes of the entry
duke@435 150 void* valuep = (void*) (psmp + data_start);
duke@435 151
duke@435 152 assert(is_on_c_heap() || PerfMemory::contains(cname), "just checking");
duke@435 153 assert(is_on_c_heap() || PerfMemory::contains((char*)valuep), "just checking");
duke@435 154
duke@435 155 // copy the name, including null terminator, into PerfData memory
duke@435 156 strcpy(cname, name());
duke@435 157
duke@435 158
duke@435 159 // set the header values in PerfData memory
duke@435 160 PerfDataEntry* pdep = (PerfDataEntry*)psmp;
duke@435 161 pdep->entry_length = (jint)size;
duke@435 162 pdep->name_offset = (jint) ((uintptr_t) cname - (uintptr_t) psmp);
duke@435 163 pdep->vector_length = (jint)vlen;
duke@435 164 pdep->data_type = (jbyte) type2char(dtype);
duke@435 165 pdep->data_units = units();
duke@435 166 pdep->data_variability = variability();
duke@435 167 pdep->flags = (jbyte)flags();
duke@435 168 pdep->data_offset = (jint) data_start;
duke@435 169
duke@435 170 if (PerfTraceDataCreation) {
duke@435 171 tty->print("name = %s, dtype = %d, variability = %d,"
duke@435 172 " units = %d, dsize = %d, vlen = %d,"
duke@435 173 " pad_length = %d, size = %d, on_c_heap = %s,"
duke@435 174 " address = " INTPTR_FORMAT ","
duke@435 175 " data address = " INTPTR_FORMAT "\n",
duke@435 176 cname, dtype, variability(),
duke@435 177 units(), dsize, vlen,
duke@435 178 pad_length, size, is_on_c_heap() ? "TRUE":"FALSE",
duke@435 179 psmp, valuep);
duke@435 180 }
duke@435 181
duke@435 182 // record the start of the entry and the location of the data field.
duke@435 183 _pdep = pdep;
duke@435 184 _valuep = valuep;
duke@435 185
duke@435 186 // mark the PerfData memory region as having been updated.
duke@435 187 PerfMemory::mark_updated();
duke@435 188 }
duke@435 189
duke@435 190 PerfLong::PerfLong(CounterNS ns, const char* namep, Units u, Variability v)
duke@435 191 : PerfData(ns, namep, u, v) {
duke@435 192
duke@435 193 create_entry(T_LONG, sizeof(jlong));
duke@435 194 }
duke@435 195
duke@435 196 int PerfLong::format(char* buffer, int length) {
hseigel@4465 197 return jio_snprintf(buffer, length, JLONG_FORMAT, *(jlong*)_valuep);
duke@435 198 }
duke@435 199
duke@435 200 PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
duke@435 201 Variability v, jlong* sampled)
duke@435 202 : PerfLong(ns, namep, u, v),
duke@435 203 _sampled(sampled), _sample_helper(NULL) {
duke@435 204
duke@435 205 sample();
duke@435 206 }
duke@435 207
duke@435 208 PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
duke@435 209 Variability v, PerfLongSampleHelper* helper)
duke@435 210 : PerfLong(ns, namep, u, v),
duke@435 211 _sampled(NULL), _sample_helper(helper) {
duke@435 212
duke@435 213 sample();
duke@435 214 }
duke@435 215
duke@435 216 void PerfLongVariant::sample() {
duke@435 217
coleenp@4037 218 // JJJ - This should not happen. Maybe the first sample is taken
coleenp@4037 219 // while the _sample_helper is being null'ed out.
coleenp@4037 220 // assert(_sample_helper != NULL || _sampled != NULL, "unexpected state");
coleenp@4037 221 if (_sample_helper == NULL) return;
duke@435 222
duke@435 223 if (_sample_helper != NULL) {
duke@435 224 *(jlong*)_valuep = _sample_helper->take_sample();
duke@435 225 }
duke@435 226 else if (_sampled != NULL) {
duke@435 227 *(jlong*)_valuep = *_sampled;
duke@435 228 }
duke@435 229 }
duke@435 230
duke@435 231 PerfByteArray::PerfByteArray(CounterNS ns, const char* namep, Units u,
duke@435 232 Variability v, jint length)
duke@435 233 : PerfData(ns, namep, u, v), _length(length) {
duke@435 234
duke@435 235 create_entry(T_BYTE, sizeof(jbyte), (size_t)_length);
duke@435 236 }
duke@435 237
duke@435 238 void PerfString::set_string(const char* s2) {
duke@435 239
duke@435 240 // copy n bytes of the string, assuring the null string is
duke@435 241 // copied if s2 == NULL.
duke@435 242 strncpy((char *)_valuep, s2 == NULL ? "" : s2, _length);
duke@435 243
duke@435 244 // assure the string is null terminated when strlen(s2) >= _length
duke@435 245 ((char*)_valuep)[_length-1] = '\0';
duke@435 246 }
duke@435 247
duke@435 248 int PerfString::format(char* buffer, int length) {
duke@435 249 return jio_snprintf(buffer, length, "%s", (char*)_valuep);
duke@435 250 }
duke@435 251
duke@435 252 PerfStringConstant::PerfStringConstant(CounterNS ns, const char* namep,
duke@435 253 const char* initial_value)
duke@435 254 : PerfString(ns, namep, V_Constant,
duke@435 255 initial_value == NULL ? 1 :
duke@435 256 MIN2((jint)(strlen((char*)initial_value)+1),
duke@435 257 (jint)(PerfMaxStringConstLength+1)),
duke@435 258 initial_value) {
duke@435 259
duke@435 260 if (PrintMiscellaneous && Verbose) {
duke@435 261 if (is_valid() && initial_value != NULL &&
duke@435 262 ((jint)strlen(initial_value) > (jint)PerfMaxStringConstLength)) {
duke@435 263
duke@435 264 warning("Truncating PerfStringConstant: name = %s,"
duke@435 265 " length = " INT32_FORMAT ","
duke@435 266 " PerfMaxStringConstLength = " INT32_FORMAT "\n",
duke@435 267 namep,
duke@435 268 (jint)strlen(initial_value),
duke@435 269 (jint)PerfMaxStringConstLength);
duke@435 270 }
duke@435 271 }
duke@435 272 }
duke@435 273
duke@435 274
duke@435 275
duke@435 276
duke@435 277
duke@435 278
duke@435 279 void PerfDataManager::destroy() {
duke@435 280
duke@435 281 if (_all == NULL)
duke@435 282 // destroy already called, or initialization never happened
duke@435 283 return;
duke@435 284
duke@435 285 for (int index = 0; index < _all->length(); index++) {
duke@435 286 PerfData* p = _all->at(index);
duke@435 287 delete p;
duke@435 288 }
duke@435 289
duke@435 290 delete(_all);
duke@435 291 delete(_sampled);
duke@435 292 delete(_constants);
duke@435 293
duke@435 294 _all = NULL;
duke@435 295 _sampled = NULL;
duke@435 296 _constants = NULL;
duke@435 297 }
duke@435 298
duke@435 299 void PerfDataManager::add_item(PerfData* p, bool sampled) {
duke@435 300
duke@435 301 MutexLocker ml(PerfDataManager_lock);
duke@435 302
duke@435 303 if (_all == NULL) {
duke@435 304 _all = new PerfDataList(100);
duke@435 305 }
duke@435 306
duke@435 307 assert(!_all->contains(p->name()), "duplicate name added");
duke@435 308
duke@435 309 // add to the list of all perf data items
duke@435 310 _all->append(p);
duke@435 311
duke@435 312 if (p->variability() == PerfData::V_Constant) {
duke@435 313 if (_constants == NULL) {
duke@435 314 _constants = new PerfDataList(25);
duke@435 315 }
duke@435 316 _constants->append(p);
duke@435 317 return;
duke@435 318 }
duke@435 319
duke@435 320 if (sampled) {
duke@435 321 if (_sampled == NULL) {
duke@435 322 _sampled = new PerfDataList(25);
duke@435 323 }
duke@435 324 _sampled->append(p);
duke@435 325 }
duke@435 326 }
duke@435 327
sla@5237 328 PerfData* PerfDataManager::find_by_name(const char* name) {
sla@5237 329 return _all->find_by_name(name);
sla@5237 330 }
sla@5237 331
duke@435 332 PerfDataList* PerfDataManager::all() {
duke@435 333
duke@435 334 MutexLocker ml(PerfDataManager_lock);
duke@435 335
duke@435 336 if (_all == NULL)
duke@435 337 return NULL;
duke@435 338
duke@435 339 PerfDataList* clone = _all->clone();
duke@435 340 return clone;
duke@435 341 }
duke@435 342
duke@435 343 PerfDataList* PerfDataManager::sampled() {
duke@435 344
duke@435 345 MutexLocker ml(PerfDataManager_lock);
duke@435 346
duke@435 347 if (_sampled == NULL)
duke@435 348 return NULL;
duke@435 349
duke@435 350 PerfDataList* clone = _sampled->clone();
duke@435 351 return clone;
duke@435 352 }
duke@435 353
duke@435 354 PerfDataList* PerfDataManager::constants() {
duke@435 355
duke@435 356 MutexLocker ml(PerfDataManager_lock);
duke@435 357
duke@435 358 if (_constants == NULL)
duke@435 359 return NULL;
duke@435 360
duke@435 361 PerfDataList* clone = _constants->clone();
duke@435 362 return clone;
duke@435 363 }
duke@435 364
duke@435 365 char* PerfDataManager::counter_name(const char* ns, const char* name) {
duke@435 366 assert(ns != NULL, "ns string required");
duke@435 367 assert(name != NULL, "name string required");
duke@435 368
duke@435 369 size_t len = strlen(ns) + strlen(name) + 2;
duke@435 370 char* result = NEW_RESOURCE_ARRAY(char, len);
duke@435 371 sprintf(result, "%s.%s", ns, name);
duke@435 372 return result;
duke@435 373 }
duke@435 374
duke@435 375 char* PerfDataManager::name_space(const char* ns, const char* sub,
duke@435 376 int instance) {
duke@435 377 char intbuf[40];
duke@435 378 jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
duke@435 379 return name_space(ns, name_space(sub, intbuf));
duke@435 380 }
duke@435 381
duke@435 382 char *PerfDataManager::name_space(const char* ns, int instance) {
duke@435 383 char intbuf[40];
duke@435 384 jio_snprintf(intbuf, 40, UINT32_FORMAT, instance);
duke@435 385 return name_space(ns, intbuf);
duke@435 386 }
duke@435 387
duke@435 388 PerfStringConstant* PerfDataManager::create_string_constant(CounterNS ns,
duke@435 389 const char* name,
duke@435 390 const char* s,
duke@435 391 TRAPS) {
duke@435 392
duke@435 393 PerfStringConstant* p = new PerfStringConstant(ns, name, s);
duke@435 394
duke@435 395 if (!p->is_valid()) {
duke@435 396 // allocation of native resources failed.
duke@435 397 delete p;
duke@435 398 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 399 }
duke@435 400
duke@435 401 add_item(p, false);
duke@435 402
duke@435 403 return p;
duke@435 404 }
duke@435 405
duke@435 406 PerfLongConstant* PerfDataManager::create_long_constant(CounterNS ns,
duke@435 407 const char* name,
duke@435 408 PerfData::Units u,
duke@435 409 jlong val, TRAPS) {
duke@435 410
duke@435 411 PerfLongConstant* p = new PerfLongConstant(ns, name, u, val);
duke@435 412
duke@435 413 if (!p->is_valid()) {
duke@435 414 // allocation of native resources failed.
duke@435 415 delete p;
duke@435 416 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 417 }
duke@435 418
duke@435 419 add_item(p, false);
duke@435 420
duke@435 421 return p;
duke@435 422 }
duke@435 423
duke@435 424 PerfStringVariable* PerfDataManager::create_string_variable(CounterNS ns,
duke@435 425 const char* name,
duke@435 426 jint max_length,
duke@435 427 const char* s,
duke@435 428 TRAPS) {
duke@435 429
duke@435 430 if (max_length == 0 && s != NULL) max_length = (jint)strlen(s);
duke@435 431
duke@435 432 assert(max_length != 0, "PerfStringVariable with length 0");
duke@435 433
duke@435 434 PerfStringVariable* p = new PerfStringVariable(ns, name, max_length, s);
duke@435 435
duke@435 436 if (!p->is_valid()) {
duke@435 437 // allocation of native resources failed.
duke@435 438 delete p;
duke@435 439 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 440 }
duke@435 441
duke@435 442 add_item(p, false);
duke@435 443
duke@435 444 return p;
duke@435 445 }
duke@435 446
duke@435 447 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
duke@435 448 const char* name,
duke@435 449 PerfData::Units u,
duke@435 450 jlong ival, TRAPS) {
duke@435 451
duke@435 452 PerfLongVariable* p = new PerfLongVariable(ns, name, u, ival);
duke@435 453
duke@435 454 if (!p->is_valid()) {
duke@435 455 // allocation of native resources failed.
duke@435 456 delete p;
duke@435 457 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 458 }
duke@435 459
duke@435 460 add_item(p, false);
duke@435 461
duke@435 462 return p;
duke@435 463 }
duke@435 464
duke@435 465 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
duke@435 466 const char* name,
duke@435 467 PerfData::Units u,
duke@435 468 jlong* sp, TRAPS) {
duke@435 469
duke@435 470 // Sampled counters not supported if UsePerfData is false
duke@435 471 if (!UsePerfData) return NULL;
duke@435 472
duke@435 473 PerfLongVariable* p = new PerfLongVariable(ns, name, u, sp);
duke@435 474
duke@435 475 if (!p->is_valid()) {
duke@435 476 // allocation of native resources failed.
duke@435 477 delete p;
duke@435 478 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 479 }
duke@435 480
duke@435 481 add_item(p, true);
duke@435 482
duke@435 483 return p;
duke@435 484 }
duke@435 485
duke@435 486 PerfLongVariable* PerfDataManager::create_long_variable(CounterNS ns,
duke@435 487 const char* name,
duke@435 488 PerfData::Units u,
duke@435 489 PerfSampleHelper* sh,
duke@435 490 TRAPS) {
duke@435 491
duke@435 492 // Sampled counters not supported if UsePerfData is false
duke@435 493 if (!UsePerfData) return NULL;
duke@435 494
duke@435 495 PerfLongVariable* p = new PerfLongVariable(ns, name, u, sh);
duke@435 496
duke@435 497 if (!p->is_valid()) {
duke@435 498 // allocation of native resources failed.
duke@435 499 delete p;
duke@435 500 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 501 }
duke@435 502
duke@435 503 add_item(p, true);
duke@435 504
duke@435 505 return p;
duke@435 506 }
duke@435 507
duke@435 508 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
duke@435 509 const char* name,
duke@435 510 PerfData::Units u,
duke@435 511 jlong ival, TRAPS) {
duke@435 512
duke@435 513 PerfLongCounter* p = new PerfLongCounter(ns, name, u, ival);
duke@435 514
duke@435 515 if (!p->is_valid()) {
duke@435 516 // allocation of native resources failed.
duke@435 517 delete p;
duke@435 518 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 519 }
duke@435 520
duke@435 521 add_item(p, false);
duke@435 522
duke@435 523 return p;
duke@435 524 }
duke@435 525
duke@435 526 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
duke@435 527 const char* name,
duke@435 528 PerfData::Units u,
duke@435 529 jlong* sp, TRAPS) {
duke@435 530
duke@435 531 // Sampled counters not supported if UsePerfData is false
duke@435 532 if (!UsePerfData) return NULL;
duke@435 533
duke@435 534 PerfLongCounter* p = new PerfLongCounter(ns, name, u, sp);
duke@435 535
duke@435 536 if (!p->is_valid()) {
duke@435 537 // allocation of native resources failed.
duke@435 538 delete p;
duke@435 539 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 540 }
duke@435 541
duke@435 542 add_item(p, true);
duke@435 543
duke@435 544 return p;
duke@435 545 }
duke@435 546
duke@435 547 PerfLongCounter* PerfDataManager::create_long_counter(CounterNS ns,
duke@435 548 const char* name,
duke@435 549 PerfData::Units u,
duke@435 550 PerfSampleHelper* sh,
duke@435 551 TRAPS) {
duke@435 552
duke@435 553 // Sampled counters not supported if UsePerfData is false
duke@435 554 if (!UsePerfData) return NULL;
duke@435 555
duke@435 556 PerfLongCounter* p = new PerfLongCounter(ns, name, u, sh);
duke@435 557
duke@435 558 if (!p->is_valid()) {
duke@435 559 // allocation of native resources failed.
duke@435 560 delete p;
duke@435 561 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
duke@435 562 }
duke@435 563
duke@435 564 add_item(p, true);
duke@435 565
duke@435 566 return p;
duke@435 567 }
duke@435 568
duke@435 569 PerfDataList::PerfDataList(int length) {
duke@435 570
zgu@3900 571 _set = new(ResourceObj::C_HEAP, mtInternal) PerfDataArray(length, true);
duke@435 572 }
duke@435 573
duke@435 574 PerfDataList::PerfDataList(PerfDataList* p) {
duke@435 575
zgu@3900 576 _set = new(ResourceObj::C_HEAP, mtInternal) PerfDataArray(p->length(), true);
duke@435 577
duke@435 578 _set->appendAll(p->get_impl());
duke@435 579 }
duke@435 580
duke@435 581 PerfDataList::~PerfDataList() {
duke@435 582
duke@435 583 delete _set;
duke@435 584
duke@435 585 }
duke@435 586
duke@435 587 bool PerfDataList::by_name(void* name, PerfData* pd) {
duke@435 588
duke@435 589 if (pd == NULL)
duke@435 590 return false;
duke@435 591
duke@435 592 return strcmp((const char*)name, pd->name()) == 0;
duke@435 593 }
duke@435 594
duke@435 595 PerfData* PerfDataList::find_by_name(const char* name) {
duke@435 596
jprovino@4165 597 // if add_item hasn't been called the list won't be initialized
jprovino@4165 598 if (this == NULL)
jprovino@4165 599 return NULL;
jprovino@4165 600
duke@435 601 int i = _set->find((void*)name, PerfDataList::by_name);
duke@435 602
duke@435 603 if (i >= 0 && i <= _set->length())
duke@435 604 return _set->at(i);
duke@435 605 else
duke@435 606 return NULL;
duke@435 607 }
duke@435 608
duke@435 609 PerfDataList* PerfDataList::clone() {
duke@435 610
duke@435 611 PerfDataList* copy = new PerfDataList(this);
duke@435 612
duke@435 613 assert(copy != NULL, "just checking");
duke@435 614
duke@435 615 return copy;
duke@435 616 }

mercurial