src/share/vm/services/heapDumper.cpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "classfile/symbolTable.hpp"
aoqi@0 27 #include "classfile/systemDictionary.hpp"
aoqi@0 28 #include "classfile/vmSymbols.hpp"
aoqi@0 29 #include "gc_implementation/shared/vmGCOperations.hpp"
aoqi@0 30 #include "memory/gcLocker.inline.hpp"
aoqi@0 31 #include "memory/genCollectedHeap.hpp"
aoqi@0 32 #include "memory/universe.hpp"
aoqi@0 33 #include "oops/objArrayKlass.hpp"
aoqi@0 34 #include "runtime/javaCalls.hpp"
aoqi@0 35 #include "runtime/jniHandles.hpp"
aoqi@0 36 #include "runtime/reflectionUtils.hpp"
aoqi@0 37 #include "runtime/vframe.hpp"
aoqi@0 38 #include "runtime/vmThread.hpp"
aoqi@0 39 #include "runtime/vm_operations.hpp"
aoqi@0 40 #include "services/heapDumper.hpp"
aoqi@0 41 #include "services/threadService.hpp"
aoqi@0 42 #include "utilities/ostream.hpp"
aoqi@0 43 #include "utilities/macros.hpp"
aoqi@0 44 #if INCLUDE_ALL_GCS
aoqi@0 45 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
aoqi@0 46 #endif // INCLUDE_ALL_GCS
aoqi@0 47
aoqi@0 48 /*
aoqi@0 49 * HPROF binary format - description copied from:
aoqi@0 50 * src/share/demo/jvmti/hprof/hprof_io.c
aoqi@0 51 *
aoqi@0 52 *
aoqi@0 53 * header "JAVA PROFILE 1.0.1" or "JAVA PROFILE 1.0.2"
aoqi@0 54 * (0-terminated)
aoqi@0 55 *
aoqi@0 56 * u4 size of identifiers. Identifiers are used to represent
aoqi@0 57 * UTF8 strings, objects, stack traces, etc. They usually
aoqi@0 58 * have the same size as host pointers. For example, on
aoqi@0 59 * Solaris and Win32, the size is 4.
aoqi@0 60 * u4 high word
aoqi@0 61 * u4 low word number of milliseconds since 0:00 GMT, 1/1/70
aoqi@0 62 * [record]* a sequence of records.
aoqi@0 63 *
aoqi@0 64 *
aoqi@0 65 * Record format:
aoqi@0 66 *
aoqi@0 67 * u1 a TAG denoting the type of the record
aoqi@0 68 * u4 number of *microseconds* since the time stamp in the
aoqi@0 69 * header. (wraps around in a little more than an hour)
aoqi@0 70 * u4 number of bytes *remaining* in the record. Note that
aoqi@0 71 * this number excludes the tag and the length field itself.
aoqi@0 72 * [u1]* BODY of the record (a sequence of bytes)
aoqi@0 73 *
aoqi@0 74 *
aoqi@0 75 * The following TAGs are supported:
aoqi@0 76 *
aoqi@0 77 * TAG BODY notes
aoqi@0 78 *----------------------------------------------------------
aoqi@0 79 * HPROF_UTF8 a UTF8-encoded name
aoqi@0 80 *
aoqi@0 81 * id name ID
aoqi@0 82 * [u1]* UTF8 characters (no trailing zero)
aoqi@0 83 *
aoqi@0 84 * HPROF_LOAD_CLASS a newly loaded class
aoqi@0 85 *
aoqi@0 86 * u4 class serial number (> 0)
aoqi@0 87 * id class object ID
aoqi@0 88 * u4 stack trace serial number
aoqi@0 89 * id class name ID
aoqi@0 90 *
aoqi@0 91 * HPROF_UNLOAD_CLASS an unloading class
aoqi@0 92 *
aoqi@0 93 * u4 class serial_number
aoqi@0 94 *
aoqi@0 95 * HPROF_FRAME a Java stack frame
aoqi@0 96 *
aoqi@0 97 * id stack frame ID
aoqi@0 98 * id method name ID
aoqi@0 99 * id method signature ID
aoqi@0 100 * id source file name ID
aoqi@0 101 * u4 class serial number
aoqi@0 102 * i4 line number. >0: normal
aoqi@0 103 * -1: unknown
aoqi@0 104 * -2: compiled method
aoqi@0 105 * -3: native method
aoqi@0 106 *
aoqi@0 107 * HPROF_TRACE a Java stack trace
aoqi@0 108 *
aoqi@0 109 * u4 stack trace serial number
aoqi@0 110 * u4 thread serial number
aoqi@0 111 * u4 number of frames
aoqi@0 112 * [id]* stack frame IDs
aoqi@0 113 *
aoqi@0 114 *
aoqi@0 115 * HPROF_ALLOC_SITES a set of heap allocation sites, obtained after GC
aoqi@0 116 *
aoqi@0 117 * u2 flags 0x0001: incremental vs. complete
aoqi@0 118 * 0x0002: sorted by allocation vs. live
aoqi@0 119 * 0x0004: whether to force a GC
aoqi@0 120 * u4 cutoff ratio
aoqi@0 121 * u4 total live bytes
aoqi@0 122 * u4 total live instances
aoqi@0 123 * u8 total bytes allocated
aoqi@0 124 * u8 total instances allocated
aoqi@0 125 * u4 number of sites that follow
aoqi@0 126 * [u1 is_array: 0: normal object
aoqi@0 127 * 2: object array
aoqi@0 128 * 4: boolean array
aoqi@0 129 * 5: char array
aoqi@0 130 * 6: float array
aoqi@0 131 * 7: double array
aoqi@0 132 * 8: byte array
aoqi@0 133 * 9: short array
aoqi@0 134 * 10: int array
aoqi@0 135 * 11: long array
aoqi@0 136 * u4 class serial number (may be zero during startup)
aoqi@0 137 * u4 stack trace serial number
aoqi@0 138 * u4 number of bytes alive
aoqi@0 139 * u4 number of instances alive
aoqi@0 140 * u4 number of bytes allocated
aoqi@0 141 * u4]* number of instance allocated
aoqi@0 142 *
aoqi@0 143 * HPROF_START_THREAD a newly started thread.
aoqi@0 144 *
aoqi@0 145 * u4 thread serial number (> 0)
aoqi@0 146 * id thread object ID
aoqi@0 147 * u4 stack trace serial number
aoqi@0 148 * id thread name ID
aoqi@0 149 * id thread group name ID
aoqi@0 150 * id thread group parent name ID
aoqi@0 151 *
aoqi@0 152 * HPROF_END_THREAD a terminating thread.
aoqi@0 153 *
aoqi@0 154 * u4 thread serial number
aoqi@0 155 *
aoqi@0 156 * HPROF_HEAP_SUMMARY heap summary
aoqi@0 157 *
aoqi@0 158 * u4 total live bytes
aoqi@0 159 * u4 total live instances
aoqi@0 160 * u8 total bytes allocated
aoqi@0 161 * u8 total instances allocated
aoqi@0 162 *
aoqi@0 163 * HPROF_HEAP_DUMP denote a heap dump
aoqi@0 164 *
aoqi@0 165 * [heap dump sub-records]*
aoqi@0 166 *
aoqi@0 167 * There are four kinds of heap dump sub-records:
aoqi@0 168 *
aoqi@0 169 * u1 sub-record type
aoqi@0 170 *
aoqi@0 171 * HPROF_GC_ROOT_UNKNOWN unknown root
aoqi@0 172 *
aoqi@0 173 * id object ID
aoqi@0 174 *
aoqi@0 175 * HPROF_GC_ROOT_THREAD_OBJ thread object
aoqi@0 176 *
aoqi@0 177 * id thread object ID (may be 0 for a
aoqi@0 178 * thread newly attached through JNI)
aoqi@0 179 * u4 thread sequence number
aoqi@0 180 * u4 stack trace sequence number
aoqi@0 181 *
aoqi@0 182 * HPROF_GC_ROOT_JNI_GLOBAL JNI global ref root
aoqi@0 183 *
aoqi@0 184 * id object ID
aoqi@0 185 * id JNI global ref ID
aoqi@0 186 *
aoqi@0 187 * HPROF_GC_ROOT_JNI_LOCAL JNI local ref
aoqi@0 188 *
aoqi@0 189 * id object ID
aoqi@0 190 * u4 thread serial number
aoqi@0 191 * u4 frame # in stack trace (-1 for empty)
aoqi@0 192 *
aoqi@0 193 * HPROF_GC_ROOT_JAVA_FRAME Java stack frame
aoqi@0 194 *
aoqi@0 195 * id object ID
aoqi@0 196 * u4 thread serial number
aoqi@0 197 * u4 frame # in stack trace (-1 for empty)
aoqi@0 198 *
aoqi@0 199 * HPROF_GC_ROOT_NATIVE_STACK Native stack
aoqi@0 200 *
aoqi@0 201 * id object ID
aoqi@0 202 * u4 thread serial number
aoqi@0 203 *
aoqi@0 204 * HPROF_GC_ROOT_STICKY_CLASS System class
aoqi@0 205 *
aoqi@0 206 * id object ID
aoqi@0 207 *
aoqi@0 208 * HPROF_GC_ROOT_THREAD_BLOCK Reference from thread block
aoqi@0 209 *
aoqi@0 210 * id object ID
aoqi@0 211 * u4 thread serial number
aoqi@0 212 *
aoqi@0 213 * HPROF_GC_ROOT_MONITOR_USED Busy monitor
aoqi@0 214 *
aoqi@0 215 * id object ID
aoqi@0 216 *
aoqi@0 217 * HPROF_GC_CLASS_DUMP dump of a class object
aoqi@0 218 *
aoqi@0 219 * id class object ID
aoqi@0 220 * u4 stack trace serial number
aoqi@0 221 * id super class object ID
aoqi@0 222 * id class loader object ID
aoqi@0 223 * id signers object ID
aoqi@0 224 * id protection domain object ID
aoqi@0 225 * id reserved
aoqi@0 226 * id reserved
aoqi@0 227 *
aoqi@0 228 * u4 instance size (in bytes)
aoqi@0 229 *
aoqi@0 230 * u2 size of constant pool
aoqi@0 231 * [u2, constant pool index,
aoqi@0 232 * ty, type
aoqi@0 233 * 2: object
aoqi@0 234 * 4: boolean
aoqi@0 235 * 5: char
aoqi@0 236 * 6: float
aoqi@0 237 * 7: double
aoqi@0 238 * 8: byte
aoqi@0 239 * 9: short
aoqi@0 240 * 10: int
aoqi@0 241 * 11: long
aoqi@0 242 * vl]* and value
aoqi@0 243 *
aoqi@0 244 * u2 number of static fields
aoqi@0 245 * [id, static field name,
aoqi@0 246 * ty, type,
aoqi@0 247 * vl]* and value
aoqi@0 248 *
aoqi@0 249 * u2 number of inst. fields (not inc. super)
aoqi@0 250 * [id, instance field name,
aoqi@0 251 * ty]* type
aoqi@0 252 *
aoqi@0 253 * HPROF_GC_INSTANCE_DUMP dump of a normal object
aoqi@0 254 *
aoqi@0 255 * id object ID
aoqi@0 256 * u4 stack trace serial number
aoqi@0 257 * id class object ID
aoqi@0 258 * u4 number of bytes that follow
aoqi@0 259 * [vl]* instance field values (class, followed
aoqi@0 260 * by super, super's super ...)
aoqi@0 261 *
aoqi@0 262 * HPROF_GC_OBJ_ARRAY_DUMP dump of an object array
aoqi@0 263 *
aoqi@0 264 * id array object ID
aoqi@0 265 * u4 stack trace serial number
aoqi@0 266 * u4 number of elements
aoqi@0 267 * id array class ID
aoqi@0 268 * [id]* elements
aoqi@0 269 *
aoqi@0 270 * HPROF_GC_PRIM_ARRAY_DUMP dump of a primitive array
aoqi@0 271 *
aoqi@0 272 * id array object ID
aoqi@0 273 * u4 stack trace serial number
aoqi@0 274 * u4 number of elements
aoqi@0 275 * u1 element type
aoqi@0 276 * 4: boolean array
aoqi@0 277 * 5: char array
aoqi@0 278 * 6: float array
aoqi@0 279 * 7: double array
aoqi@0 280 * 8: byte array
aoqi@0 281 * 9: short array
aoqi@0 282 * 10: int array
aoqi@0 283 * 11: long array
aoqi@0 284 * [u1]* elements
aoqi@0 285 *
aoqi@0 286 * HPROF_CPU_SAMPLES a set of sample traces of running threads
aoqi@0 287 *
aoqi@0 288 * u4 total number of samples
aoqi@0 289 * u4 # of traces
aoqi@0 290 * [u4 # of samples
aoqi@0 291 * u4]* stack trace serial number
aoqi@0 292 *
aoqi@0 293 * HPROF_CONTROL_SETTINGS the settings of on/off switches
aoqi@0 294 *
aoqi@0 295 * u4 0x00000001: alloc traces on/off
aoqi@0 296 * 0x00000002: cpu sampling on/off
aoqi@0 297 * u2 stack trace depth
aoqi@0 298 *
aoqi@0 299 *
aoqi@0 300 * When the header is "JAVA PROFILE 1.0.2" a heap dump can optionally
aoqi@0 301 * be generated as a sequence of heap dump segments. This sequence is
aoqi@0 302 * terminated by an end record. The additional tags allowed by format
aoqi@0 303 * "JAVA PROFILE 1.0.2" are:
aoqi@0 304 *
aoqi@0 305 * HPROF_HEAP_DUMP_SEGMENT denote a heap dump segment
aoqi@0 306 *
aoqi@0 307 * [heap dump sub-records]*
aoqi@0 308 * The same sub-record types allowed by HPROF_HEAP_DUMP
aoqi@0 309 *
aoqi@0 310 * HPROF_HEAP_DUMP_END denotes the end of a heap dump
aoqi@0 311 *
aoqi@0 312 */
aoqi@0 313
aoqi@0 314
aoqi@0 315 // HPROF tags
aoqi@0 316
aoqi@0 317 typedef enum {
aoqi@0 318 // top-level records
aoqi@0 319 HPROF_UTF8 = 0x01,
aoqi@0 320 HPROF_LOAD_CLASS = 0x02,
aoqi@0 321 HPROF_UNLOAD_CLASS = 0x03,
aoqi@0 322 HPROF_FRAME = 0x04,
aoqi@0 323 HPROF_TRACE = 0x05,
aoqi@0 324 HPROF_ALLOC_SITES = 0x06,
aoqi@0 325 HPROF_HEAP_SUMMARY = 0x07,
aoqi@0 326 HPROF_START_THREAD = 0x0A,
aoqi@0 327 HPROF_END_THREAD = 0x0B,
aoqi@0 328 HPROF_HEAP_DUMP = 0x0C,
aoqi@0 329 HPROF_CPU_SAMPLES = 0x0D,
aoqi@0 330 HPROF_CONTROL_SETTINGS = 0x0E,
aoqi@0 331
aoqi@0 332 // 1.0.2 record types
aoqi@0 333 HPROF_HEAP_DUMP_SEGMENT = 0x1C,
aoqi@0 334 HPROF_HEAP_DUMP_END = 0x2C,
aoqi@0 335
aoqi@0 336 // field types
aoqi@0 337 HPROF_ARRAY_OBJECT = 0x01,
aoqi@0 338 HPROF_NORMAL_OBJECT = 0x02,
aoqi@0 339 HPROF_BOOLEAN = 0x04,
aoqi@0 340 HPROF_CHAR = 0x05,
aoqi@0 341 HPROF_FLOAT = 0x06,
aoqi@0 342 HPROF_DOUBLE = 0x07,
aoqi@0 343 HPROF_BYTE = 0x08,
aoqi@0 344 HPROF_SHORT = 0x09,
aoqi@0 345 HPROF_INT = 0x0A,
aoqi@0 346 HPROF_LONG = 0x0B,
aoqi@0 347
aoqi@0 348 // data-dump sub-records
aoqi@0 349 HPROF_GC_ROOT_UNKNOWN = 0xFF,
aoqi@0 350 HPROF_GC_ROOT_JNI_GLOBAL = 0x01,
aoqi@0 351 HPROF_GC_ROOT_JNI_LOCAL = 0x02,
aoqi@0 352 HPROF_GC_ROOT_JAVA_FRAME = 0x03,
aoqi@0 353 HPROF_GC_ROOT_NATIVE_STACK = 0x04,
aoqi@0 354 HPROF_GC_ROOT_STICKY_CLASS = 0x05,
aoqi@0 355 HPROF_GC_ROOT_THREAD_BLOCK = 0x06,
aoqi@0 356 HPROF_GC_ROOT_MONITOR_USED = 0x07,
aoqi@0 357 HPROF_GC_ROOT_THREAD_OBJ = 0x08,
aoqi@0 358 HPROF_GC_CLASS_DUMP = 0x20,
aoqi@0 359 HPROF_GC_INSTANCE_DUMP = 0x21,
aoqi@0 360 HPROF_GC_OBJ_ARRAY_DUMP = 0x22,
aoqi@0 361 HPROF_GC_PRIM_ARRAY_DUMP = 0x23
aoqi@0 362 } hprofTag;
aoqi@0 363
aoqi@0 364 // Default stack trace ID (used for dummy HPROF_TRACE record)
aoqi@0 365 enum {
aoqi@0 366 STACK_TRACE_ID = 1,
aoqi@0 367 INITIAL_CLASS_COUNT = 200
aoqi@0 368 };
aoqi@0 369
aoqi@0 370 // Supports I/O operations on a dump file
aoqi@0 371
aoqi@0 372 class DumpWriter : public StackObj {
aoqi@0 373 private:
aoqi@0 374 enum {
aoqi@0 375 io_buffer_size = 8*M
aoqi@0 376 };
aoqi@0 377
aoqi@0 378 int _fd; // file descriptor (-1 if dump file not open)
aoqi@0 379 jlong _bytes_written; // number of byte written to dump file
aoqi@0 380
aoqi@0 381 char* _buffer; // internal buffer
aoqi@0 382 int _size;
aoqi@0 383 int _pos;
aoqi@0 384
aoqi@0 385 char* _error; // error message when I/O fails
aoqi@0 386
aoqi@0 387 void set_file_descriptor(int fd) { _fd = fd; }
aoqi@0 388 int file_descriptor() const { return _fd; }
aoqi@0 389
aoqi@0 390 char* buffer() const { return _buffer; }
aoqi@0 391 int buffer_size() const { return _size; }
aoqi@0 392 int position() const { return _pos; }
aoqi@0 393 void set_position(int pos) { _pos = pos; }
aoqi@0 394
aoqi@0 395 void set_error(const char* error) { _error = (char*)os::strdup(error); }
aoqi@0 396
aoqi@0 397 // all I/O go through this function
aoqi@0 398 void write_internal(void* s, int len);
aoqi@0 399
aoqi@0 400 public:
aoqi@0 401 DumpWriter(const char* path);
aoqi@0 402 ~DumpWriter();
aoqi@0 403
aoqi@0 404 void close();
aoqi@0 405 bool is_open() const { return file_descriptor() >= 0; }
aoqi@0 406 void flush();
aoqi@0 407
aoqi@0 408 // total number of bytes written to the disk
aoqi@0 409 jlong bytes_written() const { return _bytes_written; }
aoqi@0 410
aoqi@0 411 // adjust the number of bytes written to disk (used to keep the count
aoqi@0 412 // of the number of bytes written in case of rewrites)
aoqi@0 413 void adjust_bytes_written(jlong n) { _bytes_written += n; }
aoqi@0 414
aoqi@0 415 // number of (buffered) bytes as yet unwritten to the dump file
aoqi@0 416 jlong bytes_unwritten() const { return (jlong)position(); }
aoqi@0 417
aoqi@0 418 char* error() const { return _error; }
aoqi@0 419
aoqi@0 420 jlong current_offset();
aoqi@0 421 void seek_to_offset(jlong pos);
aoqi@0 422
aoqi@0 423 // writer functions
aoqi@0 424 void write_raw(void* s, int len);
aoqi@0 425 void write_u1(u1 x) { write_raw((void*)&x, 1); }
aoqi@0 426 void write_u2(u2 x);
aoqi@0 427 void write_u4(u4 x);
aoqi@0 428 void write_u8(u8 x);
aoqi@0 429 void write_objectID(oop o);
aoqi@0 430 void write_symbolID(Symbol* o);
aoqi@0 431 void write_classID(Klass* k);
aoqi@0 432 void write_id(u4 x);
aoqi@0 433 };
aoqi@0 434
aoqi@0 435 DumpWriter::DumpWriter(const char* path) {
aoqi@0 436 // try to allocate an I/O buffer of io_buffer_size. If there isn't
aoqi@0 437 // sufficient memory then reduce size until we can allocate something.
aoqi@0 438 _size = io_buffer_size;
aoqi@0 439 do {
aoqi@0 440 _buffer = (char*)os::malloc(_size, mtInternal);
aoqi@0 441 if (_buffer == NULL) {
aoqi@0 442 _size = _size >> 1;
aoqi@0 443 }
aoqi@0 444 } while (_buffer == NULL && _size > 0);
aoqi@0 445 assert((_size > 0 && _buffer != NULL) || (_size == 0 && _buffer == NULL), "sanity check");
aoqi@0 446 _pos = 0;
aoqi@0 447 _error = NULL;
aoqi@0 448 _bytes_written = 0L;
aoqi@0 449 _fd = os::create_binary_file(path, false); // don't replace existing file
aoqi@0 450
aoqi@0 451 // if the open failed we record the error
aoqi@0 452 if (_fd < 0) {
aoqi@0 453 _error = (char*)os::strdup(strerror(errno));
aoqi@0 454 }
aoqi@0 455 }
aoqi@0 456
aoqi@0 457 DumpWriter::~DumpWriter() {
aoqi@0 458 // flush and close dump file
aoqi@0 459 if (is_open()) {
aoqi@0 460 close();
aoqi@0 461 }
aoqi@0 462 if (_buffer != NULL) os::free(_buffer);
aoqi@0 463 if (_error != NULL) os::free(_error);
aoqi@0 464 }
aoqi@0 465
aoqi@0 466 // closes dump file (if open)
aoqi@0 467 void DumpWriter::close() {
aoqi@0 468 // flush and close dump file
aoqi@0 469 if (is_open()) {
aoqi@0 470 flush();
aoqi@0 471 ::close(file_descriptor());
aoqi@0 472 set_file_descriptor(-1);
aoqi@0 473 }
aoqi@0 474 }
aoqi@0 475
aoqi@0 476 // write directly to the file
aoqi@0 477 void DumpWriter::write_internal(void* s, int len) {
aoqi@0 478 if (is_open()) {
aoqi@0 479 int n = ::write(file_descriptor(), s, len);
aoqi@0 480 if (n > 0) {
aoqi@0 481 _bytes_written += n;
aoqi@0 482 }
aoqi@0 483 if (n != len) {
aoqi@0 484 if (n < 0) {
aoqi@0 485 set_error(strerror(errno));
aoqi@0 486 } else {
aoqi@0 487 set_error("file size limit");
aoqi@0 488 }
aoqi@0 489 ::close(file_descriptor());
aoqi@0 490 set_file_descriptor(-1);
aoqi@0 491 }
aoqi@0 492 }
aoqi@0 493 }
aoqi@0 494
aoqi@0 495 // write raw bytes
aoqi@0 496 void DumpWriter::write_raw(void* s, int len) {
aoqi@0 497 if (is_open()) {
aoqi@0 498 // flush buffer to make toom
aoqi@0 499 if ((position()+ len) >= buffer_size()) {
aoqi@0 500 flush();
aoqi@0 501 }
aoqi@0 502
aoqi@0 503 // buffer not available or too big to buffer it
aoqi@0 504 if ((buffer() == NULL) || (len >= buffer_size())) {
aoqi@0 505 write_internal(s, len);
aoqi@0 506 } else {
aoqi@0 507 // Should optimize this for u1/u2/u4/u8 sizes.
aoqi@0 508 memcpy(buffer() + position(), s, len);
aoqi@0 509 set_position(position() + len);
aoqi@0 510 }
aoqi@0 511 }
aoqi@0 512 }
aoqi@0 513
aoqi@0 514 // flush any buffered bytes to the file
aoqi@0 515 void DumpWriter::flush() {
aoqi@0 516 if (is_open() && position() > 0) {
aoqi@0 517 write_internal(buffer(), position());
aoqi@0 518 set_position(0);
aoqi@0 519 }
aoqi@0 520 }
aoqi@0 521
aoqi@0 522
aoqi@0 523 jlong DumpWriter::current_offset() {
aoqi@0 524 if (is_open()) {
aoqi@0 525 // the offset is the file offset plus whatever we have buffered
aoqi@0 526 jlong offset = os::current_file_offset(file_descriptor());
aoqi@0 527 assert(offset >= 0, "lseek failed");
aoqi@0 528 return offset + (jlong)position();
aoqi@0 529 } else {
aoqi@0 530 return (jlong)-1;
aoqi@0 531 }
aoqi@0 532 }
aoqi@0 533
aoqi@0 534 void DumpWriter::seek_to_offset(jlong off) {
aoqi@0 535 assert(off >= 0, "bad offset");
aoqi@0 536
aoqi@0 537 // need to flush before seeking
aoqi@0 538 flush();
aoqi@0 539
aoqi@0 540 // may be closed due to I/O error
aoqi@0 541 if (is_open()) {
aoqi@0 542 jlong n = os::seek_to_file_offset(file_descriptor(), off);
aoqi@0 543 assert(n >= 0, "lseek failed");
aoqi@0 544 }
aoqi@0 545 }
aoqi@0 546
aoqi@0 547 void DumpWriter::write_u2(u2 x) {
aoqi@0 548 u2 v;
aoqi@0 549 Bytes::put_Java_u2((address)&v, x);
aoqi@0 550 write_raw((void*)&v, 2);
aoqi@0 551 }
aoqi@0 552
aoqi@0 553 void DumpWriter::write_u4(u4 x) {
aoqi@0 554 u4 v;
aoqi@0 555 Bytes::put_Java_u4((address)&v, x);
aoqi@0 556 write_raw((void*)&v, 4);
aoqi@0 557 }
aoqi@0 558
aoqi@0 559 void DumpWriter::write_u8(u8 x) {
aoqi@0 560 u8 v;
aoqi@0 561 Bytes::put_Java_u8((address)&v, x);
aoqi@0 562 write_raw((void*)&v, 8);
aoqi@0 563 }
aoqi@0 564
aoqi@0 565 void DumpWriter::write_objectID(oop o) {
aoqi@0 566 address a = (address)o;
aoqi@0 567 #ifdef _LP64
aoqi@0 568 write_u8((u8)a);
aoqi@0 569 #else
aoqi@0 570 write_u4((u4)a);
aoqi@0 571 #endif
aoqi@0 572 }
aoqi@0 573
aoqi@0 574 void DumpWriter::write_symbolID(Symbol* s) {
aoqi@0 575 address a = (address)((uintptr_t)s);
aoqi@0 576 #ifdef _LP64
aoqi@0 577 write_u8((u8)a);
aoqi@0 578 #else
aoqi@0 579 write_u4((u4)a);
aoqi@0 580 #endif
aoqi@0 581 }
aoqi@0 582
aoqi@0 583 void DumpWriter::write_id(u4 x) {
aoqi@0 584 #ifdef _LP64
aoqi@0 585 write_u8((u8) x);
aoqi@0 586 #else
aoqi@0 587 write_u4(x);
aoqi@0 588 #endif
aoqi@0 589 }
aoqi@0 590
aoqi@0 591 // We use java mirror as the class ID
aoqi@0 592 void DumpWriter::write_classID(Klass* k) {
aoqi@0 593 write_objectID(k->java_mirror());
aoqi@0 594 }
aoqi@0 595
aoqi@0 596
aoqi@0 597
aoqi@0 598 // Support class with a collection of functions used when dumping the heap
aoqi@0 599
aoqi@0 600 class DumperSupport : AllStatic {
aoqi@0 601 public:
aoqi@0 602
aoqi@0 603 // write a header of the given type
aoqi@0 604 static void write_header(DumpWriter* writer, hprofTag tag, u4 len);
aoqi@0 605
aoqi@0 606 // returns hprof tag for the given type signature
aoqi@0 607 static hprofTag sig2tag(Symbol* sig);
aoqi@0 608 // returns hprof tag for the given basic type
aoqi@0 609 static hprofTag type2tag(BasicType type);
aoqi@0 610
aoqi@0 611 // returns the size of the instance of the given class
aoqi@0 612 static u4 instance_size(Klass* k);
aoqi@0 613
aoqi@0 614 // dump a jfloat
aoqi@0 615 static void dump_float(DumpWriter* writer, jfloat f);
aoqi@0 616 // dump a jdouble
aoqi@0 617 static void dump_double(DumpWriter* writer, jdouble d);
aoqi@0 618 // dumps the raw value of the given field
aoqi@0 619 static void dump_field_value(DumpWriter* writer, char type, address addr);
aoqi@0 620 // dumps static fields of the given class
aoqi@0 621 static void dump_static_fields(DumpWriter* writer, Klass* k);
aoqi@0 622 // dump the raw values of the instance fields of the given object
aoqi@0 623 static void dump_instance_fields(DumpWriter* writer, oop o);
aoqi@0 624 // dumps the definition of the instance fields for a given class
aoqi@0 625 static void dump_instance_field_descriptors(DumpWriter* writer, Klass* k);
aoqi@0 626 // creates HPROF_GC_INSTANCE_DUMP record for the given object
aoqi@0 627 static void dump_instance(DumpWriter* writer, oop o);
aoqi@0 628 // creates HPROF_GC_CLASS_DUMP record for the given class and each of its
aoqi@0 629 // array classes
aoqi@0 630 static void dump_class_and_array_classes(DumpWriter* writer, Klass* k);
aoqi@0 631 // creates HPROF_GC_CLASS_DUMP record for a given primitive array
aoqi@0 632 // class (and each multi-dimensional array class too)
aoqi@0 633 static void dump_basic_type_array_class(DumpWriter* writer, Klass* k);
aoqi@0 634
aoqi@0 635 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
aoqi@0 636 static void dump_object_array(DumpWriter* writer, objArrayOop array);
aoqi@0 637 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
aoqi@0 638 static void dump_prim_array(DumpWriter* writer, typeArrayOop array);
aoqi@0 639 // create HPROF_FRAME record for the given method and bci
aoqi@0 640 static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci);
aoqi@0 641 };
aoqi@0 642
aoqi@0 643 // write a header of the given type
aoqi@0 644 void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) {
aoqi@0 645 writer->write_u1((u1)tag);
aoqi@0 646 writer->write_u4(0); // current ticks
aoqi@0 647 writer->write_u4(len);
aoqi@0 648 }
aoqi@0 649
aoqi@0 650 // returns hprof tag for the given type signature
aoqi@0 651 hprofTag DumperSupport::sig2tag(Symbol* sig) {
aoqi@0 652 switch (sig->byte_at(0)) {
aoqi@0 653 case JVM_SIGNATURE_CLASS : return HPROF_NORMAL_OBJECT;
aoqi@0 654 case JVM_SIGNATURE_ARRAY : return HPROF_NORMAL_OBJECT;
aoqi@0 655 case JVM_SIGNATURE_BYTE : return HPROF_BYTE;
aoqi@0 656 case JVM_SIGNATURE_CHAR : return HPROF_CHAR;
aoqi@0 657 case JVM_SIGNATURE_FLOAT : return HPROF_FLOAT;
aoqi@0 658 case JVM_SIGNATURE_DOUBLE : return HPROF_DOUBLE;
aoqi@0 659 case JVM_SIGNATURE_INT : return HPROF_INT;
aoqi@0 660 case JVM_SIGNATURE_LONG : return HPROF_LONG;
aoqi@0 661 case JVM_SIGNATURE_SHORT : return HPROF_SHORT;
aoqi@0 662 case JVM_SIGNATURE_BOOLEAN : return HPROF_BOOLEAN;
aoqi@0 663 default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
aoqi@0 664 }
aoqi@0 665 }
aoqi@0 666
aoqi@0 667 hprofTag DumperSupport::type2tag(BasicType type) {
aoqi@0 668 switch (type) {
aoqi@0 669 case T_BYTE : return HPROF_BYTE;
aoqi@0 670 case T_CHAR : return HPROF_CHAR;
aoqi@0 671 case T_FLOAT : return HPROF_FLOAT;
aoqi@0 672 case T_DOUBLE : return HPROF_DOUBLE;
aoqi@0 673 case T_INT : return HPROF_INT;
aoqi@0 674 case T_LONG : return HPROF_LONG;
aoqi@0 675 case T_SHORT : return HPROF_SHORT;
aoqi@0 676 case T_BOOLEAN : return HPROF_BOOLEAN;
aoqi@0 677 default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
aoqi@0 678 }
aoqi@0 679 }
aoqi@0 680
aoqi@0 681 // dump a jfloat
aoqi@0 682 void DumperSupport::dump_float(DumpWriter* writer, jfloat f) {
aoqi@0 683 if (g_isnan(f)) {
aoqi@0 684 writer->write_u4(0x7fc00000); // collapsing NaNs
aoqi@0 685 } else {
aoqi@0 686 union {
aoqi@0 687 int i;
aoqi@0 688 float f;
aoqi@0 689 } u;
aoqi@0 690 u.f = (float)f;
aoqi@0 691 writer->write_u4((u4)u.i);
aoqi@0 692 }
aoqi@0 693 }
aoqi@0 694
aoqi@0 695 // dump a jdouble
aoqi@0 696 void DumperSupport::dump_double(DumpWriter* writer, jdouble d) {
aoqi@0 697 union {
aoqi@0 698 jlong l;
aoqi@0 699 double d;
aoqi@0 700 } u;
aoqi@0 701 if (g_isnan(d)) { // collapsing NaNs
aoqi@0 702 u.l = (jlong)(0x7ff80000);
aoqi@0 703 u.l = (u.l << 32);
aoqi@0 704 } else {
aoqi@0 705 u.d = (double)d;
aoqi@0 706 }
aoqi@0 707 writer->write_u8((u8)u.l);
aoqi@0 708 }
aoqi@0 709
aoqi@0 710 // dumps the raw value of the given field
aoqi@0 711 void DumperSupport::dump_field_value(DumpWriter* writer, char type, address addr) {
aoqi@0 712 switch (type) {
aoqi@0 713 case JVM_SIGNATURE_CLASS :
aoqi@0 714 case JVM_SIGNATURE_ARRAY : {
aoqi@0 715 oop o;
aoqi@0 716 if (UseCompressedOops) {
aoqi@0 717 o = oopDesc::load_decode_heap_oop((narrowOop*)addr);
aoqi@0 718 } else {
aoqi@0 719 o = oopDesc::load_decode_heap_oop((oop*)addr);
aoqi@0 720 }
aoqi@0 721
aoqi@0 722 // reflection and sun.misc.Unsafe classes may have a reference to a
aoqi@0 723 // Klass* so filter it out.
aoqi@0 724 assert(o->is_oop_or_null(), "should always be an oop");
aoqi@0 725 writer->write_objectID(o);
aoqi@0 726 break;
aoqi@0 727 }
aoqi@0 728 case JVM_SIGNATURE_BYTE : {
aoqi@0 729 jbyte* b = (jbyte*)addr;
aoqi@0 730 writer->write_u1((u1)*b);
aoqi@0 731 break;
aoqi@0 732 }
aoqi@0 733 case JVM_SIGNATURE_CHAR : {
aoqi@0 734 jchar* c = (jchar*)addr;
aoqi@0 735 writer->write_u2((u2)*c);
aoqi@0 736 break;
aoqi@0 737 }
aoqi@0 738 case JVM_SIGNATURE_SHORT : {
aoqi@0 739 jshort* s = (jshort*)addr;
aoqi@0 740 writer->write_u2((u2)*s);
aoqi@0 741 break;
aoqi@0 742 }
aoqi@0 743 case JVM_SIGNATURE_FLOAT : {
aoqi@0 744 jfloat* f = (jfloat*)addr;
aoqi@0 745 dump_float(writer, *f);
aoqi@0 746 break;
aoqi@0 747 }
aoqi@0 748 case JVM_SIGNATURE_DOUBLE : {
aoqi@0 749 jdouble* f = (jdouble*)addr;
aoqi@0 750 dump_double(writer, *f);
aoqi@0 751 break;
aoqi@0 752 }
aoqi@0 753 case JVM_SIGNATURE_INT : {
aoqi@0 754 jint* i = (jint*)addr;
aoqi@0 755 writer->write_u4((u4)*i);
aoqi@0 756 break;
aoqi@0 757 }
aoqi@0 758 case JVM_SIGNATURE_LONG : {
aoqi@0 759 jlong* l = (jlong*)addr;
aoqi@0 760 writer->write_u8((u8)*l);
aoqi@0 761 break;
aoqi@0 762 }
aoqi@0 763 case JVM_SIGNATURE_BOOLEAN : {
aoqi@0 764 jboolean* b = (jboolean*)addr;
aoqi@0 765 writer->write_u1((u1)*b);
aoqi@0 766 break;
aoqi@0 767 }
aoqi@0 768 default : ShouldNotReachHere();
aoqi@0 769 }
aoqi@0 770 }
aoqi@0 771
aoqi@0 772 // returns the size of the instance of the given class
aoqi@0 773 u4 DumperSupport::instance_size(Klass* k) {
aoqi@0 774 HandleMark hm;
aoqi@0 775 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
aoqi@0 776
aoqi@0 777 int size = 0;
aoqi@0 778
aoqi@0 779 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
aoqi@0 780 if (!fld.access_flags().is_static()) {
aoqi@0 781 Symbol* sig = fld.signature();
aoqi@0 782 switch (sig->byte_at(0)) {
aoqi@0 783 case JVM_SIGNATURE_CLASS :
aoqi@0 784 case JVM_SIGNATURE_ARRAY : size += oopSize; break;
aoqi@0 785
aoqi@0 786 case JVM_SIGNATURE_BYTE :
aoqi@0 787 case JVM_SIGNATURE_BOOLEAN : size += 1; break;
aoqi@0 788
aoqi@0 789 case JVM_SIGNATURE_CHAR :
aoqi@0 790 case JVM_SIGNATURE_SHORT : size += 2; break;
aoqi@0 791
aoqi@0 792 case JVM_SIGNATURE_INT :
aoqi@0 793 case JVM_SIGNATURE_FLOAT : size += 4; break;
aoqi@0 794
aoqi@0 795 case JVM_SIGNATURE_LONG :
aoqi@0 796 case JVM_SIGNATURE_DOUBLE : size += 8; break;
aoqi@0 797
aoqi@0 798 default : ShouldNotReachHere();
aoqi@0 799 }
aoqi@0 800 }
aoqi@0 801 }
aoqi@0 802 return (u4)size;
aoqi@0 803 }
aoqi@0 804
aoqi@0 805 // dumps static fields of the given class
aoqi@0 806 void DumperSupport::dump_static_fields(DumpWriter* writer, Klass* k) {
aoqi@0 807 HandleMark hm;
aoqi@0 808 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
aoqi@0 809
aoqi@0 810 // pass 1 - count the static fields
aoqi@0 811 u2 field_count = 0;
aoqi@0 812 for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
aoqi@0 813 if (fldc.access_flags().is_static()) field_count++;
aoqi@0 814 }
aoqi@0 815
aoqi@0 816 writer->write_u2(field_count);
aoqi@0 817
aoqi@0 818 // pass 2 - dump the field descriptors and raw values
aoqi@0 819 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {
aoqi@0 820 if (fld.access_flags().is_static()) {
aoqi@0 821 Symbol* sig = fld.signature();
aoqi@0 822
aoqi@0 823 writer->write_symbolID(fld.name()); // name
aoqi@0 824 writer->write_u1(sig2tag(sig)); // type
aoqi@0 825
aoqi@0 826 // value
aoqi@0 827 int offset = fld.offset();
aoqi@0 828 address addr = (address)ikh->java_mirror() + offset;
aoqi@0 829
aoqi@0 830 dump_field_value(writer, sig->byte_at(0), addr);
aoqi@0 831 }
aoqi@0 832 }
aoqi@0 833 }
aoqi@0 834
aoqi@0 835 // dump the raw values of the instance fields of the given object
aoqi@0 836 void DumperSupport::dump_instance_fields(DumpWriter* writer, oop o) {
aoqi@0 837 HandleMark hm;
aoqi@0 838 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), o->klass());
aoqi@0 839
aoqi@0 840 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
aoqi@0 841 if (!fld.access_flags().is_static()) {
aoqi@0 842 Symbol* sig = fld.signature();
aoqi@0 843 address addr = (address)o + fld.offset();
aoqi@0 844
aoqi@0 845 dump_field_value(writer, sig->byte_at(0), addr);
aoqi@0 846 }
aoqi@0 847 }
aoqi@0 848 }
aoqi@0 849
aoqi@0 850 // dumps the definition of the instance fields for a given class
aoqi@0 851 void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, Klass* k) {
aoqi@0 852 HandleMark hm;
aoqi@0 853 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
aoqi@0 854
aoqi@0 855 // pass 1 - count the instance fields
aoqi@0 856 u2 field_count = 0;
aoqi@0 857 for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
aoqi@0 858 if (!fldc.access_flags().is_static()) field_count++;
aoqi@0 859 }
aoqi@0 860
aoqi@0 861 writer->write_u2(field_count);
aoqi@0 862
aoqi@0 863 // pass 2 - dump the field descriptors
aoqi@0 864 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {
aoqi@0 865 if (!fld.access_flags().is_static()) {
aoqi@0 866 Symbol* sig = fld.signature();
aoqi@0 867
aoqi@0 868 writer->write_symbolID(fld.name()); // name
aoqi@0 869 writer->write_u1(sig2tag(sig)); // type
aoqi@0 870 }
aoqi@0 871 }
aoqi@0 872 }
aoqi@0 873
aoqi@0 874 // creates HPROF_GC_INSTANCE_DUMP record for the given object
aoqi@0 875 void DumperSupport::dump_instance(DumpWriter* writer, oop o) {
aoqi@0 876 Klass* k = o->klass();
aoqi@0 877
aoqi@0 878 writer->write_u1(HPROF_GC_INSTANCE_DUMP);
aoqi@0 879 writer->write_objectID(o);
aoqi@0 880 writer->write_u4(STACK_TRACE_ID);
aoqi@0 881
aoqi@0 882 // class ID
aoqi@0 883 writer->write_classID(k);
aoqi@0 884
aoqi@0 885 // number of bytes that follow
aoqi@0 886 writer->write_u4(instance_size(k) );
aoqi@0 887
aoqi@0 888 // field values
aoqi@0 889 dump_instance_fields(writer, o);
aoqi@0 890 }
aoqi@0 891
aoqi@0 892 // creates HPROF_GC_CLASS_DUMP record for the given class and each of
aoqi@0 893 // its array classes
aoqi@0 894 void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) {
aoqi@0 895 Klass* klass = k;
aoqi@0 896 assert(klass->oop_is_instance(), "not an InstanceKlass");
aoqi@0 897 InstanceKlass* ik = (InstanceKlass*)klass;
aoqi@0 898
aoqi@0 899 writer->write_u1(HPROF_GC_CLASS_DUMP);
aoqi@0 900
aoqi@0 901 // class ID
aoqi@0 902 writer->write_classID(ik);
aoqi@0 903 writer->write_u4(STACK_TRACE_ID);
aoqi@0 904
aoqi@0 905 // super class ID
aoqi@0 906 Klass* java_super = ik->java_super();
aoqi@0 907 if (java_super == NULL) {
aoqi@0 908 writer->write_objectID(oop(NULL));
aoqi@0 909 } else {
aoqi@0 910 writer->write_classID(java_super);
aoqi@0 911 }
aoqi@0 912
aoqi@0 913 writer->write_objectID(ik->class_loader());
aoqi@0 914 writer->write_objectID(ik->signers());
aoqi@0 915 writer->write_objectID(ik->protection_domain());
aoqi@0 916
aoqi@0 917 // reserved
aoqi@0 918 writer->write_objectID(oop(NULL));
aoqi@0 919 writer->write_objectID(oop(NULL));
aoqi@0 920
aoqi@0 921 // instance size
aoqi@0 922 writer->write_u4(DumperSupport::instance_size(k));
aoqi@0 923
aoqi@0 924 // size of constant pool - ignored by HAT 1.1
aoqi@0 925 writer->write_u2(0);
aoqi@0 926
aoqi@0 927 // number of static fields
aoqi@0 928 dump_static_fields(writer, k);
aoqi@0 929
aoqi@0 930 // description of instance fields
aoqi@0 931 dump_instance_field_descriptors(writer, k);
aoqi@0 932
aoqi@0 933 // array classes
aoqi@0 934 k = klass->array_klass_or_null();
aoqi@0 935 while (k != NULL) {
aoqi@0 936 Klass* klass = k;
aoqi@0 937 assert(klass->oop_is_objArray(), "not an ObjArrayKlass");
aoqi@0 938
aoqi@0 939 writer->write_u1(HPROF_GC_CLASS_DUMP);
aoqi@0 940 writer->write_classID(klass);
aoqi@0 941 writer->write_u4(STACK_TRACE_ID);
aoqi@0 942
aoqi@0 943 // super class of array classes is java.lang.Object
aoqi@0 944 java_super = klass->java_super();
aoqi@0 945 assert(java_super != NULL, "checking");
aoqi@0 946 writer->write_classID(java_super);
aoqi@0 947
aoqi@0 948 writer->write_objectID(ik->class_loader());
aoqi@0 949 writer->write_objectID(ik->signers());
aoqi@0 950 writer->write_objectID(ik->protection_domain());
aoqi@0 951
aoqi@0 952 writer->write_objectID(oop(NULL)); // reserved
aoqi@0 953 writer->write_objectID(oop(NULL));
aoqi@0 954 writer->write_u4(0); // instance size
aoqi@0 955 writer->write_u2(0); // constant pool
aoqi@0 956 writer->write_u2(0); // static fields
aoqi@0 957 writer->write_u2(0); // instance fields
aoqi@0 958
aoqi@0 959 // get the array class for the next rank
aoqi@0 960 k = klass->array_klass_or_null();
aoqi@0 961 }
aoqi@0 962 }
aoqi@0 963
aoqi@0 964 // creates HPROF_GC_CLASS_DUMP record for a given primitive array
aoqi@0 965 // class (and each multi-dimensional array class too)
aoqi@0 966 void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) {
aoqi@0 967 // array classes
aoqi@0 968 while (k != NULL) {
aoqi@0 969 Klass* klass = k;
aoqi@0 970
aoqi@0 971 writer->write_u1(HPROF_GC_CLASS_DUMP);
aoqi@0 972 writer->write_classID(klass);
aoqi@0 973 writer->write_u4(STACK_TRACE_ID);
aoqi@0 974
aoqi@0 975 // super class of array classes is java.lang.Object
aoqi@0 976 Klass* java_super = klass->java_super();
aoqi@0 977 assert(java_super != NULL, "checking");
aoqi@0 978 writer->write_classID(java_super);
aoqi@0 979
aoqi@0 980 writer->write_objectID(oop(NULL)); // loader
aoqi@0 981 writer->write_objectID(oop(NULL)); // signers
aoqi@0 982 writer->write_objectID(oop(NULL)); // protection domain
aoqi@0 983
aoqi@0 984 writer->write_objectID(oop(NULL)); // reserved
aoqi@0 985 writer->write_objectID(oop(NULL));
aoqi@0 986 writer->write_u4(0); // instance size
aoqi@0 987 writer->write_u2(0); // constant pool
aoqi@0 988 writer->write_u2(0); // static fields
aoqi@0 989 writer->write_u2(0); // instance fields
aoqi@0 990
aoqi@0 991 // get the array class for the next rank
aoqi@0 992 k = klass->array_klass_or_null();
aoqi@0 993 }
aoqi@0 994 }
aoqi@0 995
aoqi@0 996 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
aoqi@0 997 void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) {
aoqi@0 998
aoqi@0 999 writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP);
aoqi@0 1000 writer->write_objectID(array);
aoqi@0 1001 writer->write_u4(STACK_TRACE_ID);
aoqi@0 1002 writer->write_u4((u4)array->length());
aoqi@0 1003
aoqi@0 1004 // array class ID
aoqi@0 1005 writer->write_classID(array->klass());
aoqi@0 1006
aoqi@0 1007 // [id]* elements
aoqi@0 1008 for (int index=0; index<array->length(); index++) {
aoqi@0 1009 oop o = array->obj_at(index);
aoqi@0 1010 writer->write_objectID(o);
aoqi@0 1011 }
aoqi@0 1012 }
aoqi@0 1013
aoqi@0 1014 #define WRITE_ARRAY(Array, Type, Size) \
aoqi@0 1015 for (int i=0; i<Array->length(); i++) { writer->write_##Size((Size)array->Type##_at(i)); }
aoqi@0 1016
aoqi@0 1017
aoqi@0 1018 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
aoqi@0 1019 void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
aoqi@0 1020 BasicType type = TypeArrayKlass::cast(array->klass())->element_type();
aoqi@0 1021
aoqi@0 1022 writer->write_u1(HPROF_GC_PRIM_ARRAY_DUMP);
aoqi@0 1023 writer->write_objectID(array);
aoqi@0 1024 writer->write_u4(STACK_TRACE_ID);
aoqi@0 1025 writer->write_u4((u4)array->length());
aoqi@0 1026 writer->write_u1(type2tag(type));
aoqi@0 1027
aoqi@0 1028 // nothing to copy
aoqi@0 1029 if (array->length() == 0) {
aoqi@0 1030 return;
aoqi@0 1031 }
aoqi@0 1032
aoqi@0 1033 // If the byte ordering is big endian then we can copy most types directly
aoqi@0 1034 int length_in_bytes = array->length() * type2aelembytes(type);
aoqi@0 1035 assert(length_in_bytes > 0, "nothing to copy");
aoqi@0 1036
aoqi@0 1037 switch (type) {
aoqi@0 1038 case T_INT : {
aoqi@0 1039 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1040 WRITE_ARRAY(array, int, u4);
aoqi@0 1041 } else {
aoqi@0 1042 writer->write_raw((void*)(array->int_at_addr(0)), length_in_bytes);
aoqi@0 1043 }
aoqi@0 1044 break;
aoqi@0 1045 }
aoqi@0 1046 case T_BYTE : {
aoqi@0 1047 writer->write_raw((void*)(array->byte_at_addr(0)), length_in_bytes);
aoqi@0 1048 break;
aoqi@0 1049 }
aoqi@0 1050 case T_CHAR : {
aoqi@0 1051 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1052 WRITE_ARRAY(array, char, u2);
aoqi@0 1053 } else {
aoqi@0 1054 writer->write_raw((void*)(array->char_at_addr(0)), length_in_bytes);
aoqi@0 1055 }
aoqi@0 1056 break;
aoqi@0 1057 }
aoqi@0 1058 case T_SHORT : {
aoqi@0 1059 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1060 WRITE_ARRAY(array, short, u2);
aoqi@0 1061 } else {
aoqi@0 1062 writer->write_raw((void*)(array->short_at_addr(0)), length_in_bytes);
aoqi@0 1063 }
aoqi@0 1064 break;
aoqi@0 1065 }
aoqi@0 1066 case T_BOOLEAN : {
aoqi@0 1067 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1068 WRITE_ARRAY(array, bool, u1);
aoqi@0 1069 } else {
aoqi@0 1070 writer->write_raw((void*)(array->bool_at_addr(0)), length_in_bytes);
aoqi@0 1071 }
aoqi@0 1072 break;
aoqi@0 1073 }
aoqi@0 1074 case T_LONG : {
aoqi@0 1075 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1076 WRITE_ARRAY(array, long, u8);
aoqi@0 1077 } else {
aoqi@0 1078 writer->write_raw((void*)(array->long_at_addr(0)), length_in_bytes);
aoqi@0 1079 }
aoqi@0 1080 break;
aoqi@0 1081 }
aoqi@0 1082
aoqi@0 1083 // handle float/doubles in a special value to ensure than NaNs are
aoqi@0 1084 // written correctly. TO DO: Check if we can avoid this on processors that
aoqi@0 1085 // use IEEE 754.
aoqi@0 1086
aoqi@0 1087 case T_FLOAT : {
aoqi@0 1088 for (int i=0; i<array->length(); i++) {
aoqi@0 1089 dump_float( writer, array->float_at(i) );
aoqi@0 1090 }
aoqi@0 1091 break;
aoqi@0 1092 }
aoqi@0 1093 case T_DOUBLE : {
aoqi@0 1094 for (int i=0; i<array->length(); i++) {
aoqi@0 1095 dump_double( writer, array->double_at(i) );
aoqi@0 1096 }
aoqi@0 1097 break;
aoqi@0 1098 }
aoqi@0 1099 default : ShouldNotReachHere();
aoqi@0 1100 }
aoqi@0 1101 }
aoqi@0 1102
aoqi@0 1103 // create a HPROF_FRAME record of the given Method* and bci
aoqi@0 1104 void DumperSupport::dump_stack_frame(DumpWriter* writer,
aoqi@0 1105 int frame_serial_num,
aoqi@0 1106 int class_serial_num,
aoqi@0 1107 Method* m,
aoqi@0 1108 int bci) {
aoqi@0 1109 int line_number;
aoqi@0 1110 if (m->is_native()) {
aoqi@0 1111 line_number = -3; // native frame
aoqi@0 1112 } else {
aoqi@0 1113 line_number = m->line_number_from_bci(bci);
aoqi@0 1114 }
aoqi@0 1115
aoqi@0 1116 write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4));
aoqi@0 1117 writer->write_id(frame_serial_num); // frame serial number
aoqi@0 1118 writer->write_symbolID(m->name()); // method's name
aoqi@0 1119 writer->write_symbolID(m->signature()); // method's signature
aoqi@0 1120
aoqi@0 1121 assert(m->method_holder()->oop_is_instance(), "not InstanceKlass");
aoqi@0 1122 writer->write_symbolID(m->method_holder()->source_file_name()); // source file name
aoqi@0 1123 writer->write_u4(class_serial_num); // class serial number
aoqi@0 1124 writer->write_u4((u4) line_number); // line number
aoqi@0 1125 }
aoqi@0 1126
aoqi@0 1127
aoqi@0 1128 // Support class used to generate HPROF_UTF8 records from the entries in the
aoqi@0 1129 // SymbolTable.
aoqi@0 1130
aoqi@0 1131 class SymbolTableDumper : public SymbolClosure {
aoqi@0 1132 private:
aoqi@0 1133 DumpWriter* _writer;
aoqi@0 1134 DumpWriter* writer() const { return _writer; }
aoqi@0 1135 public:
aoqi@0 1136 SymbolTableDumper(DumpWriter* writer) { _writer = writer; }
aoqi@0 1137 void do_symbol(Symbol** p);
aoqi@0 1138 };
aoqi@0 1139
aoqi@0 1140 void SymbolTableDumper::do_symbol(Symbol** p) {
aoqi@0 1141 ResourceMark rm;
aoqi@0 1142 Symbol* sym = load_symbol(p);
aoqi@0 1143 int len = sym->utf8_length();
aoqi@0 1144 if (len > 0) {
aoqi@0 1145 char* s = sym->as_utf8();
aoqi@0 1146 DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);
aoqi@0 1147 writer()->write_symbolID(sym);
aoqi@0 1148 writer()->write_raw(s, len);
aoqi@0 1149 }
aoqi@0 1150 }
aoqi@0 1151
aoqi@0 1152 // Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records
aoqi@0 1153
aoqi@0 1154 class JNILocalsDumper : public OopClosure {
aoqi@0 1155 private:
aoqi@0 1156 DumpWriter* _writer;
aoqi@0 1157 u4 _thread_serial_num;
aoqi@0 1158 int _frame_num;
aoqi@0 1159 DumpWriter* writer() const { return _writer; }
aoqi@0 1160 public:
aoqi@0 1161 JNILocalsDumper(DumpWriter* writer, u4 thread_serial_num) {
aoqi@0 1162 _writer = writer;
aoqi@0 1163 _thread_serial_num = thread_serial_num;
aoqi@0 1164 _frame_num = -1; // default - empty stack
aoqi@0 1165 }
aoqi@0 1166 void set_frame_number(int n) { _frame_num = n; }
aoqi@0 1167 void do_oop(oop* obj_p);
aoqi@0 1168 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
aoqi@0 1169 };
aoqi@0 1170
aoqi@0 1171
aoqi@0 1172 void JNILocalsDumper::do_oop(oop* obj_p) {
aoqi@0 1173 // ignore null or deleted handles
aoqi@0 1174 oop o = *obj_p;
aoqi@0 1175 if (o != NULL && o != JNIHandles::deleted_handle()) {
aoqi@0 1176 writer()->write_u1(HPROF_GC_ROOT_JNI_LOCAL);
aoqi@0 1177 writer()->write_objectID(o);
aoqi@0 1178 writer()->write_u4(_thread_serial_num);
aoqi@0 1179 writer()->write_u4((u4)_frame_num);
aoqi@0 1180 }
aoqi@0 1181 }
aoqi@0 1182
aoqi@0 1183
aoqi@0 1184 // Support class used to generate HPROF_GC_ROOT_JNI_GLOBAL records
aoqi@0 1185
aoqi@0 1186 class JNIGlobalsDumper : public OopClosure {
aoqi@0 1187 private:
aoqi@0 1188 DumpWriter* _writer;
aoqi@0 1189 DumpWriter* writer() const { return _writer; }
aoqi@0 1190
aoqi@0 1191 public:
aoqi@0 1192 JNIGlobalsDumper(DumpWriter* writer) {
aoqi@0 1193 _writer = writer;
aoqi@0 1194 }
aoqi@0 1195 void do_oop(oop* obj_p);
aoqi@0 1196 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
aoqi@0 1197 };
aoqi@0 1198
aoqi@0 1199 void JNIGlobalsDumper::do_oop(oop* obj_p) {
aoqi@0 1200 oop o = *obj_p;
aoqi@0 1201
aoqi@0 1202 // ignore these
aoqi@0 1203 if (o == NULL || o == JNIHandles::deleted_handle()) return;
aoqi@0 1204
aoqi@0 1205 // we ignore global ref to symbols and other internal objects
aoqi@0 1206 if (o->is_instance() || o->is_objArray() || o->is_typeArray()) {
aoqi@0 1207 writer()->write_u1(HPROF_GC_ROOT_JNI_GLOBAL);
aoqi@0 1208 writer()->write_objectID(o);
aoqi@0 1209 writer()->write_objectID((oopDesc*)obj_p); // global ref ID
aoqi@0 1210 }
aoqi@0 1211 };
aoqi@0 1212
aoqi@0 1213
aoqi@0 1214 // Support class used to generate HPROF_GC_ROOT_MONITOR_USED records
aoqi@0 1215
aoqi@0 1216 class MonitorUsedDumper : public OopClosure {
aoqi@0 1217 private:
aoqi@0 1218 DumpWriter* _writer;
aoqi@0 1219 DumpWriter* writer() const { return _writer; }
aoqi@0 1220 public:
aoqi@0 1221 MonitorUsedDumper(DumpWriter* writer) {
aoqi@0 1222 _writer = writer;
aoqi@0 1223 }
aoqi@0 1224 void do_oop(oop* obj_p) {
aoqi@0 1225 writer()->write_u1(HPROF_GC_ROOT_MONITOR_USED);
aoqi@0 1226 writer()->write_objectID(*obj_p);
aoqi@0 1227 }
aoqi@0 1228 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
aoqi@0 1229 };
aoqi@0 1230
aoqi@0 1231
aoqi@0 1232 // Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records
aoqi@0 1233
aoqi@0 1234 class StickyClassDumper : public KlassClosure {
aoqi@0 1235 private:
aoqi@0 1236 DumpWriter* _writer;
aoqi@0 1237 DumpWriter* writer() const { return _writer; }
aoqi@0 1238 public:
aoqi@0 1239 StickyClassDumper(DumpWriter* writer) {
aoqi@0 1240 _writer = writer;
aoqi@0 1241 }
aoqi@0 1242 void do_klass(Klass* k) {
aoqi@0 1243 if (k->oop_is_instance()) {
aoqi@0 1244 InstanceKlass* ik = InstanceKlass::cast(k);
aoqi@0 1245 writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS);
aoqi@0 1246 writer()->write_classID(ik);
aoqi@0 1247 }
aoqi@0 1248 }
aoqi@0 1249 };
aoqi@0 1250
aoqi@0 1251
aoqi@0 1252 class VM_HeapDumper;
aoqi@0 1253
aoqi@0 1254 // Support class using when iterating over the heap.
aoqi@0 1255
aoqi@0 1256 class HeapObjectDumper : public ObjectClosure {
aoqi@0 1257 private:
aoqi@0 1258 VM_HeapDumper* _dumper;
aoqi@0 1259 DumpWriter* _writer;
aoqi@0 1260
aoqi@0 1261 VM_HeapDumper* dumper() { return _dumper; }
aoqi@0 1262 DumpWriter* writer() { return _writer; }
aoqi@0 1263
aoqi@0 1264 // used to indicate that a record has been writen
aoqi@0 1265 void mark_end_of_record();
aoqi@0 1266
aoqi@0 1267 public:
aoqi@0 1268 HeapObjectDumper(VM_HeapDumper* dumper, DumpWriter* writer) {
aoqi@0 1269 _dumper = dumper;
aoqi@0 1270 _writer = writer;
aoqi@0 1271 }
aoqi@0 1272
aoqi@0 1273 // called for each object in the heap
aoqi@0 1274 void do_object(oop o);
aoqi@0 1275 };
aoqi@0 1276
aoqi@0 1277 void HeapObjectDumper::do_object(oop o) {
aoqi@0 1278 // hide the sentinel for deleted handles
aoqi@0 1279 if (o == JNIHandles::deleted_handle()) return;
aoqi@0 1280
aoqi@0 1281 // skip classes as these emitted as HPROF_GC_CLASS_DUMP records
aoqi@0 1282 if (o->klass() == SystemDictionary::Class_klass()) {
aoqi@0 1283 if (!java_lang_Class::is_primitive(o)) {
aoqi@0 1284 return;
aoqi@0 1285 }
aoqi@0 1286 }
aoqi@0 1287
aoqi@0 1288 // create a HPROF_GC_INSTANCE record for each object
aoqi@0 1289 if (o->is_instance()) {
aoqi@0 1290 DumperSupport::dump_instance(writer(), o);
aoqi@0 1291 mark_end_of_record();
aoqi@0 1292 } else {
aoqi@0 1293 // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
aoqi@0 1294 if (o->is_objArray()) {
aoqi@0 1295 DumperSupport::dump_object_array(writer(), objArrayOop(o));
aoqi@0 1296 mark_end_of_record();
aoqi@0 1297 } else {
aoqi@0 1298 // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
aoqi@0 1299 if (o->is_typeArray()) {
aoqi@0 1300 DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
aoqi@0 1301 mark_end_of_record();
aoqi@0 1302 }
aoqi@0 1303 }
aoqi@0 1304 }
aoqi@0 1305 }
aoqi@0 1306
aoqi@0 1307 // The VM operation that performs the heap dump
aoqi@0 1308 class VM_HeapDumper : public VM_GC_Operation {
aoqi@0 1309 private:
aoqi@0 1310 static VM_HeapDumper* _global_dumper;
aoqi@0 1311 static DumpWriter* _global_writer;
aoqi@0 1312 DumpWriter* _local_writer;
aoqi@0 1313 JavaThread* _oome_thread;
aoqi@0 1314 Method* _oome_constructor;
aoqi@0 1315 bool _gc_before_heap_dump;
aoqi@0 1316 bool _is_segmented_dump;
aoqi@0 1317 jlong _dump_start;
aoqi@0 1318 GrowableArray<Klass*>* _klass_map;
aoqi@0 1319 ThreadStackTrace** _stack_traces;
aoqi@0 1320 int _num_threads;
aoqi@0 1321
aoqi@0 1322 // accessors and setters
aoqi@0 1323 static VM_HeapDumper* dumper() { assert(_global_dumper != NULL, "Error"); return _global_dumper; }
aoqi@0 1324 static DumpWriter* writer() { assert(_global_writer != NULL, "Error"); return _global_writer; }
aoqi@0 1325 void set_global_dumper() {
aoqi@0 1326 assert(_global_dumper == NULL, "Error");
aoqi@0 1327 _global_dumper = this;
aoqi@0 1328 }
aoqi@0 1329 void set_global_writer() {
aoqi@0 1330 assert(_global_writer == NULL, "Error");
aoqi@0 1331 _global_writer = _local_writer;
aoqi@0 1332 }
aoqi@0 1333 void clear_global_dumper() { _global_dumper = NULL; }
aoqi@0 1334 void clear_global_writer() { _global_writer = NULL; }
aoqi@0 1335
aoqi@0 1336 bool is_segmented_dump() const { return _is_segmented_dump; }
aoqi@0 1337 void set_segmented_dump() { _is_segmented_dump = true; }
aoqi@0 1338 jlong dump_start() const { return _dump_start; }
aoqi@0 1339 void set_dump_start(jlong pos);
aoqi@0 1340
aoqi@0 1341 bool skip_operation() const;
aoqi@0 1342
aoqi@0 1343 // writes a HPROF_LOAD_CLASS record
aoqi@0 1344 static void do_load_class(Klass* k);
aoqi@0 1345
aoqi@0 1346 // writes a HPROF_GC_CLASS_DUMP record for the given class
aoqi@0 1347 // (and each array class too)
aoqi@0 1348 static void do_class_dump(Klass* k);
aoqi@0 1349
aoqi@0 1350 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
aoqi@0 1351 // array (and each multi-dimensional array too)
aoqi@0 1352 static void do_basic_type_array_class_dump(Klass* k);
aoqi@0 1353
aoqi@0 1354 // HPROF_GC_ROOT_THREAD_OBJ records
aoqi@0 1355 int do_thread(JavaThread* thread, u4 thread_serial_num);
aoqi@0 1356 void do_threads();
aoqi@0 1357
aoqi@0 1358 void add_class_serial_number(Klass* k, int serial_num) {
aoqi@0 1359 _klass_map->at_put_grow(serial_num, k);
aoqi@0 1360 }
aoqi@0 1361
aoqi@0 1362 // HPROF_TRACE and HPROF_FRAME records
aoqi@0 1363 void dump_stack_traces();
aoqi@0 1364
aoqi@0 1365 // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
aoqi@0 1366 void write_dump_header();
aoqi@0 1367
aoqi@0 1368 // fixes up the length of the current dump record
aoqi@0 1369 void write_current_dump_record_length();
aoqi@0 1370
aoqi@0 1371 // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
aoqi@0 1372 // record in the case of a segmented heap dump)
aoqi@0 1373 void end_of_dump();
aoqi@0 1374
aoqi@0 1375 public:
aoqi@0 1376 VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) :
aoqi@0 1377 VM_GC_Operation(0 /* total collections, dummy, ignored */,
aoqi@0 1378 GCCause::_heap_dump /* GC Cause */,
aoqi@0 1379 0 /* total full collections, dummy, ignored */,
aoqi@0 1380 gc_before_heap_dump) {
aoqi@0 1381 _local_writer = writer;
aoqi@0 1382 _gc_before_heap_dump = gc_before_heap_dump;
aoqi@0 1383 _is_segmented_dump = false;
aoqi@0 1384 _dump_start = (jlong)-1;
aoqi@0 1385 _klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
aoqi@0 1386 _stack_traces = NULL;
aoqi@0 1387 _num_threads = 0;
aoqi@0 1388 if (oome) {
aoqi@0 1389 assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");
aoqi@0 1390 // get OutOfMemoryError zero-parameter constructor
aoqi@0 1391 InstanceKlass* oome_ik = InstanceKlass::cast(SystemDictionary::OutOfMemoryError_klass());
aoqi@0 1392 _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(),
aoqi@0 1393 vmSymbols::void_method_signature());
aoqi@0 1394 // get thread throwing OOME when generating the heap dump at OOME
aoqi@0 1395 _oome_thread = JavaThread::current();
aoqi@0 1396 } else {
aoqi@0 1397 _oome_thread = NULL;
aoqi@0 1398 _oome_constructor = NULL;
aoqi@0 1399 }
aoqi@0 1400 }
aoqi@0 1401 ~VM_HeapDumper() {
aoqi@0 1402 if (_stack_traces != NULL) {
aoqi@0 1403 for (int i=0; i < _num_threads; i++) {
aoqi@0 1404 delete _stack_traces[i];
aoqi@0 1405 }
aoqi@0 1406 FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces, mtInternal);
aoqi@0 1407 }
aoqi@0 1408 delete _klass_map;
aoqi@0 1409 }
aoqi@0 1410
aoqi@0 1411 VMOp_Type type() const { return VMOp_HeapDumper; }
aoqi@0 1412 // used to mark sub-record boundary
aoqi@0 1413 void check_segment_length();
aoqi@0 1414 void doit();
aoqi@0 1415 };
aoqi@0 1416
aoqi@0 1417 VM_HeapDumper* VM_HeapDumper::_global_dumper = NULL;
aoqi@0 1418 DumpWriter* VM_HeapDumper::_global_writer = NULL;
aoqi@0 1419
aoqi@0 1420 bool VM_HeapDumper::skip_operation() const {
aoqi@0 1421 return false;
aoqi@0 1422 }
aoqi@0 1423
aoqi@0 1424 // sets the dump starting position
aoqi@0 1425 void VM_HeapDumper::set_dump_start(jlong pos) {
aoqi@0 1426 _dump_start = pos;
aoqi@0 1427 }
aoqi@0 1428
aoqi@0 1429 // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
aoqi@0 1430 void VM_HeapDumper::write_dump_header() {
aoqi@0 1431 if (writer()->is_open()) {
aoqi@0 1432 if (is_segmented_dump()) {
aoqi@0 1433 writer()->write_u1(HPROF_HEAP_DUMP_SEGMENT);
aoqi@0 1434 } else {
aoqi@0 1435 writer()->write_u1(HPROF_HEAP_DUMP);
aoqi@0 1436 }
aoqi@0 1437 writer()->write_u4(0); // current ticks
aoqi@0 1438
aoqi@0 1439 // record the starting position for the dump (its length will be fixed up later)
aoqi@0 1440 set_dump_start(writer()->current_offset());
aoqi@0 1441 writer()->write_u4(0);
aoqi@0 1442 }
aoqi@0 1443 }
aoqi@0 1444
aoqi@0 1445 // fixes up the length of the current dump record
aoqi@0 1446 void VM_HeapDumper::write_current_dump_record_length() {
aoqi@0 1447 if (writer()->is_open()) {
aoqi@0 1448 assert(dump_start() >= 0, "no dump start recorded");
aoqi@0 1449
aoqi@0 1450 // calculate the size of the dump record
aoqi@0 1451 jlong dump_end = writer()->current_offset();
aoqi@0 1452 jlong dump_len = (dump_end - dump_start() - 4);
aoqi@0 1453
aoqi@0 1454 // record length must fit in a u4
aoqi@0 1455 if (dump_len > (jlong)(4L*(jlong)G)) {
aoqi@0 1456 warning("record is too large");
aoqi@0 1457 }
aoqi@0 1458
aoqi@0 1459 // seek to the dump start and fix-up the length
aoqi@0 1460 writer()->seek_to_offset(dump_start());
aoqi@0 1461 writer()->write_u4((u4)dump_len);
aoqi@0 1462
aoqi@0 1463 // adjust the total size written to keep the bytes written correct.
aoqi@0 1464 writer()->adjust_bytes_written(-((long) sizeof(u4)));
aoqi@0 1465
aoqi@0 1466 // seek to dump end so we can continue
aoqi@0 1467 writer()->seek_to_offset(dump_end);
aoqi@0 1468
aoqi@0 1469 // no current dump record
aoqi@0 1470 set_dump_start((jlong)-1);
aoqi@0 1471 }
aoqi@0 1472 }
aoqi@0 1473
aoqi@0 1474 // used on a sub-record boundary to check if we need to start a
aoqi@0 1475 // new segment.
aoqi@0 1476 void VM_HeapDumper::check_segment_length() {
aoqi@0 1477 if (writer()->is_open()) {
aoqi@0 1478 if (is_segmented_dump()) {
aoqi@0 1479 // don't use current_offset that would be too expensive on a per record basis
aoqi@0 1480 jlong dump_end = writer()->bytes_written() + writer()->bytes_unwritten();
aoqi@0 1481 assert(dump_end == writer()->current_offset(), "checking");
aoqi@0 1482 jlong dump_len = (dump_end - dump_start() - 4);
aoqi@0 1483 assert(dump_len >= 0 && dump_len <= max_juint, "bad dump length");
aoqi@0 1484
aoqi@0 1485 if (dump_len > (jlong)HeapDumpSegmentSize) {
aoqi@0 1486 write_current_dump_record_length();
aoqi@0 1487 write_dump_header();
aoqi@0 1488 }
aoqi@0 1489 }
aoqi@0 1490 }
aoqi@0 1491 }
aoqi@0 1492
aoqi@0 1493 // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
aoqi@0 1494 // record in the case of a segmented heap dump)
aoqi@0 1495 void VM_HeapDumper::end_of_dump() {
aoqi@0 1496 if (writer()->is_open()) {
aoqi@0 1497 write_current_dump_record_length();
aoqi@0 1498
aoqi@0 1499 // for segmented dump we write the end record
aoqi@0 1500 if (is_segmented_dump()) {
aoqi@0 1501 writer()->write_u1(HPROF_HEAP_DUMP_END);
aoqi@0 1502 writer()->write_u4(0);
aoqi@0 1503 writer()->write_u4(0);
aoqi@0 1504 }
aoqi@0 1505 }
aoqi@0 1506 }
aoqi@0 1507
aoqi@0 1508 // marks sub-record boundary
aoqi@0 1509 void HeapObjectDumper::mark_end_of_record() {
aoqi@0 1510 dumper()->check_segment_length();
aoqi@0 1511 }
aoqi@0 1512
aoqi@0 1513 // writes a HPROF_LOAD_CLASS record for the class (and each of its
aoqi@0 1514 // array classes)
aoqi@0 1515 void VM_HeapDumper::do_load_class(Klass* k) {
aoqi@0 1516 static u4 class_serial_num = 0;
aoqi@0 1517
aoqi@0 1518 // len of HPROF_LOAD_CLASS record
aoqi@0 1519 u4 remaining = 2*oopSize + 2*sizeof(u4);
aoqi@0 1520
aoqi@0 1521 // write a HPROF_LOAD_CLASS for the class and each array class
aoqi@0 1522 do {
aoqi@0 1523 DumperSupport::write_header(writer(), HPROF_LOAD_CLASS, remaining);
aoqi@0 1524
aoqi@0 1525 // class serial number is just a number
aoqi@0 1526 writer()->write_u4(++class_serial_num);
aoqi@0 1527
aoqi@0 1528 // class ID
aoqi@0 1529 Klass* klass = k;
aoqi@0 1530 writer()->write_classID(klass);
aoqi@0 1531
aoqi@0 1532 // add the Klass* and class serial number pair
aoqi@0 1533 dumper()->add_class_serial_number(klass, class_serial_num);
aoqi@0 1534
aoqi@0 1535 writer()->write_u4(STACK_TRACE_ID);
aoqi@0 1536
aoqi@0 1537 // class name ID
aoqi@0 1538 Symbol* name = klass->name();
aoqi@0 1539 writer()->write_symbolID(name);
aoqi@0 1540
aoqi@0 1541 // write a LOAD_CLASS record for the array type (if it exists)
aoqi@0 1542 k = klass->array_klass_or_null();
aoqi@0 1543 } while (k != NULL);
aoqi@0 1544 }
aoqi@0 1545
aoqi@0 1546 // writes a HPROF_GC_CLASS_DUMP record for the given class
aoqi@0 1547 void VM_HeapDumper::do_class_dump(Klass* k) {
aoqi@0 1548 if (k->oop_is_instance()) {
aoqi@0 1549 DumperSupport::dump_class_and_array_classes(writer(), k);
aoqi@0 1550 }
aoqi@0 1551 }
aoqi@0 1552
aoqi@0 1553 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
aoqi@0 1554 // array (and each multi-dimensional array too)
aoqi@0 1555 void VM_HeapDumper::do_basic_type_array_class_dump(Klass* k) {
aoqi@0 1556 DumperSupport::dump_basic_type_array_class(writer(), k);
aoqi@0 1557 }
aoqi@0 1558
aoqi@0 1559 // Walk the stack of the given thread.
aoqi@0 1560 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local
aoqi@0 1561 // Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local
aoqi@0 1562 //
aoqi@0 1563 // It returns the number of Java frames in this thread stack
aoqi@0 1564 int VM_HeapDumper::do_thread(JavaThread* java_thread, u4 thread_serial_num) {
aoqi@0 1565 JNILocalsDumper blk(writer(), thread_serial_num);
aoqi@0 1566
aoqi@0 1567 oop threadObj = java_thread->threadObj();
aoqi@0 1568 assert(threadObj != NULL, "sanity check");
aoqi@0 1569
aoqi@0 1570 int stack_depth = 0;
aoqi@0 1571 if (java_thread->has_last_Java_frame()) {
aoqi@0 1572
aoqi@0 1573 // vframes are resource allocated
aoqi@0 1574 Thread* current_thread = Thread::current();
aoqi@0 1575 ResourceMark rm(current_thread);
aoqi@0 1576 HandleMark hm(current_thread);
aoqi@0 1577
aoqi@0 1578 RegisterMap reg_map(java_thread);
aoqi@0 1579 frame f = java_thread->last_frame();
aoqi@0 1580 vframe* vf = vframe::new_vframe(&f, &reg_map, java_thread);
aoqi@0 1581 frame* last_entry_frame = NULL;
aoqi@0 1582 int extra_frames = 0;
aoqi@0 1583
aoqi@0 1584 if (java_thread == _oome_thread && _oome_constructor != NULL) {
aoqi@0 1585 extra_frames++;
aoqi@0 1586 }
aoqi@0 1587 while (vf != NULL) {
aoqi@0 1588 blk.set_frame_number(stack_depth);
aoqi@0 1589 if (vf->is_java_frame()) {
aoqi@0 1590
aoqi@0 1591 // java frame (interpreted, compiled, ...)
aoqi@0 1592 javaVFrame *jvf = javaVFrame::cast(vf);
aoqi@0 1593 if (!(jvf->method()->is_native())) {
aoqi@0 1594 StackValueCollection* locals = jvf->locals();
aoqi@0 1595 for (int slot=0; slot<locals->size(); slot++) {
aoqi@0 1596 if (locals->at(slot)->type() == T_OBJECT) {
aoqi@0 1597 oop o = locals->obj_at(slot)();
aoqi@0 1598
aoqi@0 1599 if (o != NULL) {
aoqi@0 1600 writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME);
aoqi@0 1601 writer()->write_objectID(o);
aoqi@0 1602 writer()->write_u4(thread_serial_num);
aoqi@0 1603 writer()->write_u4((u4) (stack_depth + extra_frames));
aoqi@0 1604 }
aoqi@0 1605 }
aoqi@0 1606 }
aoqi@0 1607 } else {
aoqi@0 1608 // native frame
aoqi@0 1609 if (stack_depth == 0) {
aoqi@0 1610 // JNI locals for the top frame.
aoqi@0 1611 java_thread->active_handles()->oops_do(&blk);
aoqi@0 1612 } else {
aoqi@0 1613 if (last_entry_frame != NULL) {
aoqi@0 1614 // JNI locals for the entry frame
aoqi@0 1615 assert(last_entry_frame->is_entry_frame(), "checking");
aoqi@0 1616 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(&blk);
aoqi@0 1617 }
aoqi@0 1618 }
aoqi@0 1619 }
aoqi@0 1620 // increment only for Java frames
aoqi@0 1621 stack_depth++;
aoqi@0 1622 last_entry_frame = NULL;
aoqi@0 1623
aoqi@0 1624 } else {
aoqi@0 1625 // externalVFrame - if it's an entry frame then report any JNI locals
aoqi@0 1626 // as roots when we find the corresponding native javaVFrame
aoqi@0 1627 frame* fr = vf->frame_pointer();
aoqi@0 1628 assert(fr != NULL, "sanity check");
aoqi@0 1629 if (fr->is_entry_frame()) {
aoqi@0 1630 last_entry_frame = fr;
aoqi@0 1631 }
aoqi@0 1632 }
aoqi@0 1633 vf = vf->sender();
aoqi@0 1634 }
aoqi@0 1635 } else {
aoqi@0 1636 // no last java frame but there may be JNI locals
aoqi@0 1637 java_thread->active_handles()->oops_do(&blk);
aoqi@0 1638 }
aoqi@0 1639 return stack_depth;
aoqi@0 1640 }
aoqi@0 1641
aoqi@0 1642
aoqi@0 1643 // write a HPROF_GC_ROOT_THREAD_OBJ record for each java thread. Then walk
aoqi@0 1644 // the stack so that locals and JNI locals are dumped.
aoqi@0 1645 void VM_HeapDumper::do_threads() {
aoqi@0 1646 for (int i=0; i < _num_threads; i++) {
aoqi@0 1647 JavaThread* thread = _stack_traces[i]->thread();
aoqi@0 1648 oop threadObj = thread->threadObj();
aoqi@0 1649 u4 thread_serial_num = i+1;
aoqi@0 1650 u4 stack_serial_num = thread_serial_num + STACK_TRACE_ID;
aoqi@0 1651 writer()->write_u1(HPROF_GC_ROOT_THREAD_OBJ);
aoqi@0 1652 writer()->write_objectID(threadObj);
aoqi@0 1653 writer()->write_u4(thread_serial_num); // thread number
aoqi@0 1654 writer()->write_u4(stack_serial_num); // stack trace serial number
aoqi@0 1655 int num_frames = do_thread(thread, thread_serial_num);
aoqi@0 1656 assert(num_frames == _stack_traces[i]->get_stack_depth(),
aoqi@0 1657 "total number of Java frames not matched");
aoqi@0 1658 }
aoqi@0 1659 }
aoqi@0 1660
aoqi@0 1661
aoqi@0 1662 // The VM operation that dumps the heap. The dump consists of the following
aoqi@0 1663 // records:
aoqi@0 1664 //
aoqi@0 1665 // HPROF_HEADER
aoqi@0 1666 // [HPROF_UTF8]*
aoqi@0 1667 // [HPROF_LOAD_CLASS]*
aoqi@0 1668 // [[HPROF_FRAME]*|HPROF_TRACE]*
aoqi@0 1669 // [HPROF_GC_CLASS_DUMP]*
aoqi@0 1670 // HPROF_HEAP_DUMP
aoqi@0 1671 //
aoqi@0 1672 // The HPROF_TRACE records represent the stack traces where the heap dump
aoqi@0 1673 // is generated and a "dummy trace" record which does not include
aoqi@0 1674 // any frames. The dummy trace record is used to be referenced as the
aoqi@0 1675 // unknown object alloc site.
aoqi@0 1676 //
aoqi@0 1677 // The HPROF_HEAP_DUMP record has a length following by sub-records. To allow
aoqi@0 1678 // the heap dump be generated in a single pass we remember the position of
aoqi@0 1679 // the dump length and fix it up after all sub-records have been written.
aoqi@0 1680 // To generate the sub-records we iterate over the heap, writing
aoqi@0 1681 // HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP
aoqi@0 1682 // records as we go. Once that is done we write records for some of the GC
aoqi@0 1683 // roots.
aoqi@0 1684
aoqi@0 1685 void VM_HeapDumper::doit() {
aoqi@0 1686
aoqi@0 1687 HandleMark hm;
aoqi@0 1688 CollectedHeap* ch = Universe::heap();
aoqi@0 1689
aoqi@0 1690 ch->ensure_parsability(false); // must happen, even if collection does
aoqi@0 1691 // not happen (e.g. due to GC_locker)
aoqi@0 1692
aoqi@0 1693 if (_gc_before_heap_dump) {
aoqi@0 1694 if (GC_locker::is_active()) {
aoqi@0 1695 warning("GC locker is held; pre-heapdump GC was skipped");
aoqi@0 1696 } else {
aoqi@0 1697 ch->collect_as_vm_thread(GCCause::_heap_dump);
aoqi@0 1698 }
aoqi@0 1699 }
aoqi@0 1700
aoqi@0 1701 // At this point we should be the only dumper active, so
aoqi@0 1702 // the following should be safe.
aoqi@0 1703 set_global_dumper();
aoqi@0 1704 set_global_writer();
aoqi@0 1705
aoqi@0 1706 // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1
aoqi@0 1707 size_t used = ch->used();
aoqi@0 1708 const char* header;
aoqi@0 1709 if (used > (size_t)SegmentedHeapDumpThreshold) {
aoqi@0 1710 set_segmented_dump();
aoqi@0 1711 header = "JAVA PROFILE 1.0.2";
aoqi@0 1712 } else {
aoqi@0 1713 header = "JAVA PROFILE 1.0.1";
aoqi@0 1714 }
aoqi@0 1715
aoqi@0 1716 // header is few bytes long - no chance to overflow int
aoqi@0 1717 writer()->write_raw((void*)header, (int)strlen(header));
aoqi@0 1718 writer()->write_u1(0); // terminator
aoqi@0 1719 writer()->write_u4(oopSize);
aoqi@0 1720 writer()->write_u8(os::javaTimeMillis());
aoqi@0 1721
aoqi@0 1722 // HPROF_UTF8 records
aoqi@0 1723 SymbolTableDumper sym_dumper(writer());
aoqi@0 1724 SymbolTable::symbols_do(&sym_dumper);
aoqi@0 1725
aoqi@0 1726 // write HPROF_LOAD_CLASS records
aoqi@0 1727 ClassLoaderDataGraph::classes_do(&do_load_class);
aoqi@0 1728 Universe::basic_type_classes_do(&do_load_class);
aoqi@0 1729
aoqi@0 1730 // write HPROF_FRAME and HPROF_TRACE records
aoqi@0 1731 // this must be called after _klass_map is built when iterating the classes above.
aoqi@0 1732 dump_stack_traces();
aoqi@0 1733
aoqi@0 1734 // write HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT
aoqi@0 1735 write_dump_header();
aoqi@0 1736
aoqi@0 1737 // Writes HPROF_GC_CLASS_DUMP records
aoqi@0 1738 ClassLoaderDataGraph::classes_do(&do_class_dump);
aoqi@0 1739 Universe::basic_type_classes_do(&do_basic_type_array_class_dump);
aoqi@0 1740 check_segment_length();
aoqi@0 1741
aoqi@0 1742 // writes HPROF_GC_INSTANCE_DUMP records.
aoqi@0 1743 // After each sub-record is written check_segment_length will be invoked. When
aoqi@0 1744 // generated a segmented heap dump this allows us to check if the current
aoqi@0 1745 // segment exceeds a threshold and if so, then a new segment is started.
aoqi@0 1746 // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
aoqi@0 1747 // of the heap dump.
aoqi@0 1748 HeapObjectDumper obj_dumper(this, writer());
aoqi@0 1749 Universe::heap()->safe_object_iterate(&obj_dumper);
aoqi@0 1750
aoqi@0 1751 // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
aoqi@0 1752 do_threads();
aoqi@0 1753 check_segment_length();
aoqi@0 1754
aoqi@0 1755 // HPROF_GC_ROOT_MONITOR_USED
aoqi@0 1756 MonitorUsedDumper mon_dumper(writer());
aoqi@0 1757 ObjectSynchronizer::oops_do(&mon_dumper);
aoqi@0 1758 check_segment_length();
aoqi@0 1759
aoqi@0 1760 // HPROF_GC_ROOT_JNI_GLOBAL
aoqi@0 1761 JNIGlobalsDumper jni_dumper(writer());
aoqi@0 1762 JNIHandles::oops_do(&jni_dumper);
aoqi@0 1763 check_segment_length();
aoqi@0 1764
aoqi@0 1765 // HPROF_GC_ROOT_STICKY_CLASS
aoqi@0 1766 StickyClassDumper class_dumper(writer());
aoqi@0 1767 SystemDictionary::always_strong_classes_do(&class_dumper);
aoqi@0 1768
aoqi@0 1769 // fixes up the length of the dump record. In the case of a segmented
aoqi@0 1770 // heap then the HPROF_HEAP_DUMP_END record is also written.
aoqi@0 1771 end_of_dump();
aoqi@0 1772
aoqi@0 1773 // Now we clear the global variables, so that a future dumper might run.
aoqi@0 1774 clear_global_dumper();
aoqi@0 1775 clear_global_writer();
aoqi@0 1776 }
aoqi@0 1777
aoqi@0 1778 void VM_HeapDumper::dump_stack_traces() {
aoqi@0 1779 // write a HPROF_TRACE record without any frames to be referenced as object alloc sites
aoqi@0 1780 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));
aoqi@0 1781 writer()->write_u4((u4) STACK_TRACE_ID);
aoqi@0 1782 writer()->write_u4(0); // thread number
aoqi@0 1783 writer()->write_u4(0); // frame count
aoqi@0 1784
aoqi@0 1785 _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);
aoqi@0 1786 int frame_serial_num = 0;
aoqi@0 1787 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
aoqi@0 1788 oop threadObj = thread->threadObj();
aoqi@0 1789 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
aoqi@0 1790 // dump thread stack trace
aoqi@0 1791 ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false);
aoqi@0 1792 stack_trace->dump_stack_at_safepoint(-1);
aoqi@0 1793 _stack_traces[_num_threads++] = stack_trace;
aoqi@0 1794
aoqi@0 1795 // write HPROF_FRAME records for this thread's stack trace
aoqi@0 1796 int depth = stack_trace->get_stack_depth();
aoqi@0 1797 int thread_frame_start = frame_serial_num;
aoqi@0 1798 int extra_frames = 0;
aoqi@0 1799 // write fake frame that makes it look like the thread, which caused OOME,
aoqi@0 1800 // is in the OutOfMemoryError zero-parameter constructor
aoqi@0 1801 if (thread == _oome_thread && _oome_constructor != NULL) {
aoqi@0 1802 int oome_serial_num = _klass_map->find(_oome_constructor->method_holder());
aoqi@0 1803 // the class serial number starts from 1
aoqi@0 1804 assert(oome_serial_num > 0, "OutOfMemoryError class not found");
aoqi@0 1805 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, oome_serial_num,
aoqi@0 1806 _oome_constructor, 0);
aoqi@0 1807 extra_frames++;
aoqi@0 1808 }
aoqi@0 1809 for (int j=0; j < depth; j++) {
aoqi@0 1810 StackFrameInfo* frame = stack_trace->stack_frame_at(j);
aoqi@0 1811 Method* m = frame->method();
aoqi@0 1812 int class_serial_num = _klass_map->find(m->method_holder());
aoqi@0 1813 // the class serial number starts from 1
aoqi@0 1814 assert(class_serial_num > 0, "class not found");
aoqi@0 1815 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci());
aoqi@0 1816 }
aoqi@0 1817 depth += extra_frames;
aoqi@0 1818
aoqi@0 1819 // write HPROF_TRACE record for one thread
aoqi@0 1820 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4) + depth*oopSize);
aoqi@0 1821 int stack_serial_num = _num_threads + STACK_TRACE_ID;
aoqi@0 1822 writer()->write_u4(stack_serial_num); // stack trace serial number
aoqi@0 1823 writer()->write_u4((u4) _num_threads); // thread serial number
aoqi@0 1824 writer()->write_u4(depth); // frame count
aoqi@0 1825 for (int j=1; j <= depth; j++) {
aoqi@0 1826 writer()->write_id(thread_frame_start + j);
aoqi@0 1827 }
aoqi@0 1828 }
aoqi@0 1829 }
aoqi@0 1830 }
aoqi@0 1831
aoqi@0 1832 // dump the heap to given path.
aoqi@0 1833 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
aoqi@0 1834 int HeapDumper::dump(const char* path) {
aoqi@0 1835 assert(path != NULL && strlen(path) > 0, "path missing");
aoqi@0 1836
aoqi@0 1837 // print message in interactive case
aoqi@0 1838 if (print_to_tty()) {
aoqi@0 1839 tty->print_cr("Dumping heap to %s ...", path);
aoqi@0 1840 timer()->start();
aoqi@0 1841 }
aoqi@0 1842
aoqi@0 1843 // create the dump writer. If the file can be opened then bail
aoqi@0 1844 DumpWriter writer(path);
aoqi@0 1845 if (!writer.is_open()) {
aoqi@0 1846 set_error(writer.error());
aoqi@0 1847 if (print_to_tty()) {
aoqi@0 1848 tty->print_cr("Unable to create %s: %s", path,
aoqi@0 1849 (error() != NULL) ? error() : "reason unknown");
aoqi@0 1850 }
aoqi@0 1851 return -1;
aoqi@0 1852 }
aoqi@0 1853
aoqi@0 1854 // generate the dump
aoqi@0 1855 VM_HeapDumper dumper(&writer, _gc_before_heap_dump, _oome);
aoqi@0 1856 if (Thread::current()->is_VM_thread()) {
aoqi@0 1857 assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint");
aoqi@0 1858 dumper.doit();
aoqi@0 1859 } else {
aoqi@0 1860 VMThread::execute(&dumper);
aoqi@0 1861 }
aoqi@0 1862
aoqi@0 1863 // close dump file and record any error that the writer may have encountered
aoqi@0 1864 writer.close();
aoqi@0 1865 set_error(writer.error());
aoqi@0 1866
aoqi@0 1867 // print message in interactive case
aoqi@0 1868 if (print_to_tty()) {
aoqi@0 1869 timer()->stop();
aoqi@0 1870 if (error() == NULL) {
aoqi@0 1871 char msg[256];
aoqi@0 1872 sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]",
aoqi@0 1873 JLONG_FORMAT, timer()->seconds());
aoqi@0 1874 PRAGMA_DIAG_PUSH
aoqi@0 1875 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
aoqi@0 1876 tty->print_cr(msg, writer.bytes_written());
aoqi@0 1877 PRAGMA_DIAG_POP
aoqi@0 1878 } else {
aoqi@0 1879 tty->print_cr("Dump file is incomplete: %s", writer.error());
aoqi@0 1880 }
aoqi@0 1881 }
aoqi@0 1882
aoqi@0 1883 return (writer.error() == NULL) ? 0 : -1;
aoqi@0 1884 }
aoqi@0 1885
aoqi@0 1886 // stop timer (if still active), and free any error string we might be holding
aoqi@0 1887 HeapDumper::~HeapDumper() {
aoqi@0 1888 if (timer()->is_active()) {
aoqi@0 1889 timer()->stop();
aoqi@0 1890 }
aoqi@0 1891 set_error(NULL);
aoqi@0 1892 }
aoqi@0 1893
aoqi@0 1894
aoqi@0 1895 // returns the error string (resource allocated), or NULL
aoqi@0 1896 char* HeapDumper::error_as_C_string() const {
aoqi@0 1897 if (error() != NULL) {
aoqi@0 1898 char* str = NEW_RESOURCE_ARRAY(char, strlen(error())+1);
aoqi@0 1899 strcpy(str, error());
aoqi@0 1900 return str;
aoqi@0 1901 } else {
aoqi@0 1902 return NULL;
aoqi@0 1903 }
aoqi@0 1904 }
aoqi@0 1905
aoqi@0 1906 // set the error string
aoqi@0 1907 void HeapDumper::set_error(char* error) {
aoqi@0 1908 if (_error != NULL) {
aoqi@0 1909 os::free(_error);
aoqi@0 1910 }
aoqi@0 1911 if (error == NULL) {
aoqi@0 1912 _error = NULL;
aoqi@0 1913 } else {
aoqi@0 1914 _error = os::strdup(error);
aoqi@0 1915 assert(_error != NULL, "allocation failure");
aoqi@0 1916 }
aoqi@0 1917 }
aoqi@0 1918
aoqi@0 1919 // Called by out-of-memory error reporting by a single Java thread
aoqi@0 1920 // outside of a JVM safepoint
aoqi@0 1921 void HeapDumper::dump_heap_from_oome() {
aoqi@0 1922 HeapDumper::dump_heap(true);
aoqi@0 1923 }
aoqi@0 1924
aoqi@0 1925 // Called by error reporting by a single Java thread outside of a JVM safepoint,
aoqi@0 1926 // or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various
aoqi@0 1927 // callers are strictly serialized and guaranteed not to interfere below. For more
aoqi@0 1928 // general use, however, this method will need modification to prevent
aoqi@0 1929 // inteference when updating the static variables base_path and dump_file_seq below.
aoqi@0 1930 void HeapDumper::dump_heap() {
aoqi@0 1931 HeapDumper::dump_heap(false);
aoqi@0 1932 }
aoqi@0 1933
aoqi@0 1934 void HeapDumper::dump_heap(bool oome) {
aoqi@0 1935 static char base_path[JVM_MAXPATHLEN] = {'\0'};
aoqi@0 1936 static uint dump_file_seq = 0;
aoqi@0 1937 char* my_path;
aoqi@0 1938 const int max_digit_chars = 20;
aoqi@0 1939
aoqi@0 1940 const char* dump_file_name = "java_pid";
aoqi@0 1941 const char* dump_file_ext = ".hprof";
aoqi@0 1942
aoqi@0 1943 // The dump file defaults to java_pid<pid>.hprof in the current working
aoqi@0 1944 // directory. HeapDumpPath=<file> can be used to specify an alternative
aoqi@0 1945 // dump file name or a directory where dump file is created.
aoqi@0 1946 if (dump_file_seq == 0) { // first time in, we initialize base_path
aoqi@0 1947 // Calculate potentially longest base path and check if we have enough
aoqi@0 1948 // allocated statically.
aoqi@0 1949 const size_t total_length =
aoqi@0 1950 (HeapDumpPath == NULL ? 0 : strlen(HeapDumpPath)) +
aoqi@0 1951 strlen(os::file_separator()) + max_digit_chars +
aoqi@0 1952 strlen(dump_file_name) + strlen(dump_file_ext) + 1;
aoqi@0 1953 if (total_length > sizeof(base_path)) {
aoqi@0 1954 warning("Cannot create heap dump file. HeapDumpPath is too long.");
aoqi@0 1955 return;
aoqi@0 1956 }
aoqi@0 1957
aoqi@0 1958 bool use_default_filename = true;
aoqi@0 1959 if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
aoqi@0 1960 // HeapDumpPath=<file> not specified
aoqi@0 1961 } else {
aoqi@0 1962 strncpy(base_path, HeapDumpPath, sizeof(base_path));
aoqi@0 1963 // check if the path is a directory (must exist)
aoqi@0 1964 DIR* dir = os::opendir(base_path);
aoqi@0 1965 if (dir == NULL) {
aoqi@0 1966 use_default_filename = false;
aoqi@0 1967 } else {
aoqi@0 1968 // HeapDumpPath specified a directory. We append a file separator
aoqi@0 1969 // (if needed).
aoqi@0 1970 os::closedir(dir);
aoqi@0 1971 size_t fs_len = strlen(os::file_separator());
aoqi@0 1972 if (strlen(base_path) >= fs_len) {
aoqi@0 1973 char* end = base_path;
aoqi@0 1974 end += (strlen(base_path) - fs_len);
aoqi@0 1975 if (strcmp(end, os::file_separator()) != 0) {
aoqi@0 1976 strcat(base_path, os::file_separator());
aoqi@0 1977 }
aoqi@0 1978 }
aoqi@0 1979 }
aoqi@0 1980 }
aoqi@0 1981 // If HeapDumpPath wasn't a file name then we append the default name
aoqi@0 1982 if (use_default_filename) {
aoqi@0 1983 const size_t dlen = strlen(base_path); // if heap dump dir specified
aoqi@0 1984 jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s",
aoqi@0 1985 dump_file_name, os::current_process_id(), dump_file_ext);
aoqi@0 1986 }
aoqi@0 1987 const size_t len = strlen(base_path) + 1;
aoqi@0 1988 my_path = (char*)os::malloc(len, mtInternal);
aoqi@0 1989 if (my_path == NULL) {
aoqi@0 1990 warning("Cannot create heap dump file. Out of system memory.");
aoqi@0 1991 return;
aoqi@0 1992 }
aoqi@0 1993 strncpy(my_path, base_path, len);
aoqi@0 1994 } else {
aoqi@0 1995 // Append a sequence number id for dumps following the first
aoqi@0 1996 const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0
aoqi@0 1997 my_path = (char*)os::malloc(len, mtInternal);
aoqi@0 1998 if (my_path == NULL) {
aoqi@0 1999 warning("Cannot create heap dump file. Out of system memory.");
aoqi@0 2000 return;
aoqi@0 2001 }
aoqi@0 2002 jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq);
aoqi@0 2003 }
aoqi@0 2004 dump_file_seq++; // increment seq number for next time we dump
aoqi@0 2005
aoqi@0 2006 HeapDumper dumper(false /* no GC before heap dump */,
aoqi@0 2007 true /* send to tty */,
aoqi@0 2008 oome /* pass along out-of-memory-error flag */);
aoqi@0 2009 dumper.dump(my_path);
aoqi@0 2010 os::free(my_path);
aoqi@0 2011 }

mercurial