comparison src/share/vm/services/heapDumper.cpp @ 23974:f13e777eb255

Merge with jdk8u111-b14
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Wed, 16 Nov 2016 12:32:54 -0800
parents 52b4284cb496 b5c3e9670fa0
children
comparison
equal deleted inserted replaced
23792:3953f8820df8 23974:f13e777eb255
374 enum { 374 enum {
375 io_buffer_size = 8*M 375 io_buffer_size = 8*M
376 }; 376 };
377 377
378 int _fd; // file descriptor (-1 if dump file not open) 378 int _fd; // file descriptor (-1 if dump file not open)
379 jlong _bytes_written; // number of byte written to dump file 379 julong _bytes_written; // number of byte written to dump file
380 380
381 char* _buffer; // internal buffer 381 char* _buffer; // internal buffer
382 int _size; 382 size_t _size;
383 int _pos; 383 size_t _pos;
384 384
385 char* _error; // error message when I/O fails 385 char* _error; // error message when I/O fails
386 386
387 void set_file_descriptor(int fd) { _fd = fd; } 387 void set_file_descriptor(int fd) { _fd = fd; }
388 int file_descriptor() const { return _fd; } 388 int file_descriptor() const { return _fd; }
389 389
390 char* buffer() const { return _buffer; } 390 char* buffer() const { return _buffer; }
391 int buffer_size() const { return _size; } 391 size_t buffer_size() const { return _size; }
392 int position() const { return _pos; } 392 size_t position() const { return _pos; }
393 void set_position(int pos) { _pos = pos; } 393 void set_position(size_t pos) { _pos = pos; }
394 394
395 void set_error(const char* error) { _error = (char*)os::strdup(error); } 395 void set_error(const char* error) { _error = (char*)os::strdup(error); }
396 396
397 // all I/O go through this function 397 // all I/O go through this function
398 void write_internal(void* s, int len); 398 void write_internal(void* s, size_t len);
399 399
400 public: 400 public:
401 DumpWriter(const char* path); 401 DumpWriter(const char* path);
402 ~DumpWriter(); 402 ~DumpWriter();
403 403
404 void close(); 404 void close();
405 bool is_open() const { return file_descriptor() >= 0; } 405 bool is_open() const { return file_descriptor() >= 0; }
406 void flush(); 406 void flush();
407 407
408 // total number of bytes written to the disk 408 // total number of bytes written to the disk
409 jlong bytes_written() const { return _bytes_written; } 409 julong bytes_written() const { return _bytes_written; }
410 410
411 // adjust the number of bytes written to disk (used to keep the count 411 // adjust the number of bytes written to disk (used to keep the count
412 // of the number of bytes written in case of rewrites) 412 // of the number of bytes written in case of rewrites)
413 void adjust_bytes_written(jlong n) { _bytes_written += n; } 413 void adjust_bytes_written(jlong n) { _bytes_written += n; }
414 414
415 // number of (buffered) bytes as yet unwritten to the dump file 415 // number of (buffered) bytes as yet unwritten to the dump file
416 jlong bytes_unwritten() const { return (jlong)position(); } 416 size_t bytes_unwritten() const { return position(); }
417 417
418 char* error() const { return _error; } 418 char* error() const { return _error; }
419 419
420 jlong current_offset(); 420 jlong current_offset();
421 void seek_to_offset(jlong pos); 421 void seek_to_offset(jlong pos);
422 422
423 // writer functions 423 // writer functions
424 void write_raw(void* s, int len); 424 void write_raw(void* s, size_t len);
425 void write_u1(u1 x) { write_raw((void*)&x, 1); } 425 void write_u1(u1 x) { write_raw((void*)&x, 1); }
426 void write_u2(u2 x); 426 void write_u2(u2 x);
427 void write_u4(u4 x); 427 void write_u4(u4 x);
428 void write_u8(u8 x); 428 void write_u8(u8 x);
429 void write_objectID(oop o); 429 void write_objectID(oop o);
472 set_file_descriptor(-1); 472 set_file_descriptor(-1);
473 } 473 }
474 } 474 }
475 475
476 // write directly to the file 476 // write directly to the file
477 void DumpWriter::write_internal(void* s, int len) { 477 void DumpWriter::write_internal(void* s, size_t len) {
478 if (is_open()) { 478 if (is_open()) {
479 int n = ::write(file_descriptor(), s, len); 479 const char* pos = (char*)s;
480 if (n > 0) { 480 ssize_t n = 0;
481 _bytes_written += n; 481 while (len > 0) {
482 } 482 uint tmp = (uint)MIN2(len, (size_t)UINT_MAX);
483 if (n != len) { 483 n = ::write(file_descriptor(), pos, tmp);
484
484 if (n < 0) { 485 if (n < 0) {
485 set_error(strerror(errno)); 486 set_error(strerror(errno));
486 } else { 487 ::close(file_descriptor());
487 set_error("file size limit"); 488 set_file_descriptor(-1);
489 return;
488 } 490 }
489 ::close(file_descriptor()); 491
490 set_file_descriptor(-1); 492 _bytes_written += n;
493 pos += n;
494 len -= n;
491 } 495 }
492 } 496 }
493 } 497 }
494 498
495 // write raw bytes 499 // write raw bytes
496 void DumpWriter::write_raw(void* s, int len) { 500 void DumpWriter::write_raw(void* s, size_t len) {
497 if (is_open()) { 501 if (is_open()) {
498 // flush buffer to make toom 502 // flush buffer to make room
499 if ((position()+ len) >= buffer_size()) { 503 if ((position() + len) >= buffer_size()) {
500 flush(); 504 flush();
501 } 505 }
502 506
503 // buffer not available or too big to buffer it 507 // buffer not available or too big to buffer it
504 if ((buffer() == NULL) || (len >= buffer_size())) { 508 if ((buffer() == NULL) || (len >= buffer_size())) {
517 write_internal(buffer(), position()); 521 write_internal(buffer(), position());
518 set_position(0); 522 set_position(0);
519 } 523 }
520 } 524 }
521 525
522
523 jlong DumpWriter::current_offset() { 526 jlong DumpWriter::current_offset() {
524 if (is_open()) { 527 if (is_open()) {
525 // the offset is the file offset plus whatever we have buffered 528 // the offset is the file offset plus whatever we have buffered
526 jlong offset = os::current_file_offset(file_descriptor()); 529 jlong offset = os::current_file_offset(file_descriptor());
527 assert(offset >= 0, "lseek failed"); 530 assert(offset >= 0, "lseek failed");
528 return offset + (jlong)position(); 531 return offset + position();
529 } else { 532 } else {
530 return (jlong)-1; 533 return (jlong)-1;
531 } 534 }
532 } 535 }
533 536
772 // returns the size of the instance of the given class 775 // returns the size of the instance of the given class
773 u4 DumperSupport::instance_size(Klass* k) { 776 u4 DumperSupport::instance_size(Klass* k) {
774 HandleMark hm; 777 HandleMark hm;
775 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); 778 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
776 779
777 int size = 0; 780 u4 size = 0;
778 781
779 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) { 782 for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
780 if (!fld.access_flags().is_static()) { 783 if (!fld.access_flags().is_static()) {
781 Symbol* sig = fld.signature(); 784 Symbol* sig = fld.signature();
782 switch (sig->byte_at(0)) { 785 switch (sig->byte_at(0)) {
797 800
798 default : ShouldNotReachHere(); 801 default : ShouldNotReachHere();
799 } 802 }
800 } 803 }
801 } 804 }
802 return (u4)size; 805 return size;
803 } 806 }
804 807
805 // dumps static fields of the given class 808 // dumps static fields of the given class
806 void DumperSupport::dump_static_fields(DumpWriter* writer, Klass* k) { 809 void DumperSupport::dump_static_fields(DumpWriter* writer, Klass* k) {
807 HandleMark hm; 810 HandleMark hm;
1029 if (array->length() == 0) { 1032 if (array->length() == 0) {
1030 return; 1033 return;
1031 } 1034 }
1032 1035
1033 // If the byte ordering is big endian then we can copy most types directly 1036 // If the byte ordering is big endian then we can copy most types directly
1034 int length_in_bytes = array->length() * type2aelembytes(type); 1037 u4 length_in_bytes = (u4)array->length() * type2aelembytes(type);
1035 assert(length_in_bytes > 0, "nothing to copy");
1036 1038
1037 switch (type) { 1039 switch (type) {
1038 case T_INT : { 1040 case T_INT : {
1039 if (Bytes::is_Java_byte_ordering_different()) { 1041 if (Bytes::is_Java_byte_ordering_different()) {
1040 WRITE_ARRAY(array, int, u4); 1042 WRITE_ARRAY(array, int, u4);
1283 if (!java_lang_Class::is_primitive(o)) { 1285 if (!java_lang_Class::is_primitive(o)) {
1284 return; 1286 return;
1285 } 1287 }
1286 } 1288 }
1287 1289
1288 // create a HPROF_GC_INSTANCE record for each object
1289 if (o->is_instance()) { 1290 if (o->is_instance()) {
1291 // create a HPROF_GC_INSTANCE record for each object
1290 DumperSupport::dump_instance(writer(), o); 1292 DumperSupport::dump_instance(writer(), o);
1291 mark_end_of_record(); 1293 mark_end_of_record();
1292 } else { 1294 } else if (o->is_objArray()) {
1293 // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array 1295 // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
1294 if (o->is_objArray()) { 1296 DumperSupport::dump_object_array(writer(), objArrayOop(o));
1295 DumperSupport::dump_object_array(writer(), objArrayOop(o)); 1297 mark_end_of_record();
1296 mark_end_of_record(); 1298 } else if (o->is_typeArray()) {
1297 } else { 1299 // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
1298 // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array 1300 DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
1299 if (o->is_typeArray()) { 1301 mark_end_of_record();
1300 DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
1301 mark_end_of_record();
1302 }
1303 }
1304 } 1302 }
1305 } 1303 }
1306 1304
1307 // The VM operation that performs the heap dump 1305 // The VM operation that performs the heap dump
1308 class VM_HeapDumper : public VM_GC_Operation { 1306 class VM_HeapDumper : public VM_GC_Operation {
1446 void VM_HeapDumper::write_current_dump_record_length() { 1444 void VM_HeapDumper::write_current_dump_record_length() {
1447 if (writer()->is_open()) { 1445 if (writer()->is_open()) {
1448 assert(dump_start() >= 0, "no dump start recorded"); 1446 assert(dump_start() >= 0, "no dump start recorded");
1449 1447
1450 // calculate the size of the dump record 1448 // calculate the size of the dump record
1451 jlong dump_end = writer()->current_offset(); 1449 julong dump_end = writer()->current_offset();
1452 jlong dump_len = (dump_end - dump_start() - 4); 1450 julong dump_len = (dump_end - dump_start() - 4);
1453 1451
1454 // record length must fit in a u4 1452 // record length must fit in a u4
1455 if (dump_len > (jlong)(4L*(jlong)G)) { 1453 if (dump_len > max_juint) {
1456 warning("record is too large"); 1454 warning("record is too large");
1457 } 1455 }
1458 1456
1459 // seek to the dump start and fix-up the length 1457 // seek to the dump start and fix-up the length
1460 writer()->seek_to_offset(dump_start()); 1458 writer()->seek_to_offset(dump_start());
1461 writer()->write_u4((u4)dump_len); 1459 writer()->write_u4((u4)dump_len);
1462 1460
1463 // adjust the total size written to keep the bytes written correct. 1461 // adjust the total size written to keep the bytes written correct.
1464 writer()->adjust_bytes_written(-((long) sizeof(u4))); 1462 writer()->adjust_bytes_written(-((jlong) sizeof(u4)));
1465 1463
1466 // seek to dump end so we can continue 1464 // seek to dump end so we can continue
1467 writer()->seek_to_offset(dump_end); 1465 writer()->seek_to_offset(dump_end);
1468 1466
1469 // no current dump record 1467 // no current dump record
1475 // new segment. 1473 // new segment.
1476 void VM_HeapDumper::check_segment_length() { 1474 void VM_HeapDumper::check_segment_length() {
1477 if (writer()->is_open()) { 1475 if (writer()->is_open()) {
1478 if (is_segmented_dump()) { 1476 if (is_segmented_dump()) {
1479 // don't use current_offset that would be too expensive on a per record basis 1477 // don't use current_offset that would be too expensive on a per record basis
1480 jlong dump_end = writer()->bytes_written() + writer()->bytes_unwritten(); 1478 julong dump_end = writer()->bytes_written() + writer()->bytes_unwritten();
1481 assert(dump_end == writer()->current_offset(), "checking"); 1479 assert(dump_end == (julong)writer()->current_offset(), "checking");
1482 jlong dump_len = (dump_end - dump_start() - 4); 1480 julong dump_len = (dump_end - dump_start() - 4);
1483 assert(dump_len >= 0 && dump_len <= max_juint, "bad dump length"); 1481 assert(dump_len <= max_juint, "bad dump length");
1484 1482
1485 if (dump_len > (jlong)HeapDumpSegmentSize) { 1483 if (dump_len > HeapDumpSegmentSize) {
1486 write_current_dump_record_length(); 1484 write_current_dump_record_length();
1487 write_dump_header(); 1485 write_dump_header();
1488 } 1486 }
1489 } 1487 }
1490 } 1488 }
1866 1864
1867 // print message in interactive case 1865 // print message in interactive case
1868 if (print_to_tty()) { 1866 if (print_to_tty()) {
1869 timer()->stop(); 1867 timer()->stop();
1870 if (error() == NULL) { 1868 if (error() == NULL) {
1871 char msg[256]; 1869 tty->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",
1872 sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]", 1870 writer.bytes_written(), timer()->seconds());
1873 JLONG_FORMAT, timer()->seconds());
1874 PRAGMA_DIAG_PUSH
1875 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
1876 tty->print_cr(msg, writer.bytes_written());
1877 PRAGMA_DIAG_POP
1878 } else { 1871 } else {
1879 tty->print_cr("Dump file is incomplete: %s", writer.error()); 1872 tty->print_cr("Dump file is incomplete: %s", writer.error());
1880 } 1873 }
1881 } 1874 }
1882 1875