src/share/vm/services/heapDumper.cpp

Thu, 24 May 2018 17:06:56 +0800

author
aoqi
date
Thu, 24 May 2018 17:06:56 +0800
changeset 8604
04d83ba48607
parent 8420
b5c3e9670fa0
parent 6876
710a3c8b516e
child 9448
73d689add964
permissions
-rw-r--r--

Merge

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)
aeriksso@8317 379 julong _bytes_written; // number of byte written to dump file
aoqi@0 380
aoqi@0 381 char* _buffer; // internal buffer
aeriksso@8317 382 size_t _size;
aeriksso@8317 383 size_t _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; }
aeriksso@8317 391 size_t buffer_size() const { return _size; }
aeriksso@8317 392 size_t position() const { return _pos; }
aeriksso@8317 393 void set_position(size_t 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
aeriksso@8317 398 void write_internal(void* s, size_t 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
aeriksso@8317 409 julong 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)
aeriksso@8317 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
aeriksso@8317 416 size_t bytes_unwritten() const { return 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
aeriksso@8317 424 void write_raw(void* s, size_t 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
aeriksso@8317 477 void DumpWriter::write_internal(void* s, size_t len) {
aoqi@0 478 if (is_open()) {
aeriksso@8317 479 const char* pos = (char*)s;
aeriksso@8317 480 ssize_t n = 0;
aeriksso@8317 481 while (len > 0) {
aeriksso@8317 482 uint tmp = (uint)MIN2(len, (size_t)UINT_MAX);
aeriksso@8420 483 n = ::write(file_descriptor(), pos, tmp);
aeriksso@8317 484
aoqi@0 485 if (n < 0) {
aoqi@0 486 set_error(strerror(errno));
aeriksso@8420 487 ::close(file_descriptor());
aeriksso@8317 488 set_file_descriptor(-1);
aeriksso@8317 489 return;
aoqi@0 490 }
aeriksso@8317 491
drchase@6680 492 _bytes_written += n;
aeriksso@8317 493 pos += n;
aeriksso@8317 494 len -= n;
aoqi@0 495 }
aoqi@0 496 }
aoqi@0 497 }
aoqi@0 498
aoqi@0 499 // write raw bytes
aeriksso@8317 500 void DumpWriter::write_raw(void* s, size_t len) {
aoqi@0 501 if (is_open()) {
aeriksso@8317 502 // flush buffer to make room
aeriksso@8317 503 if ((position() + len) >= buffer_size()) {
aoqi@0 504 flush();
aoqi@0 505 }
aoqi@0 506
aoqi@0 507 // buffer not available or too big to buffer it
aoqi@0 508 if ((buffer() == NULL) || (len >= buffer_size())) {
aoqi@0 509 write_internal(s, len);
aoqi@0 510 } else {
aoqi@0 511 // Should optimize this for u1/u2/u4/u8 sizes.
aoqi@0 512 memcpy(buffer() + position(), s, len);
aoqi@0 513 set_position(position() + len);
aoqi@0 514 }
aoqi@0 515 }
aoqi@0 516 }
aoqi@0 517
aoqi@0 518 // flush any buffered bytes to the file
aoqi@0 519 void DumpWriter::flush() {
aoqi@0 520 if (is_open() && position() > 0) {
aoqi@0 521 write_internal(buffer(), position());
aoqi@0 522 set_position(0);
aoqi@0 523 }
aoqi@0 524 }
aoqi@0 525
aoqi@0 526 jlong DumpWriter::current_offset() {
aoqi@0 527 if (is_open()) {
aoqi@0 528 // the offset is the file offset plus whatever we have buffered
aoqi@0 529 jlong offset = os::current_file_offset(file_descriptor());
aoqi@0 530 assert(offset >= 0, "lseek failed");
aeriksso@8317 531 return offset + position();
aoqi@0 532 } else {
aoqi@0 533 return (jlong)-1;
aoqi@0 534 }
aoqi@0 535 }
aoqi@0 536
aoqi@0 537 void DumpWriter::seek_to_offset(jlong off) {
aoqi@0 538 assert(off >= 0, "bad offset");
aoqi@0 539
aoqi@0 540 // need to flush before seeking
aoqi@0 541 flush();
aoqi@0 542
aoqi@0 543 // may be closed due to I/O error
aoqi@0 544 if (is_open()) {
aoqi@0 545 jlong n = os::seek_to_file_offset(file_descriptor(), off);
aoqi@0 546 assert(n >= 0, "lseek failed");
aoqi@0 547 }
aoqi@0 548 }
aoqi@0 549
aoqi@0 550 void DumpWriter::write_u2(u2 x) {
aoqi@0 551 u2 v;
aoqi@0 552 Bytes::put_Java_u2((address)&v, x);
aoqi@0 553 write_raw((void*)&v, 2);
aoqi@0 554 }
aoqi@0 555
aoqi@0 556 void DumpWriter::write_u4(u4 x) {
aoqi@0 557 u4 v;
aoqi@0 558 Bytes::put_Java_u4((address)&v, x);
aoqi@0 559 write_raw((void*)&v, 4);
aoqi@0 560 }
aoqi@0 561
aoqi@0 562 void DumpWriter::write_u8(u8 x) {
aoqi@0 563 u8 v;
aoqi@0 564 Bytes::put_Java_u8((address)&v, x);
aoqi@0 565 write_raw((void*)&v, 8);
aoqi@0 566 }
aoqi@0 567
aoqi@0 568 void DumpWriter::write_objectID(oop o) {
aoqi@0 569 address a = (address)o;
aoqi@0 570 #ifdef _LP64
aoqi@0 571 write_u8((u8)a);
aoqi@0 572 #else
aoqi@0 573 write_u4((u4)a);
aoqi@0 574 #endif
aoqi@0 575 }
aoqi@0 576
aoqi@0 577 void DumpWriter::write_symbolID(Symbol* s) {
aoqi@0 578 address a = (address)((uintptr_t)s);
aoqi@0 579 #ifdef _LP64
aoqi@0 580 write_u8((u8)a);
aoqi@0 581 #else
aoqi@0 582 write_u4((u4)a);
aoqi@0 583 #endif
aoqi@0 584 }
aoqi@0 585
aoqi@0 586 void DumpWriter::write_id(u4 x) {
aoqi@0 587 #ifdef _LP64
aoqi@0 588 write_u8((u8) x);
aoqi@0 589 #else
aoqi@0 590 write_u4(x);
aoqi@0 591 #endif
aoqi@0 592 }
aoqi@0 593
aoqi@0 594 // We use java mirror as the class ID
aoqi@0 595 void DumpWriter::write_classID(Klass* k) {
aoqi@0 596 write_objectID(k->java_mirror());
aoqi@0 597 }
aoqi@0 598
aoqi@0 599
aoqi@0 600
aoqi@0 601 // Support class with a collection of functions used when dumping the heap
aoqi@0 602
aoqi@0 603 class DumperSupport : AllStatic {
aoqi@0 604 public:
aoqi@0 605
aoqi@0 606 // write a header of the given type
aoqi@0 607 static void write_header(DumpWriter* writer, hprofTag tag, u4 len);
aoqi@0 608
aoqi@0 609 // returns hprof tag for the given type signature
aoqi@0 610 static hprofTag sig2tag(Symbol* sig);
aoqi@0 611 // returns hprof tag for the given basic type
aoqi@0 612 static hprofTag type2tag(BasicType type);
aoqi@0 613
aoqi@0 614 // returns the size of the instance of the given class
aoqi@0 615 static u4 instance_size(Klass* k);
aoqi@0 616
aoqi@0 617 // dump a jfloat
aoqi@0 618 static void dump_float(DumpWriter* writer, jfloat f);
aoqi@0 619 // dump a jdouble
aoqi@0 620 static void dump_double(DumpWriter* writer, jdouble d);
aoqi@0 621 // dumps the raw value of the given field
aoqi@0 622 static void dump_field_value(DumpWriter* writer, char type, address addr);
aoqi@0 623 // dumps static fields of the given class
aoqi@0 624 static void dump_static_fields(DumpWriter* writer, Klass* k);
aoqi@0 625 // dump the raw values of the instance fields of the given object
aoqi@0 626 static void dump_instance_fields(DumpWriter* writer, oop o);
aoqi@0 627 // dumps the definition of the instance fields for a given class
aoqi@0 628 static void dump_instance_field_descriptors(DumpWriter* writer, Klass* k);
aoqi@0 629 // creates HPROF_GC_INSTANCE_DUMP record for the given object
aoqi@0 630 static void dump_instance(DumpWriter* writer, oop o);
aoqi@0 631 // creates HPROF_GC_CLASS_DUMP record for the given class and each of its
aoqi@0 632 // array classes
aoqi@0 633 static void dump_class_and_array_classes(DumpWriter* writer, Klass* k);
aoqi@0 634 // creates HPROF_GC_CLASS_DUMP record for a given primitive array
aoqi@0 635 // class (and each multi-dimensional array class too)
aoqi@0 636 static void dump_basic_type_array_class(DumpWriter* writer, Klass* k);
aoqi@0 637
aoqi@0 638 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
aoqi@0 639 static void dump_object_array(DumpWriter* writer, objArrayOop array);
aoqi@0 640 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
aoqi@0 641 static void dump_prim_array(DumpWriter* writer, typeArrayOop array);
aoqi@0 642 // create HPROF_FRAME record for the given method and bci
aoqi@0 643 static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci);
aoqi@0 644 };
aoqi@0 645
aoqi@0 646 // write a header of the given type
aoqi@0 647 void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) {
aoqi@0 648 writer->write_u1((u1)tag);
aoqi@0 649 writer->write_u4(0); // current ticks
aoqi@0 650 writer->write_u4(len);
aoqi@0 651 }
aoqi@0 652
aoqi@0 653 // returns hprof tag for the given type signature
aoqi@0 654 hprofTag DumperSupport::sig2tag(Symbol* sig) {
aoqi@0 655 switch (sig->byte_at(0)) {
aoqi@0 656 case JVM_SIGNATURE_CLASS : return HPROF_NORMAL_OBJECT;
aoqi@0 657 case JVM_SIGNATURE_ARRAY : return HPROF_NORMAL_OBJECT;
aoqi@0 658 case JVM_SIGNATURE_BYTE : return HPROF_BYTE;
aoqi@0 659 case JVM_SIGNATURE_CHAR : return HPROF_CHAR;
aoqi@0 660 case JVM_SIGNATURE_FLOAT : return HPROF_FLOAT;
aoqi@0 661 case JVM_SIGNATURE_DOUBLE : return HPROF_DOUBLE;
aoqi@0 662 case JVM_SIGNATURE_INT : return HPROF_INT;
aoqi@0 663 case JVM_SIGNATURE_LONG : return HPROF_LONG;
aoqi@0 664 case JVM_SIGNATURE_SHORT : return HPROF_SHORT;
aoqi@0 665 case JVM_SIGNATURE_BOOLEAN : return HPROF_BOOLEAN;
aoqi@0 666 default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
aoqi@0 667 }
aoqi@0 668 }
aoqi@0 669
aoqi@0 670 hprofTag DumperSupport::type2tag(BasicType type) {
aoqi@0 671 switch (type) {
aoqi@0 672 case T_BYTE : return HPROF_BYTE;
aoqi@0 673 case T_CHAR : return HPROF_CHAR;
aoqi@0 674 case T_FLOAT : return HPROF_FLOAT;
aoqi@0 675 case T_DOUBLE : return HPROF_DOUBLE;
aoqi@0 676 case T_INT : return HPROF_INT;
aoqi@0 677 case T_LONG : return HPROF_LONG;
aoqi@0 678 case T_SHORT : return HPROF_SHORT;
aoqi@0 679 case T_BOOLEAN : return HPROF_BOOLEAN;
aoqi@0 680 default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;
aoqi@0 681 }
aoqi@0 682 }
aoqi@0 683
aoqi@0 684 // dump a jfloat
aoqi@0 685 void DumperSupport::dump_float(DumpWriter* writer, jfloat f) {
aoqi@0 686 if (g_isnan(f)) {
aoqi@0 687 writer->write_u4(0x7fc00000); // collapsing NaNs
aoqi@0 688 } else {
aoqi@0 689 union {
aoqi@0 690 int i;
aoqi@0 691 float f;
aoqi@0 692 } u;
aoqi@0 693 u.f = (float)f;
aoqi@0 694 writer->write_u4((u4)u.i);
aoqi@0 695 }
aoqi@0 696 }
aoqi@0 697
aoqi@0 698 // dump a jdouble
aoqi@0 699 void DumperSupport::dump_double(DumpWriter* writer, jdouble d) {
aoqi@0 700 union {
aoqi@0 701 jlong l;
aoqi@0 702 double d;
aoqi@0 703 } u;
aoqi@0 704 if (g_isnan(d)) { // collapsing NaNs
aoqi@0 705 u.l = (jlong)(0x7ff80000);
aoqi@0 706 u.l = (u.l << 32);
aoqi@0 707 } else {
aoqi@0 708 u.d = (double)d;
aoqi@0 709 }
aoqi@0 710 writer->write_u8((u8)u.l);
aoqi@0 711 }
aoqi@0 712
aoqi@0 713 // dumps the raw value of the given field
aoqi@0 714 void DumperSupport::dump_field_value(DumpWriter* writer, char type, address addr) {
aoqi@0 715 switch (type) {
aoqi@0 716 case JVM_SIGNATURE_CLASS :
aoqi@0 717 case JVM_SIGNATURE_ARRAY : {
aoqi@0 718 oop o;
aoqi@0 719 if (UseCompressedOops) {
aoqi@0 720 o = oopDesc::load_decode_heap_oop((narrowOop*)addr);
aoqi@0 721 } else {
aoqi@0 722 o = oopDesc::load_decode_heap_oop((oop*)addr);
aoqi@0 723 }
aoqi@0 724
aoqi@0 725 // reflection and sun.misc.Unsafe classes may have a reference to a
aoqi@0 726 // Klass* so filter it out.
aoqi@0 727 assert(o->is_oop_or_null(), "should always be an oop");
aoqi@0 728 writer->write_objectID(o);
aoqi@0 729 break;
aoqi@0 730 }
aoqi@0 731 case JVM_SIGNATURE_BYTE : {
aoqi@0 732 jbyte* b = (jbyte*)addr;
aoqi@0 733 writer->write_u1((u1)*b);
aoqi@0 734 break;
aoqi@0 735 }
aoqi@0 736 case JVM_SIGNATURE_CHAR : {
aoqi@0 737 jchar* c = (jchar*)addr;
aoqi@0 738 writer->write_u2((u2)*c);
aoqi@0 739 break;
aoqi@0 740 }
aoqi@0 741 case JVM_SIGNATURE_SHORT : {
aoqi@0 742 jshort* s = (jshort*)addr;
aoqi@0 743 writer->write_u2((u2)*s);
aoqi@0 744 break;
aoqi@0 745 }
aoqi@0 746 case JVM_SIGNATURE_FLOAT : {
aoqi@0 747 jfloat* f = (jfloat*)addr;
aoqi@0 748 dump_float(writer, *f);
aoqi@0 749 break;
aoqi@0 750 }
aoqi@0 751 case JVM_SIGNATURE_DOUBLE : {
aoqi@0 752 jdouble* f = (jdouble*)addr;
aoqi@0 753 dump_double(writer, *f);
aoqi@0 754 break;
aoqi@0 755 }
aoqi@0 756 case JVM_SIGNATURE_INT : {
aoqi@0 757 jint* i = (jint*)addr;
aoqi@0 758 writer->write_u4((u4)*i);
aoqi@0 759 break;
aoqi@0 760 }
aoqi@0 761 case JVM_SIGNATURE_LONG : {
aoqi@0 762 jlong* l = (jlong*)addr;
aoqi@0 763 writer->write_u8((u8)*l);
aoqi@0 764 break;
aoqi@0 765 }
aoqi@0 766 case JVM_SIGNATURE_BOOLEAN : {
aoqi@0 767 jboolean* b = (jboolean*)addr;
aoqi@0 768 writer->write_u1((u1)*b);
aoqi@0 769 break;
aoqi@0 770 }
aoqi@0 771 default : ShouldNotReachHere();
aoqi@0 772 }
aoqi@0 773 }
aoqi@0 774
aoqi@0 775 // returns the size of the instance of the given class
aoqi@0 776 u4 DumperSupport::instance_size(Klass* k) {
aoqi@0 777 HandleMark hm;
aoqi@0 778 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
aoqi@0 779
aeriksso@8317 780 u4 size = 0;
aoqi@0 781
aoqi@0 782 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
aoqi@0 783 if (!fld.access_flags().is_static()) {
aoqi@0 784 Symbol* sig = fld.signature();
aoqi@0 785 switch (sig->byte_at(0)) {
aoqi@0 786 case JVM_SIGNATURE_CLASS :
aoqi@0 787 case JVM_SIGNATURE_ARRAY : size += oopSize; break;
aoqi@0 788
aoqi@0 789 case JVM_SIGNATURE_BYTE :
aoqi@0 790 case JVM_SIGNATURE_BOOLEAN : size += 1; break;
aoqi@0 791
aoqi@0 792 case JVM_SIGNATURE_CHAR :
aoqi@0 793 case JVM_SIGNATURE_SHORT : size += 2; break;
aoqi@0 794
aoqi@0 795 case JVM_SIGNATURE_INT :
aoqi@0 796 case JVM_SIGNATURE_FLOAT : size += 4; break;
aoqi@0 797
aoqi@0 798 case JVM_SIGNATURE_LONG :
aoqi@0 799 case JVM_SIGNATURE_DOUBLE : size += 8; break;
aoqi@0 800
aoqi@0 801 default : ShouldNotReachHere();
aoqi@0 802 }
aoqi@0 803 }
aoqi@0 804 }
aeriksso@8317 805 return size;
aoqi@0 806 }
aoqi@0 807
aoqi@0 808 // dumps static fields of the given class
aoqi@0 809 void DumperSupport::dump_static_fields(DumpWriter* writer, Klass* k) {
aoqi@0 810 HandleMark hm;
aoqi@0 811 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
aoqi@0 812
aoqi@0 813 // pass 1 - count the static fields
aoqi@0 814 u2 field_count = 0;
aoqi@0 815 for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
aoqi@0 816 if (fldc.access_flags().is_static()) field_count++;
aoqi@0 817 }
aoqi@0 818
aoqi@0 819 writer->write_u2(field_count);
aoqi@0 820
aoqi@0 821 // pass 2 - dump the field descriptors and raw values
aoqi@0 822 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {
aoqi@0 823 if (fld.access_flags().is_static()) {
aoqi@0 824 Symbol* sig = fld.signature();
aoqi@0 825
aoqi@0 826 writer->write_symbolID(fld.name()); // name
aoqi@0 827 writer->write_u1(sig2tag(sig)); // type
aoqi@0 828
aoqi@0 829 // value
aoqi@0 830 int offset = fld.offset();
aoqi@0 831 address addr = (address)ikh->java_mirror() + offset;
aoqi@0 832
aoqi@0 833 dump_field_value(writer, sig->byte_at(0), addr);
aoqi@0 834 }
aoqi@0 835 }
aoqi@0 836 }
aoqi@0 837
aoqi@0 838 // dump the raw values of the instance fields of the given object
aoqi@0 839 void DumperSupport::dump_instance_fields(DumpWriter* writer, oop o) {
aoqi@0 840 HandleMark hm;
aoqi@0 841 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), o->klass());
aoqi@0 842
aoqi@0 843 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
aoqi@0 844 if (!fld.access_flags().is_static()) {
aoqi@0 845 Symbol* sig = fld.signature();
aoqi@0 846 address addr = (address)o + fld.offset();
aoqi@0 847
aoqi@0 848 dump_field_value(writer, sig->byte_at(0), addr);
aoqi@0 849 }
aoqi@0 850 }
aoqi@0 851 }
aoqi@0 852
aoqi@0 853 // dumps the definition of the instance fields for a given class
aoqi@0 854 void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, Klass* k) {
aoqi@0 855 HandleMark hm;
aoqi@0 856 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
aoqi@0 857
aoqi@0 858 // pass 1 - count the instance fields
aoqi@0 859 u2 field_count = 0;
aoqi@0 860 for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {
aoqi@0 861 if (!fldc.access_flags().is_static()) field_count++;
aoqi@0 862 }
aoqi@0 863
aoqi@0 864 writer->write_u2(field_count);
aoqi@0 865
aoqi@0 866 // pass 2 - dump the field descriptors
aoqi@0 867 for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {
aoqi@0 868 if (!fld.access_flags().is_static()) {
aoqi@0 869 Symbol* sig = fld.signature();
aoqi@0 870
aoqi@0 871 writer->write_symbolID(fld.name()); // name
aoqi@0 872 writer->write_u1(sig2tag(sig)); // type
aoqi@0 873 }
aoqi@0 874 }
aoqi@0 875 }
aoqi@0 876
aoqi@0 877 // creates HPROF_GC_INSTANCE_DUMP record for the given object
aoqi@0 878 void DumperSupport::dump_instance(DumpWriter* writer, oop o) {
aoqi@0 879 Klass* k = o->klass();
aoqi@0 880
aoqi@0 881 writer->write_u1(HPROF_GC_INSTANCE_DUMP);
aoqi@0 882 writer->write_objectID(o);
aoqi@0 883 writer->write_u4(STACK_TRACE_ID);
aoqi@0 884
aoqi@0 885 // class ID
aoqi@0 886 writer->write_classID(k);
aoqi@0 887
aoqi@0 888 // number of bytes that follow
aoqi@0 889 writer->write_u4(instance_size(k) );
aoqi@0 890
aoqi@0 891 // field values
aoqi@0 892 dump_instance_fields(writer, o);
aoqi@0 893 }
aoqi@0 894
aoqi@0 895 // creates HPROF_GC_CLASS_DUMP record for the given class and each of
aoqi@0 896 // its array classes
aoqi@0 897 void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) {
aoqi@0 898 Klass* klass = k;
aoqi@0 899 assert(klass->oop_is_instance(), "not an InstanceKlass");
aoqi@0 900 InstanceKlass* ik = (InstanceKlass*)klass;
aoqi@0 901
aoqi@0 902 writer->write_u1(HPROF_GC_CLASS_DUMP);
aoqi@0 903
aoqi@0 904 // class ID
aoqi@0 905 writer->write_classID(ik);
aoqi@0 906 writer->write_u4(STACK_TRACE_ID);
aoqi@0 907
aoqi@0 908 // super class ID
aoqi@0 909 Klass* java_super = ik->java_super();
aoqi@0 910 if (java_super == NULL) {
aoqi@0 911 writer->write_objectID(oop(NULL));
aoqi@0 912 } else {
aoqi@0 913 writer->write_classID(java_super);
aoqi@0 914 }
aoqi@0 915
aoqi@0 916 writer->write_objectID(ik->class_loader());
aoqi@0 917 writer->write_objectID(ik->signers());
aoqi@0 918 writer->write_objectID(ik->protection_domain());
aoqi@0 919
aoqi@0 920 // reserved
aoqi@0 921 writer->write_objectID(oop(NULL));
aoqi@0 922 writer->write_objectID(oop(NULL));
aoqi@0 923
aoqi@0 924 // instance size
aoqi@0 925 writer->write_u4(DumperSupport::instance_size(k));
aoqi@0 926
aoqi@0 927 // size of constant pool - ignored by HAT 1.1
aoqi@0 928 writer->write_u2(0);
aoqi@0 929
aoqi@0 930 // number of static fields
aoqi@0 931 dump_static_fields(writer, k);
aoqi@0 932
aoqi@0 933 // description of instance fields
aoqi@0 934 dump_instance_field_descriptors(writer, k);
aoqi@0 935
aoqi@0 936 // array classes
aoqi@0 937 k = klass->array_klass_or_null();
aoqi@0 938 while (k != NULL) {
aoqi@0 939 Klass* klass = k;
aoqi@0 940 assert(klass->oop_is_objArray(), "not an ObjArrayKlass");
aoqi@0 941
aoqi@0 942 writer->write_u1(HPROF_GC_CLASS_DUMP);
aoqi@0 943 writer->write_classID(klass);
aoqi@0 944 writer->write_u4(STACK_TRACE_ID);
aoqi@0 945
aoqi@0 946 // super class of array classes is java.lang.Object
aoqi@0 947 java_super = klass->java_super();
aoqi@0 948 assert(java_super != NULL, "checking");
aoqi@0 949 writer->write_classID(java_super);
aoqi@0 950
aoqi@0 951 writer->write_objectID(ik->class_loader());
aoqi@0 952 writer->write_objectID(ik->signers());
aoqi@0 953 writer->write_objectID(ik->protection_domain());
aoqi@0 954
aoqi@0 955 writer->write_objectID(oop(NULL)); // reserved
aoqi@0 956 writer->write_objectID(oop(NULL));
aoqi@0 957 writer->write_u4(0); // instance size
aoqi@0 958 writer->write_u2(0); // constant pool
aoqi@0 959 writer->write_u2(0); // static fields
aoqi@0 960 writer->write_u2(0); // instance fields
aoqi@0 961
aoqi@0 962 // get the array class for the next rank
aoqi@0 963 k = klass->array_klass_or_null();
aoqi@0 964 }
aoqi@0 965 }
aoqi@0 966
aoqi@0 967 // creates HPROF_GC_CLASS_DUMP record for a given primitive array
aoqi@0 968 // class (and each multi-dimensional array class too)
aoqi@0 969 void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) {
aoqi@0 970 // array classes
aoqi@0 971 while (k != NULL) {
aoqi@0 972 Klass* klass = k;
aoqi@0 973
aoqi@0 974 writer->write_u1(HPROF_GC_CLASS_DUMP);
aoqi@0 975 writer->write_classID(klass);
aoqi@0 976 writer->write_u4(STACK_TRACE_ID);
aoqi@0 977
aoqi@0 978 // super class of array classes is java.lang.Object
aoqi@0 979 Klass* java_super = klass->java_super();
aoqi@0 980 assert(java_super != NULL, "checking");
aoqi@0 981 writer->write_classID(java_super);
aoqi@0 982
aoqi@0 983 writer->write_objectID(oop(NULL)); // loader
aoqi@0 984 writer->write_objectID(oop(NULL)); // signers
aoqi@0 985 writer->write_objectID(oop(NULL)); // protection domain
aoqi@0 986
aoqi@0 987 writer->write_objectID(oop(NULL)); // reserved
aoqi@0 988 writer->write_objectID(oop(NULL));
aoqi@0 989 writer->write_u4(0); // instance size
aoqi@0 990 writer->write_u2(0); // constant pool
aoqi@0 991 writer->write_u2(0); // static fields
aoqi@0 992 writer->write_u2(0); // instance fields
aoqi@0 993
aoqi@0 994 // get the array class for the next rank
aoqi@0 995 k = klass->array_klass_or_null();
aoqi@0 996 }
aoqi@0 997 }
aoqi@0 998
aoqi@0 999 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
aoqi@0 1000 void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) {
aoqi@0 1001
aoqi@0 1002 writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP);
aoqi@0 1003 writer->write_objectID(array);
aoqi@0 1004 writer->write_u4(STACK_TRACE_ID);
aoqi@0 1005 writer->write_u4((u4)array->length());
aoqi@0 1006
aoqi@0 1007 // array class ID
aoqi@0 1008 writer->write_classID(array->klass());
aoqi@0 1009
aoqi@0 1010 // [id]* elements
aoqi@0 1011 for (int index=0; index<array->length(); index++) {
aoqi@0 1012 oop o = array->obj_at(index);
aoqi@0 1013 writer->write_objectID(o);
aoqi@0 1014 }
aoqi@0 1015 }
aoqi@0 1016
aoqi@0 1017 #define WRITE_ARRAY(Array, Type, Size) \
aoqi@0 1018 for (int i=0; i<Array->length(); i++) { writer->write_##Size((Size)array->Type##_at(i)); }
aoqi@0 1019
aoqi@0 1020
aoqi@0 1021 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
aoqi@0 1022 void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
aoqi@0 1023 BasicType type = TypeArrayKlass::cast(array->klass())->element_type();
aoqi@0 1024
aoqi@0 1025 writer->write_u1(HPROF_GC_PRIM_ARRAY_DUMP);
aoqi@0 1026 writer->write_objectID(array);
aoqi@0 1027 writer->write_u4(STACK_TRACE_ID);
aoqi@0 1028 writer->write_u4((u4)array->length());
aoqi@0 1029 writer->write_u1(type2tag(type));
aoqi@0 1030
aoqi@0 1031 // nothing to copy
aoqi@0 1032 if (array->length() == 0) {
aoqi@0 1033 return;
aoqi@0 1034 }
aoqi@0 1035
aoqi@0 1036 // If the byte ordering is big endian then we can copy most types directly
aeriksso@8317 1037 u4 length_in_bytes = (u4)array->length() * type2aelembytes(type);
aoqi@0 1038
aoqi@0 1039 switch (type) {
aoqi@0 1040 case T_INT : {
aoqi@0 1041 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1042 WRITE_ARRAY(array, int, u4);
aoqi@0 1043 } else {
aoqi@0 1044 writer->write_raw((void*)(array->int_at_addr(0)), length_in_bytes);
aoqi@0 1045 }
aoqi@0 1046 break;
aoqi@0 1047 }
aoqi@0 1048 case T_BYTE : {
aoqi@0 1049 writer->write_raw((void*)(array->byte_at_addr(0)), length_in_bytes);
aoqi@0 1050 break;
aoqi@0 1051 }
aoqi@0 1052 case T_CHAR : {
aoqi@0 1053 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1054 WRITE_ARRAY(array, char, u2);
aoqi@0 1055 } else {
aoqi@0 1056 writer->write_raw((void*)(array->char_at_addr(0)), length_in_bytes);
aoqi@0 1057 }
aoqi@0 1058 break;
aoqi@0 1059 }
aoqi@0 1060 case T_SHORT : {
aoqi@0 1061 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1062 WRITE_ARRAY(array, short, u2);
aoqi@0 1063 } else {
aoqi@0 1064 writer->write_raw((void*)(array->short_at_addr(0)), length_in_bytes);
aoqi@0 1065 }
aoqi@0 1066 break;
aoqi@0 1067 }
aoqi@0 1068 case T_BOOLEAN : {
aoqi@0 1069 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1070 WRITE_ARRAY(array, bool, u1);
aoqi@0 1071 } else {
aoqi@0 1072 writer->write_raw((void*)(array->bool_at_addr(0)), length_in_bytes);
aoqi@0 1073 }
aoqi@0 1074 break;
aoqi@0 1075 }
aoqi@0 1076 case T_LONG : {
aoqi@0 1077 if (Bytes::is_Java_byte_ordering_different()) {
aoqi@0 1078 WRITE_ARRAY(array, long, u8);
aoqi@0 1079 } else {
aoqi@0 1080 writer->write_raw((void*)(array->long_at_addr(0)), length_in_bytes);
aoqi@0 1081 }
aoqi@0 1082 break;
aoqi@0 1083 }
aoqi@0 1084
aoqi@0 1085 // handle float/doubles in a special value to ensure than NaNs are
aoqi@0 1086 // written correctly. TO DO: Check if we can avoid this on processors that
aoqi@0 1087 // use IEEE 754.
aoqi@0 1088
aoqi@0 1089 case T_FLOAT : {
aoqi@0 1090 for (int i=0; i<array->length(); i++) {
aoqi@0 1091 dump_float( writer, array->float_at(i) );
aoqi@0 1092 }
aoqi@0 1093 break;
aoqi@0 1094 }
aoqi@0 1095 case T_DOUBLE : {
aoqi@0 1096 for (int i=0; i<array->length(); i++) {
aoqi@0 1097 dump_double( writer, array->double_at(i) );
aoqi@0 1098 }
aoqi@0 1099 break;
aoqi@0 1100 }
aoqi@0 1101 default : ShouldNotReachHere();
aoqi@0 1102 }
aoqi@0 1103 }
aoqi@0 1104
aoqi@0 1105 // create a HPROF_FRAME record of the given Method* and bci
aoqi@0 1106 void DumperSupport::dump_stack_frame(DumpWriter* writer,
aoqi@0 1107 int frame_serial_num,
aoqi@0 1108 int class_serial_num,
aoqi@0 1109 Method* m,
aoqi@0 1110 int bci) {
aoqi@0 1111 int line_number;
aoqi@0 1112 if (m->is_native()) {
aoqi@0 1113 line_number = -3; // native frame
aoqi@0 1114 } else {
aoqi@0 1115 line_number = m->line_number_from_bci(bci);
aoqi@0 1116 }
aoqi@0 1117
aoqi@0 1118 write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4));
aoqi@0 1119 writer->write_id(frame_serial_num); // frame serial number
aoqi@0 1120 writer->write_symbolID(m->name()); // method's name
aoqi@0 1121 writer->write_symbolID(m->signature()); // method's signature
aoqi@0 1122
aoqi@0 1123 assert(m->method_holder()->oop_is_instance(), "not InstanceKlass");
aoqi@0 1124 writer->write_symbolID(m->method_holder()->source_file_name()); // source file name
aoqi@0 1125 writer->write_u4(class_serial_num); // class serial number
aoqi@0 1126 writer->write_u4((u4) line_number); // line number
aoqi@0 1127 }
aoqi@0 1128
aoqi@0 1129
aoqi@0 1130 // Support class used to generate HPROF_UTF8 records from the entries in the
aoqi@0 1131 // SymbolTable.
aoqi@0 1132
aoqi@0 1133 class SymbolTableDumper : public SymbolClosure {
aoqi@0 1134 private:
aoqi@0 1135 DumpWriter* _writer;
aoqi@0 1136 DumpWriter* writer() const { return _writer; }
aoqi@0 1137 public:
aoqi@0 1138 SymbolTableDumper(DumpWriter* writer) { _writer = writer; }
aoqi@0 1139 void do_symbol(Symbol** p);
aoqi@0 1140 };
aoqi@0 1141
aoqi@0 1142 void SymbolTableDumper::do_symbol(Symbol** p) {
aoqi@0 1143 ResourceMark rm;
aoqi@0 1144 Symbol* sym = load_symbol(p);
aoqi@0 1145 int len = sym->utf8_length();
aoqi@0 1146 if (len > 0) {
aoqi@0 1147 char* s = sym->as_utf8();
aoqi@0 1148 DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);
aoqi@0 1149 writer()->write_symbolID(sym);
aoqi@0 1150 writer()->write_raw(s, len);
aoqi@0 1151 }
aoqi@0 1152 }
aoqi@0 1153
aoqi@0 1154 // Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records
aoqi@0 1155
aoqi@0 1156 class JNILocalsDumper : public OopClosure {
aoqi@0 1157 private:
aoqi@0 1158 DumpWriter* _writer;
aoqi@0 1159 u4 _thread_serial_num;
aoqi@0 1160 int _frame_num;
aoqi@0 1161 DumpWriter* writer() const { return _writer; }
aoqi@0 1162 public:
aoqi@0 1163 JNILocalsDumper(DumpWriter* writer, u4 thread_serial_num) {
aoqi@0 1164 _writer = writer;
aoqi@0 1165 _thread_serial_num = thread_serial_num;
aoqi@0 1166 _frame_num = -1; // default - empty stack
aoqi@0 1167 }
aoqi@0 1168 void set_frame_number(int n) { _frame_num = n; }
aoqi@0 1169 void do_oop(oop* obj_p);
aoqi@0 1170 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
aoqi@0 1171 };
aoqi@0 1172
aoqi@0 1173
aoqi@0 1174 void JNILocalsDumper::do_oop(oop* obj_p) {
aoqi@0 1175 // ignore null or deleted handles
aoqi@0 1176 oop o = *obj_p;
aoqi@0 1177 if (o != NULL && o != JNIHandles::deleted_handle()) {
aoqi@0 1178 writer()->write_u1(HPROF_GC_ROOT_JNI_LOCAL);
aoqi@0 1179 writer()->write_objectID(o);
aoqi@0 1180 writer()->write_u4(_thread_serial_num);
aoqi@0 1181 writer()->write_u4((u4)_frame_num);
aoqi@0 1182 }
aoqi@0 1183 }
aoqi@0 1184
aoqi@0 1185
aoqi@0 1186 // Support class used to generate HPROF_GC_ROOT_JNI_GLOBAL records
aoqi@0 1187
aoqi@0 1188 class JNIGlobalsDumper : public OopClosure {
aoqi@0 1189 private:
aoqi@0 1190 DumpWriter* _writer;
aoqi@0 1191 DumpWriter* writer() const { return _writer; }
aoqi@0 1192
aoqi@0 1193 public:
aoqi@0 1194 JNIGlobalsDumper(DumpWriter* writer) {
aoqi@0 1195 _writer = writer;
aoqi@0 1196 }
aoqi@0 1197 void do_oop(oop* obj_p);
aoqi@0 1198 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
aoqi@0 1199 };
aoqi@0 1200
aoqi@0 1201 void JNIGlobalsDumper::do_oop(oop* obj_p) {
aoqi@0 1202 oop o = *obj_p;
aoqi@0 1203
aoqi@0 1204 // ignore these
aoqi@0 1205 if (o == NULL || o == JNIHandles::deleted_handle()) return;
aoqi@0 1206
aoqi@0 1207 // we ignore global ref to symbols and other internal objects
aoqi@0 1208 if (o->is_instance() || o->is_objArray() || o->is_typeArray()) {
aoqi@0 1209 writer()->write_u1(HPROF_GC_ROOT_JNI_GLOBAL);
aoqi@0 1210 writer()->write_objectID(o);
aoqi@0 1211 writer()->write_objectID((oopDesc*)obj_p); // global ref ID
aoqi@0 1212 }
aoqi@0 1213 };
aoqi@0 1214
aoqi@0 1215
aoqi@0 1216 // Support class used to generate HPROF_GC_ROOT_MONITOR_USED records
aoqi@0 1217
aoqi@0 1218 class MonitorUsedDumper : public OopClosure {
aoqi@0 1219 private:
aoqi@0 1220 DumpWriter* _writer;
aoqi@0 1221 DumpWriter* writer() const { return _writer; }
aoqi@0 1222 public:
aoqi@0 1223 MonitorUsedDumper(DumpWriter* writer) {
aoqi@0 1224 _writer = writer;
aoqi@0 1225 }
aoqi@0 1226 void do_oop(oop* obj_p) {
aoqi@0 1227 writer()->write_u1(HPROF_GC_ROOT_MONITOR_USED);
aoqi@0 1228 writer()->write_objectID(*obj_p);
aoqi@0 1229 }
aoqi@0 1230 void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
aoqi@0 1231 };
aoqi@0 1232
aoqi@0 1233
aoqi@0 1234 // Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records
aoqi@0 1235
aoqi@0 1236 class StickyClassDumper : public KlassClosure {
aoqi@0 1237 private:
aoqi@0 1238 DumpWriter* _writer;
aoqi@0 1239 DumpWriter* writer() const { return _writer; }
aoqi@0 1240 public:
aoqi@0 1241 StickyClassDumper(DumpWriter* writer) {
aoqi@0 1242 _writer = writer;
aoqi@0 1243 }
aoqi@0 1244 void do_klass(Klass* k) {
aoqi@0 1245 if (k->oop_is_instance()) {
aoqi@0 1246 InstanceKlass* ik = InstanceKlass::cast(k);
aoqi@0 1247 writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS);
aoqi@0 1248 writer()->write_classID(ik);
aoqi@0 1249 }
aoqi@0 1250 }
aoqi@0 1251 };
aoqi@0 1252
aoqi@0 1253
aoqi@0 1254 class VM_HeapDumper;
aoqi@0 1255
aoqi@0 1256 // Support class using when iterating over the heap.
aoqi@0 1257
aoqi@0 1258 class HeapObjectDumper : public ObjectClosure {
aoqi@0 1259 private:
aoqi@0 1260 VM_HeapDumper* _dumper;
aoqi@0 1261 DumpWriter* _writer;
aoqi@0 1262
aoqi@0 1263 VM_HeapDumper* dumper() { return _dumper; }
aoqi@0 1264 DumpWriter* writer() { return _writer; }
aoqi@0 1265
aoqi@0 1266 // used to indicate that a record has been writen
aoqi@0 1267 void mark_end_of_record();
aoqi@0 1268
aoqi@0 1269 public:
aoqi@0 1270 HeapObjectDumper(VM_HeapDumper* dumper, DumpWriter* writer) {
aoqi@0 1271 _dumper = dumper;
aoqi@0 1272 _writer = writer;
aoqi@0 1273 }
aoqi@0 1274
aoqi@0 1275 // called for each object in the heap
aoqi@0 1276 void do_object(oop o);
aoqi@0 1277 };
aoqi@0 1278
aoqi@0 1279 void HeapObjectDumper::do_object(oop o) {
aoqi@0 1280 // hide the sentinel for deleted handles
aoqi@0 1281 if (o == JNIHandles::deleted_handle()) return;
aoqi@0 1282
aoqi@0 1283 // skip classes as these emitted as HPROF_GC_CLASS_DUMP records
aoqi@0 1284 if (o->klass() == SystemDictionary::Class_klass()) {
aoqi@0 1285 if (!java_lang_Class::is_primitive(o)) {
aoqi@0 1286 return;
aoqi@0 1287 }
aoqi@0 1288 }
aoqi@0 1289
aoqi@0 1290 if (o->is_instance()) {
aeriksso@8317 1291 // create a HPROF_GC_INSTANCE record for each object
aoqi@0 1292 DumperSupport::dump_instance(writer(), o);
aoqi@0 1293 mark_end_of_record();
aeriksso@8317 1294 } else if (o->is_objArray()) {
aoqi@0 1295 // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
aeriksso@8317 1296 DumperSupport::dump_object_array(writer(), objArrayOop(o));
aeriksso@8317 1297 mark_end_of_record();
aeriksso@8317 1298 } else if (o->is_typeArray()) {
aeriksso@8317 1299 // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
aeriksso@8317 1300 DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
aeriksso@8317 1301 mark_end_of_record();
aoqi@0 1302 }
aoqi@0 1303 }
aoqi@0 1304
aoqi@0 1305 // The VM operation that performs the heap dump
aoqi@0 1306 class VM_HeapDumper : public VM_GC_Operation {
aoqi@0 1307 private:
aoqi@0 1308 static VM_HeapDumper* _global_dumper;
aoqi@0 1309 static DumpWriter* _global_writer;
aoqi@0 1310 DumpWriter* _local_writer;
aoqi@0 1311 JavaThread* _oome_thread;
aoqi@0 1312 Method* _oome_constructor;
aoqi@0 1313 bool _gc_before_heap_dump;
aoqi@0 1314 bool _is_segmented_dump;
aoqi@0 1315 jlong _dump_start;
aoqi@0 1316 GrowableArray<Klass*>* _klass_map;
aoqi@0 1317 ThreadStackTrace** _stack_traces;
aoqi@0 1318 int _num_threads;
aoqi@0 1319
aoqi@0 1320 // accessors and setters
aoqi@0 1321 static VM_HeapDumper* dumper() { assert(_global_dumper != NULL, "Error"); return _global_dumper; }
aoqi@0 1322 static DumpWriter* writer() { assert(_global_writer != NULL, "Error"); return _global_writer; }
aoqi@0 1323 void set_global_dumper() {
aoqi@0 1324 assert(_global_dumper == NULL, "Error");
aoqi@0 1325 _global_dumper = this;
aoqi@0 1326 }
aoqi@0 1327 void set_global_writer() {
aoqi@0 1328 assert(_global_writer == NULL, "Error");
aoqi@0 1329 _global_writer = _local_writer;
aoqi@0 1330 }
aoqi@0 1331 void clear_global_dumper() { _global_dumper = NULL; }
aoqi@0 1332 void clear_global_writer() { _global_writer = NULL; }
aoqi@0 1333
aoqi@0 1334 bool is_segmented_dump() const { return _is_segmented_dump; }
aoqi@0 1335 void set_segmented_dump() { _is_segmented_dump = true; }
aoqi@0 1336 jlong dump_start() const { return _dump_start; }
aoqi@0 1337 void set_dump_start(jlong pos);
aoqi@0 1338
aoqi@0 1339 bool skip_operation() const;
aoqi@0 1340
aoqi@0 1341 // writes a HPROF_LOAD_CLASS record
aoqi@0 1342 static void do_load_class(Klass* k);
aoqi@0 1343
aoqi@0 1344 // writes a HPROF_GC_CLASS_DUMP record for the given class
aoqi@0 1345 // (and each array class too)
aoqi@0 1346 static void do_class_dump(Klass* k);
aoqi@0 1347
aoqi@0 1348 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
aoqi@0 1349 // array (and each multi-dimensional array too)
aoqi@0 1350 static void do_basic_type_array_class_dump(Klass* k);
aoqi@0 1351
aoqi@0 1352 // HPROF_GC_ROOT_THREAD_OBJ records
aoqi@0 1353 int do_thread(JavaThread* thread, u4 thread_serial_num);
aoqi@0 1354 void do_threads();
aoqi@0 1355
aoqi@0 1356 void add_class_serial_number(Klass* k, int serial_num) {
aoqi@0 1357 _klass_map->at_put_grow(serial_num, k);
aoqi@0 1358 }
aoqi@0 1359
aoqi@0 1360 // HPROF_TRACE and HPROF_FRAME records
aoqi@0 1361 void dump_stack_traces();
aoqi@0 1362
aoqi@0 1363 // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
aoqi@0 1364 void write_dump_header();
aoqi@0 1365
aoqi@0 1366 // fixes up the length of the current dump record
aoqi@0 1367 void write_current_dump_record_length();
aoqi@0 1368
aoqi@0 1369 // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
aoqi@0 1370 // record in the case of a segmented heap dump)
aoqi@0 1371 void end_of_dump();
aoqi@0 1372
aoqi@0 1373 public:
aoqi@0 1374 VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) :
aoqi@0 1375 VM_GC_Operation(0 /* total collections, dummy, ignored */,
aoqi@0 1376 GCCause::_heap_dump /* GC Cause */,
aoqi@0 1377 0 /* total full collections, dummy, ignored */,
aoqi@0 1378 gc_before_heap_dump) {
aoqi@0 1379 _local_writer = writer;
aoqi@0 1380 _gc_before_heap_dump = gc_before_heap_dump;
aoqi@0 1381 _is_segmented_dump = false;
aoqi@0 1382 _dump_start = (jlong)-1;
aoqi@0 1383 _klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
aoqi@0 1384 _stack_traces = NULL;
aoqi@0 1385 _num_threads = 0;
aoqi@0 1386 if (oome) {
aoqi@0 1387 assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");
aoqi@0 1388 // get OutOfMemoryError zero-parameter constructor
aoqi@0 1389 InstanceKlass* oome_ik = InstanceKlass::cast(SystemDictionary::OutOfMemoryError_klass());
aoqi@0 1390 _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(),
aoqi@0 1391 vmSymbols::void_method_signature());
aoqi@0 1392 // get thread throwing OOME when generating the heap dump at OOME
aoqi@0 1393 _oome_thread = JavaThread::current();
aoqi@0 1394 } else {
aoqi@0 1395 _oome_thread = NULL;
aoqi@0 1396 _oome_constructor = NULL;
aoqi@0 1397 }
aoqi@0 1398 }
aoqi@0 1399 ~VM_HeapDumper() {
aoqi@0 1400 if (_stack_traces != NULL) {
aoqi@0 1401 for (int i=0; i < _num_threads; i++) {
aoqi@0 1402 delete _stack_traces[i];
aoqi@0 1403 }
aoqi@0 1404 FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces, mtInternal);
aoqi@0 1405 }
aoqi@0 1406 delete _klass_map;
aoqi@0 1407 }
aoqi@0 1408
aoqi@0 1409 VMOp_Type type() const { return VMOp_HeapDumper; }
aoqi@0 1410 // used to mark sub-record boundary
aoqi@0 1411 void check_segment_length();
aoqi@0 1412 void doit();
aoqi@0 1413 };
aoqi@0 1414
aoqi@0 1415 VM_HeapDumper* VM_HeapDumper::_global_dumper = NULL;
aoqi@0 1416 DumpWriter* VM_HeapDumper::_global_writer = NULL;
aoqi@0 1417
aoqi@0 1418 bool VM_HeapDumper::skip_operation() const {
aoqi@0 1419 return false;
aoqi@0 1420 }
aoqi@0 1421
aoqi@0 1422 // sets the dump starting position
aoqi@0 1423 void VM_HeapDumper::set_dump_start(jlong pos) {
aoqi@0 1424 _dump_start = pos;
aoqi@0 1425 }
aoqi@0 1426
aoqi@0 1427 // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
aoqi@0 1428 void VM_HeapDumper::write_dump_header() {
aoqi@0 1429 if (writer()->is_open()) {
aoqi@0 1430 if (is_segmented_dump()) {
aoqi@0 1431 writer()->write_u1(HPROF_HEAP_DUMP_SEGMENT);
aoqi@0 1432 } else {
aoqi@0 1433 writer()->write_u1(HPROF_HEAP_DUMP);
aoqi@0 1434 }
aoqi@0 1435 writer()->write_u4(0); // current ticks
aoqi@0 1436
aoqi@0 1437 // record the starting position for the dump (its length will be fixed up later)
aoqi@0 1438 set_dump_start(writer()->current_offset());
aoqi@0 1439 writer()->write_u4(0);
aoqi@0 1440 }
aoqi@0 1441 }
aoqi@0 1442
aoqi@0 1443 // fixes up the length of the current dump record
aoqi@0 1444 void VM_HeapDumper::write_current_dump_record_length() {
aoqi@0 1445 if (writer()->is_open()) {
aoqi@0 1446 assert(dump_start() >= 0, "no dump start recorded");
aoqi@0 1447
aoqi@0 1448 // calculate the size of the dump record
aeriksso@8317 1449 julong dump_end = writer()->current_offset();
aeriksso@8317 1450 julong dump_len = (dump_end - dump_start() - 4);
aoqi@0 1451
aoqi@0 1452 // record length must fit in a u4
aeriksso@8317 1453 if (dump_len > max_juint) {
aoqi@0 1454 warning("record is too large");
aoqi@0 1455 }
aoqi@0 1456
aoqi@0 1457 // seek to the dump start and fix-up the length
aoqi@0 1458 writer()->seek_to_offset(dump_start());
aoqi@0 1459 writer()->write_u4((u4)dump_len);
aoqi@0 1460
aoqi@0 1461 // adjust the total size written to keep the bytes written correct.
aeriksso@8317 1462 writer()->adjust_bytes_written(-((jlong) sizeof(u4)));
aoqi@0 1463
aoqi@0 1464 // seek to dump end so we can continue
aoqi@0 1465 writer()->seek_to_offset(dump_end);
aoqi@0 1466
aoqi@0 1467 // no current dump record
aoqi@0 1468 set_dump_start((jlong)-1);
aoqi@0 1469 }
aoqi@0 1470 }
aoqi@0 1471
aoqi@0 1472 // used on a sub-record boundary to check if we need to start a
aoqi@0 1473 // new segment.
aoqi@0 1474 void VM_HeapDumper::check_segment_length() {
aoqi@0 1475 if (writer()->is_open()) {
aoqi@0 1476 if (is_segmented_dump()) {
aoqi@0 1477 // don't use current_offset that would be too expensive on a per record basis
aeriksso@8317 1478 julong dump_end = writer()->bytes_written() + writer()->bytes_unwritten();
aeriksso@8317 1479 assert(dump_end == (julong)writer()->current_offset(), "checking");
aeriksso@8317 1480 julong dump_len = (dump_end - dump_start() - 4);
aeriksso@8317 1481 assert(dump_len <= max_juint, "bad dump length");
aoqi@0 1482
aeriksso@8317 1483 if (dump_len > HeapDumpSegmentSize) {
aoqi@0 1484 write_current_dump_record_length();
aoqi@0 1485 write_dump_header();
aoqi@0 1486 }
aoqi@0 1487 }
aoqi@0 1488 }
aoqi@0 1489 }
aoqi@0 1490
aoqi@0 1491 // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
aoqi@0 1492 // record in the case of a segmented heap dump)
aoqi@0 1493 void VM_HeapDumper::end_of_dump() {
aoqi@0 1494 if (writer()->is_open()) {
aoqi@0 1495 write_current_dump_record_length();
aoqi@0 1496
aoqi@0 1497 // for segmented dump we write the end record
aoqi@0 1498 if (is_segmented_dump()) {
aoqi@0 1499 writer()->write_u1(HPROF_HEAP_DUMP_END);
aoqi@0 1500 writer()->write_u4(0);
aoqi@0 1501 writer()->write_u4(0);
aoqi@0 1502 }
aoqi@0 1503 }
aoqi@0 1504 }
aoqi@0 1505
aoqi@0 1506 // marks sub-record boundary
aoqi@0 1507 void HeapObjectDumper::mark_end_of_record() {
aoqi@0 1508 dumper()->check_segment_length();
aoqi@0 1509 }
aoqi@0 1510
aoqi@0 1511 // writes a HPROF_LOAD_CLASS record for the class (and each of its
aoqi@0 1512 // array classes)
aoqi@0 1513 void VM_HeapDumper::do_load_class(Klass* k) {
aoqi@0 1514 static u4 class_serial_num = 0;
aoqi@0 1515
aoqi@0 1516 // len of HPROF_LOAD_CLASS record
aoqi@0 1517 u4 remaining = 2*oopSize + 2*sizeof(u4);
aoqi@0 1518
aoqi@0 1519 // write a HPROF_LOAD_CLASS for the class and each array class
aoqi@0 1520 do {
aoqi@0 1521 DumperSupport::write_header(writer(), HPROF_LOAD_CLASS, remaining);
aoqi@0 1522
aoqi@0 1523 // class serial number is just a number
aoqi@0 1524 writer()->write_u4(++class_serial_num);
aoqi@0 1525
aoqi@0 1526 // class ID
aoqi@0 1527 Klass* klass = k;
aoqi@0 1528 writer()->write_classID(klass);
aoqi@0 1529
aoqi@0 1530 // add the Klass* and class serial number pair
aoqi@0 1531 dumper()->add_class_serial_number(klass, class_serial_num);
aoqi@0 1532
aoqi@0 1533 writer()->write_u4(STACK_TRACE_ID);
aoqi@0 1534
aoqi@0 1535 // class name ID
aoqi@0 1536 Symbol* name = klass->name();
aoqi@0 1537 writer()->write_symbolID(name);
aoqi@0 1538
aoqi@0 1539 // write a LOAD_CLASS record for the array type (if it exists)
aoqi@0 1540 k = klass->array_klass_or_null();
aoqi@0 1541 } while (k != NULL);
aoqi@0 1542 }
aoqi@0 1543
aoqi@0 1544 // writes a HPROF_GC_CLASS_DUMP record for the given class
aoqi@0 1545 void VM_HeapDumper::do_class_dump(Klass* k) {
aoqi@0 1546 if (k->oop_is_instance()) {
aoqi@0 1547 DumperSupport::dump_class_and_array_classes(writer(), k);
aoqi@0 1548 }
aoqi@0 1549 }
aoqi@0 1550
aoqi@0 1551 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
aoqi@0 1552 // array (and each multi-dimensional array too)
aoqi@0 1553 void VM_HeapDumper::do_basic_type_array_class_dump(Klass* k) {
aoqi@0 1554 DumperSupport::dump_basic_type_array_class(writer(), k);
aoqi@0 1555 }
aoqi@0 1556
aoqi@0 1557 // Walk the stack of the given thread.
aoqi@0 1558 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local
aoqi@0 1559 // Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local
aoqi@0 1560 //
aoqi@0 1561 // It returns the number of Java frames in this thread stack
aoqi@0 1562 int VM_HeapDumper::do_thread(JavaThread* java_thread, u4 thread_serial_num) {
aoqi@0 1563 JNILocalsDumper blk(writer(), thread_serial_num);
aoqi@0 1564
aoqi@0 1565 oop threadObj = java_thread->threadObj();
aoqi@0 1566 assert(threadObj != NULL, "sanity check");
aoqi@0 1567
aoqi@0 1568 int stack_depth = 0;
aoqi@0 1569 if (java_thread->has_last_Java_frame()) {
aoqi@0 1570
aoqi@0 1571 // vframes are resource allocated
aoqi@0 1572 Thread* current_thread = Thread::current();
aoqi@0 1573 ResourceMark rm(current_thread);
aoqi@0 1574 HandleMark hm(current_thread);
aoqi@0 1575
aoqi@0 1576 RegisterMap reg_map(java_thread);
aoqi@0 1577 frame f = java_thread->last_frame();
aoqi@0 1578 vframe* vf = vframe::new_vframe(&f, &reg_map, java_thread);
aoqi@0 1579 frame* last_entry_frame = NULL;
aoqi@0 1580 int extra_frames = 0;
aoqi@0 1581
aoqi@0 1582 if (java_thread == _oome_thread && _oome_constructor != NULL) {
aoqi@0 1583 extra_frames++;
aoqi@0 1584 }
aoqi@0 1585 while (vf != NULL) {
aoqi@0 1586 blk.set_frame_number(stack_depth);
aoqi@0 1587 if (vf->is_java_frame()) {
aoqi@0 1588
aoqi@0 1589 // java frame (interpreted, compiled, ...)
aoqi@0 1590 javaVFrame *jvf = javaVFrame::cast(vf);
aoqi@0 1591 if (!(jvf->method()->is_native())) {
aoqi@0 1592 StackValueCollection* locals = jvf->locals();
aoqi@0 1593 for (int slot=0; slot<locals->size(); slot++) {
aoqi@0 1594 if (locals->at(slot)->type() == T_OBJECT) {
aoqi@0 1595 oop o = locals->obj_at(slot)();
aoqi@0 1596
aoqi@0 1597 if (o != NULL) {
aoqi@0 1598 writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME);
aoqi@0 1599 writer()->write_objectID(o);
aoqi@0 1600 writer()->write_u4(thread_serial_num);
aoqi@0 1601 writer()->write_u4((u4) (stack_depth + extra_frames));
aoqi@0 1602 }
aoqi@0 1603 }
aoqi@0 1604 }
aoqi@0 1605 } else {
aoqi@0 1606 // native frame
aoqi@0 1607 if (stack_depth == 0) {
aoqi@0 1608 // JNI locals for the top frame.
aoqi@0 1609 java_thread->active_handles()->oops_do(&blk);
aoqi@0 1610 } else {
aoqi@0 1611 if (last_entry_frame != NULL) {
aoqi@0 1612 // JNI locals for the entry frame
aoqi@0 1613 assert(last_entry_frame->is_entry_frame(), "checking");
aoqi@0 1614 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(&blk);
aoqi@0 1615 }
aoqi@0 1616 }
aoqi@0 1617 }
aoqi@0 1618 // increment only for Java frames
aoqi@0 1619 stack_depth++;
aoqi@0 1620 last_entry_frame = NULL;
aoqi@0 1621
aoqi@0 1622 } else {
aoqi@0 1623 // externalVFrame - if it's an entry frame then report any JNI locals
aoqi@0 1624 // as roots when we find the corresponding native javaVFrame
aoqi@0 1625 frame* fr = vf->frame_pointer();
aoqi@0 1626 assert(fr != NULL, "sanity check");
aoqi@0 1627 if (fr->is_entry_frame()) {
aoqi@0 1628 last_entry_frame = fr;
aoqi@0 1629 }
aoqi@0 1630 }
aoqi@0 1631 vf = vf->sender();
aoqi@0 1632 }
aoqi@0 1633 } else {
aoqi@0 1634 // no last java frame but there may be JNI locals
aoqi@0 1635 java_thread->active_handles()->oops_do(&blk);
aoqi@0 1636 }
aoqi@0 1637 return stack_depth;
aoqi@0 1638 }
aoqi@0 1639
aoqi@0 1640
aoqi@0 1641 // write a HPROF_GC_ROOT_THREAD_OBJ record for each java thread. Then walk
aoqi@0 1642 // the stack so that locals and JNI locals are dumped.
aoqi@0 1643 void VM_HeapDumper::do_threads() {
aoqi@0 1644 for (int i=0; i < _num_threads; i++) {
aoqi@0 1645 JavaThread* thread = _stack_traces[i]->thread();
aoqi@0 1646 oop threadObj = thread->threadObj();
aoqi@0 1647 u4 thread_serial_num = i+1;
aoqi@0 1648 u4 stack_serial_num = thread_serial_num + STACK_TRACE_ID;
aoqi@0 1649 writer()->write_u1(HPROF_GC_ROOT_THREAD_OBJ);
aoqi@0 1650 writer()->write_objectID(threadObj);
aoqi@0 1651 writer()->write_u4(thread_serial_num); // thread number
aoqi@0 1652 writer()->write_u4(stack_serial_num); // stack trace serial number
aoqi@0 1653 int num_frames = do_thread(thread, thread_serial_num);
aoqi@0 1654 assert(num_frames == _stack_traces[i]->get_stack_depth(),
aoqi@0 1655 "total number of Java frames not matched");
aoqi@0 1656 }
aoqi@0 1657 }
aoqi@0 1658
aoqi@0 1659
aoqi@0 1660 // The VM operation that dumps the heap. The dump consists of the following
aoqi@0 1661 // records:
aoqi@0 1662 //
aoqi@0 1663 // HPROF_HEADER
aoqi@0 1664 // [HPROF_UTF8]*
aoqi@0 1665 // [HPROF_LOAD_CLASS]*
aoqi@0 1666 // [[HPROF_FRAME]*|HPROF_TRACE]*
aoqi@0 1667 // [HPROF_GC_CLASS_DUMP]*
aoqi@0 1668 // HPROF_HEAP_DUMP
aoqi@0 1669 //
aoqi@0 1670 // The HPROF_TRACE records represent the stack traces where the heap dump
aoqi@0 1671 // is generated and a "dummy trace" record which does not include
aoqi@0 1672 // any frames. The dummy trace record is used to be referenced as the
aoqi@0 1673 // unknown object alloc site.
aoqi@0 1674 //
aoqi@0 1675 // The HPROF_HEAP_DUMP record has a length following by sub-records. To allow
aoqi@0 1676 // the heap dump be generated in a single pass we remember the position of
aoqi@0 1677 // the dump length and fix it up after all sub-records have been written.
aoqi@0 1678 // To generate the sub-records we iterate over the heap, writing
aoqi@0 1679 // HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP
aoqi@0 1680 // records as we go. Once that is done we write records for some of the GC
aoqi@0 1681 // roots.
aoqi@0 1682
aoqi@0 1683 void VM_HeapDumper::doit() {
aoqi@0 1684
aoqi@0 1685 HandleMark hm;
aoqi@0 1686 CollectedHeap* ch = Universe::heap();
aoqi@0 1687
aoqi@0 1688 ch->ensure_parsability(false); // must happen, even if collection does
aoqi@0 1689 // not happen (e.g. due to GC_locker)
aoqi@0 1690
aoqi@0 1691 if (_gc_before_heap_dump) {
aoqi@0 1692 if (GC_locker::is_active()) {
aoqi@0 1693 warning("GC locker is held; pre-heapdump GC was skipped");
aoqi@0 1694 } else {
aoqi@0 1695 ch->collect_as_vm_thread(GCCause::_heap_dump);
aoqi@0 1696 }
aoqi@0 1697 }
aoqi@0 1698
aoqi@0 1699 // At this point we should be the only dumper active, so
aoqi@0 1700 // the following should be safe.
aoqi@0 1701 set_global_dumper();
aoqi@0 1702 set_global_writer();
aoqi@0 1703
aoqi@0 1704 // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1
aoqi@0 1705 size_t used = ch->used();
aoqi@0 1706 const char* header;
aoqi@0 1707 if (used > (size_t)SegmentedHeapDumpThreshold) {
aoqi@0 1708 set_segmented_dump();
aoqi@0 1709 header = "JAVA PROFILE 1.0.2";
aoqi@0 1710 } else {
aoqi@0 1711 header = "JAVA PROFILE 1.0.1";
aoqi@0 1712 }
aoqi@0 1713
aoqi@0 1714 // header is few bytes long - no chance to overflow int
aoqi@0 1715 writer()->write_raw((void*)header, (int)strlen(header));
aoqi@0 1716 writer()->write_u1(0); // terminator
aoqi@0 1717 writer()->write_u4(oopSize);
aoqi@0 1718 writer()->write_u8(os::javaTimeMillis());
aoqi@0 1719
aoqi@0 1720 // HPROF_UTF8 records
aoqi@0 1721 SymbolTableDumper sym_dumper(writer());
aoqi@0 1722 SymbolTable::symbols_do(&sym_dumper);
aoqi@0 1723
aoqi@0 1724 // write HPROF_LOAD_CLASS records
aoqi@0 1725 ClassLoaderDataGraph::classes_do(&do_load_class);
aoqi@0 1726 Universe::basic_type_classes_do(&do_load_class);
aoqi@0 1727
aoqi@0 1728 // write HPROF_FRAME and HPROF_TRACE records
aoqi@0 1729 // this must be called after _klass_map is built when iterating the classes above.
aoqi@0 1730 dump_stack_traces();
aoqi@0 1731
aoqi@0 1732 // write HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT
aoqi@0 1733 write_dump_header();
aoqi@0 1734
aoqi@0 1735 // Writes HPROF_GC_CLASS_DUMP records
aoqi@0 1736 ClassLoaderDataGraph::classes_do(&do_class_dump);
aoqi@0 1737 Universe::basic_type_classes_do(&do_basic_type_array_class_dump);
aoqi@0 1738 check_segment_length();
aoqi@0 1739
aoqi@0 1740 // writes HPROF_GC_INSTANCE_DUMP records.
aoqi@0 1741 // After each sub-record is written check_segment_length will be invoked. When
aoqi@0 1742 // generated a segmented heap dump this allows us to check if the current
aoqi@0 1743 // segment exceeds a threshold and if so, then a new segment is started.
aoqi@0 1744 // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
aoqi@0 1745 // of the heap dump.
aoqi@0 1746 HeapObjectDumper obj_dumper(this, writer());
aoqi@0 1747 Universe::heap()->safe_object_iterate(&obj_dumper);
aoqi@0 1748
aoqi@0 1749 // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
aoqi@0 1750 do_threads();
aoqi@0 1751 check_segment_length();
aoqi@0 1752
aoqi@0 1753 // HPROF_GC_ROOT_MONITOR_USED
aoqi@0 1754 MonitorUsedDumper mon_dumper(writer());
aoqi@0 1755 ObjectSynchronizer::oops_do(&mon_dumper);
aoqi@0 1756 check_segment_length();
aoqi@0 1757
aoqi@0 1758 // HPROF_GC_ROOT_JNI_GLOBAL
aoqi@0 1759 JNIGlobalsDumper jni_dumper(writer());
aoqi@0 1760 JNIHandles::oops_do(&jni_dumper);
aoqi@0 1761 check_segment_length();
aoqi@0 1762
aoqi@0 1763 // HPROF_GC_ROOT_STICKY_CLASS
aoqi@0 1764 StickyClassDumper class_dumper(writer());
aoqi@0 1765 SystemDictionary::always_strong_classes_do(&class_dumper);
aoqi@0 1766
aoqi@0 1767 // fixes up the length of the dump record. In the case of a segmented
aoqi@0 1768 // heap then the HPROF_HEAP_DUMP_END record is also written.
aoqi@0 1769 end_of_dump();
aoqi@0 1770
aoqi@0 1771 // Now we clear the global variables, so that a future dumper might run.
aoqi@0 1772 clear_global_dumper();
aoqi@0 1773 clear_global_writer();
aoqi@0 1774 }
aoqi@0 1775
aoqi@0 1776 void VM_HeapDumper::dump_stack_traces() {
aoqi@0 1777 // write a HPROF_TRACE record without any frames to be referenced as object alloc sites
aoqi@0 1778 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));
aoqi@0 1779 writer()->write_u4((u4) STACK_TRACE_ID);
aoqi@0 1780 writer()->write_u4(0); // thread number
aoqi@0 1781 writer()->write_u4(0); // frame count
aoqi@0 1782
aoqi@0 1783 _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);
aoqi@0 1784 int frame_serial_num = 0;
aoqi@0 1785 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
aoqi@0 1786 oop threadObj = thread->threadObj();
aoqi@0 1787 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
aoqi@0 1788 // dump thread stack trace
aoqi@0 1789 ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false);
aoqi@0 1790 stack_trace->dump_stack_at_safepoint(-1);
aoqi@0 1791 _stack_traces[_num_threads++] = stack_trace;
aoqi@0 1792
aoqi@0 1793 // write HPROF_FRAME records for this thread's stack trace
aoqi@0 1794 int depth = stack_trace->get_stack_depth();
aoqi@0 1795 int thread_frame_start = frame_serial_num;
aoqi@0 1796 int extra_frames = 0;
aoqi@0 1797 // write fake frame that makes it look like the thread, which caused OOME,
aoqi@0 1798 // is in the OutOfMemoryError zero-parameter constructor
aoqi@0 1799 if (thread == _oome_thread && _oome_constructor != NULL) {
aoqi@0 1800 int oome_serial_num = _klass_map->find(_oome_constructor->method_holder());
aoqi@0 1801 // the class serial number starts from 1
aoqi@0 1802 assert(oome_serial_num > 0, "OutOfMemoryError class not found");
aoqi@0 1803 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, oome_serial_num,
aoqi@0 1804 _oome_constructor, 0);
aoqi@0 1805 extra_frames++;
aoqi@0 1806 }
aoqi@0 1807 for (int j=0; j < depth; j++) {
aoqi@0 1808 StackFrameInfo* frame = stack_trace->stack_frame_at(j);
aoqi@0 1809 Method* m = frame->method();
aoqi@0 1810 int class_serial_num = _klass_map->find(m->method_holder());
aoqi@0 1811 // the class serial number starts from 1
aoqi@0 1812 assert(class_serial_num > 0, "class not found");
aoqi@0 1813 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci());
aoqi@0 1814 }
aoqi@0 1815 depth += extra_frames;
aoqi@0 1816
aoqi@0 1817 // write HPROF_TRACE record for one thread
aoqi@0 1818 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4) + depth*oopSize);
aoqi@0 1819 int stack_serial_num = _num_threads + STACK_TRACE_ID;
aoqi@0 1820 writer()->write_u4(stack_serial_num); // stack trace serial number
aoqi@0 1821 writer()->write_u4((u4) _num_threads); // thread serial number
aoqi@0 1822 writer()->write_u4(depth); // frame count
aoqi@0 1823 for (int j=1; j <= depth; j++) {
aoqi@0 1824 writer()->write_id(thread_frame_start + j);
aoqi@0 1825 }
aoqi@0 1826 }
aoqi@0 1827 }
aoqi@0 1828 }
aoqi@0 1829
aoqi@0 1830 // dump the heap to given path.
aoqi@0 1831 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
aoqi@0 1832 int HeapDumper::dump(const char* path) {
aoqi@0 1833 assert(path != NULL && strlen(path) > 0, "path missing");
aoqi@0 1834
aoqi@0 1835 // print message in interactive case
aoqi@0 1836 if (print_to_tty()) {
aoqi@0 1837 tty->print_cr("Dumping heap to %s ...", path);
aoqi@0 1838 timer()->start();
aoqi@0 1839 }
aoqi@0 1840
aoqi@0 1841 // create the dump writer. If the file can be opened then bail
aoqi@0 1842 DumpWriter writer(path);
aoqi@0 1843 if (!writer.is_open()) {
aoqi@0 1844 set_error(writer.error());
aoqi@0 1845 if (print_to_tty()) {
aoqi@0 1846 tty->print_cr("Unable to create %s: %s", path,
aoqi@0 1847 (error() != NULL) ? error() : "reason unknown");
aoqi@0 1848 }
aoqi@0 1849 return -1;
aoqi@0 1850 }
aoqi@0 1851
aoqi@0 1852 // generate the dump
aoqi@0 1853 VM_HeapDumper dumper(&writer, _gc_before_heap_dump, _oome);
aoqi@0 1854 if (Thread::current()->is_VM_thread()) {
aoqi@0 1855 assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint");
aoqi@0 1856 dumper.doit();
aoqi@0 1857 } else {
aoqi@0 1858 VMThread::execute(&dumper);
aoqi@0 1859 }
aoqi@0 1860
aoqi@0 1861 // close dump file and record any error that the writer may have encountered
aoqi@0 1862 writer.close();
aoqi@0 1863 set_error(writer.error());
aoqi@0 1864
aoqi@0 1865 // print message in interactive case
aoqi@0 1866 if (print_to_tty()) {
aoqi@0 1867 timer()->stop();
aoqi@0 1868 if (error() == NULL) {
aeriksso@8317 1869 tty->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",
aeriksso@8317 1870 writer.bytes_written(), timer()->seconds());
aoqi@0 1871 } else {
aoqi@0 1872 tty->print_cr("Dump file is incomplete: %s", writer.error());
aoqi@0 1873 }
aoqi@0 1874 }
aoqi@0 1875
aoqi@0 1876 return (writer.error() == NULL) ? 0 : -1;
aoqi@0 1877 }
aoqi@0 1878
aoqi@0 1879 // stop timer (if still active), and free any error string we might be holding
aoqi@0 1880 HeapDumper::~HeapDumper() {
aoqi@0 1881 if (timer()->is_active()) {
aoqi@0 1882 timer()->stop();
aoqi@0 1883 }
aoqi@0 1884 set_error(NULL);
aoqi@0 1885 }
aoqi@0 1886
aoqi@0 1887
aoqi@0 1888 // returns the error string (resource allocated), or NULL
aoqi@0 1889 char* HeapDumper::error_as_C_string() const {
aoqi@0 1890 if (error() != NULL) {
aoqi@0 1891 char* str = NEW_RESOURCE_ARRAY(char, strlen(error())+1);
aoqi@0 1892 strcpy(str, error());
aoqi@0 1893 return str;
aoqi@0 1894 } else {
aoqi@0 1895 return NULL;
aoqi@0 1896 }
aoqi@0 1897 }
aoqi@0 1898
aoqi@0 1899 // set the error string
aoqi@0 1900 void HeapDumper::set_error(char* error) {
aoqi@0 1901 if (_error != NULL) {
aoqi@0 1902 os::free(_error);
aoqi@0 1903 }
aoqi@0 1904 if (error == NULL) {
aoqi@0 1905 _error = NULL;
aoqi@0 1906 } else {
aoqi@0 1907 _error = os::strdup(error);
aoqi@0 1908 assert(_error != NULL, "allocation failure");
aoqi@0 1909 }
aoqi@0 1910 }
aoqi@0 1911
aoqi@0 1912 // Called by out-of-memory error reporting by a single Java thread
aoqi@0 1913 // outside of a JVM safepoint
aoqi@0 1914 void HeapDumper::dump_heap_from_oome() {
aoqi@0 1915 HeapDumper::dump_heap(true);
aoqi@0 1916 }
aoqi@0 1917
aoqi@0 1918 // Called by error reporting by a single Java thread outside of a JVM safepoint,
aoqi@0 1919 // or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various
aoqi@0 1920 // callers are strictly serialized and guaranteed not to interfere below. For more
aoqi@0 1921 // general use, however, this method will need modification to prevent
aoqi@0 1922 // inteference when updating the static variables base_path and dump_file_seq below.
aoqi@0 1923 void HeapDumper::dump_heap() {
aoqi@0 1924 HeapDumper::dump_heap(false);
aoqi@0 1925 }
aoqi@0 1926
aoqi@0 1927 void HeapDumper::dump_heap(bool oome) {
aoqi@0 1928 static char base_path[JVM_MAXPATHLEN] = {'\0'};
aoqi@0 1929 static uint dump_file_seq = 0;
aoqi@0 1930 char* my_path;
aoqi@0 1931 const int max_digit_chars = 20;
aoqi@0 1932
aoqi@0 1933 const char* dump_file_name = "java_pid";
aoqi@0 1934 const char* dump_file_ext = ".hprof";
aoqi@0 1935
aoqi@0 1936 // The dump file defaults to java_pid<pid>.hprof in the current working
aoqi@0 1937 // directory. HeapDumpPath=<file> can be used to specify an alternative
aoqi@0 1938 // dump file name or a directory where dump file is created.
aoqi@0 1939 if (dump_file_seq == 0) { // first time in, we initialize base_path
aoqi@0 1940 // Calculate potentially longest base path and check if we have enough
aoqi@0 1941 // allocated statically.
aoqi@0 1942 const size_t total_length =
aoqi@0 1943 (HeapDumpPath == NULL ? 0 : strlen(HeapDumpPath)) +
aoqi@0 1944 strlen(os::file_separator()) + max_digit_chars +
aoqi@0 1945 strlen(dump_file_name) + strlen(dump_file_ext) + 1;
aoqi@0 1946 if (total_length > sizeof(base_path)) {
aoqi@0 1947 warning("Cannot create heap dump file. HeapDumpPath is too long.");
aoqi@0 1948 return;
aoqi@0 1949 }
aoqi@0 1950
aoqi@0 1951 bool use_default_filename = true;
aoqi@0 1952 if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
aoqi@0 1953 // HeapDumpPath=<file> not specified
aoqi@0 1954 } else {
aoqi@0 1955 strncpy(base_path, HeapDumpPath, sizeof(base_path));
aoqi@0 1956 // check if the path is a directory (must exist)
aoqi@0 1957 DIR* dir = os::opendir(base_path);
aoqi@0 1958 if (dir == NULL) {
aoqi@0 1959 use_default_filename = false;
aoqi@0 1960 } else {
aoqi@0 1961 // HeapDumpPath specified a directory. We append a file separator
aoqi@0 1962 // (if needed).
aoqi@0 1963 os::closedir(dir);
aoqi@0 1964 size_t fs_len = strlen(os::file_separator());
aoqi@0 1965 if (strlen(base_path) >= fs_len) {
aoqi@0 1966 char* end = base_path;
aoqi@0 1967 end += (strlen(base_path) - fs_len);
aoqi@0 1968 if (strcmp(end, os::file_separator()) != 0) {
aoqi@0 1969 strcat(base_path, os::file_separator());
aoqi@0 1970 }
aoqi@0 1971 }
aoqi@0 1972 }
aoqi@0 1973 }
aoqi@0 1974 // If HeapDumpPath wasn't a file name then we append the default name
aoqi@0 1975 if (use_default_filename) {
aoqi@0 1976 const size_t dlen = strlen(base_path); // if heap dump dir specified
aoqi@0 1977 jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s",
aoqi@0 1978 dump_file_name, os::current_process_id(), dump_file_ext);
aoqi@0 1979 }
aoqi@0 1980 const size_t len = strlen(base_path) + 1;
aoqi@0 1981 my_path = (char*)os::malloc(len, mtInternal);
aoqi@0 1982 if (my_path == NULL) {
aoqi@0 1983 warning("Cannot create heap dump file. Out of system memory.");
aoqi@0 1984 return;
aoqi@0 1985 }
aoqi@0 1986 strncpy(my_path, base_path, len);
aoqi@0 1987 } else {
aoqi@0 1988 // Append a sequence number id for dumps following the first
aoqi@0 1989 const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0
aoqi@0 1990 my_path = (char*)os::malloc(len, mtInternal);
aoqi@0 1991 if (my_path == NULL) {
aoqi@0 1992 warning("Cannot create heap dump file. Out of system memory.");
aoqi@0 1993 return;
aoqi@0 1994 }
aoqi@0 1995 jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq);
aoqi@0 1996 }
aoqi@0 1997 dump_file_seq++; // increment seq number for next time we dump
aoqi@0 1998
aoqi@0 1999 HeapDumper dumper(false /* no GC before heap dump */,
aoqi@0 2000 true /* send to tty */,
aoqi@0 2001 oome /* pass along out-of-memory-error flag */);
aoqi@0 2002 dumper.dump(my_path);
aoqi@0 2003 os::free(my_path);
aoqi@0 2004 }

mercurial