src/share/vm/services/heapDumper.cpp

changeset 8317
ebd6745380b9
parent 6680
78bbf4d43a14
child 8420
b5c3e9670fa0
     1.1 --- a/src/share/vm/services/heapDumper.cpp	Tue Mar 01 12:50:37 2016 +0530
     1.2 +++ b/src/share/vm/services/heapDumper.cpp	Fri Mar 04 16:40:30 2016 +0100
     1.3 @@ -376,11 +376,11 @@
     1.4    };
     1.5  
     1.6    int _fd;              // file descriptor (-1 if dump file not open)
     1.7 -  jlong _bytes_written; // number of byte written to dump file
     1.8 +  julong _bytes_written; // number of byte written to dump file
     1.9  
    1.10    char* _buffer;    // internal buffer
    1.11 -  int _size;
    1.12 -  int _pos;
    1.13 +  size_t _size;
    1.14 +  size_t _pos;
    1.15  
    1.16    char* _error;   // error message when I/O fails
    1.17  
    1.18 @@ -388,14 +388,14 @@
    1.19    int file_descriptor() const                   { return _fd; }
    1.20  
    1.21    char* buffer() const                          { return _buffer; }
    1.22 -  int buffer_size() const                       { return _size; }
    1.23 -  int position() const                          { return _pos; }
    1.24 -  void set_position(int pos)                    { _pos = pos; }
    1.25 +  size_t buffer_size() const                    { return _size; }
    1.26 +  size_t position() const                       { return _pos; }
    1.27 +  void set_position(size_t pos)                 { _pos = pos; }
    1.28  
    1.29    void set_error(const char* error)             { _error = (char*)os::strdup(error); }
    1.30  
    1.31    // all I/O go through this function
    1.32 -  void write_internal(void* s, int len);
    1.33 +  void write_internal(void* s, size_t len);
    1.34  
    1.35   public:
    1.36    DumpWriter(const char* path);
    1.37 @@ -406,14 +406,14 @@
    1.38    void flush();
    1.39  
    1.40    // total number of bytes written to the disk
    1.41 -  jlong bytes_written() const           { return _bytes_written; }
    1.42 +  julong bytes_written() const          { return _bytes_written; }
    1.43  
    1.44    // adjust the number of bytes written to disk (used to keep the count
    1.45    // of the number of bytes written in case of rewrites)
    1.46 -  void adjust_bytes_written(jlong n)     { _bytes_written += n; }
    1.47 +  void adjust_bytes_written(jlong n)    { _bytes_written += n; }
    1.48  
    1.49    // number of (buffered) bytes as yet unwritten to the dump file
    1.50 -  jlong bytes_unwritten() const          { return (jlong)position(); }
    1.51 +  size_t bytes_unwritten() const        { return position(); }
    1.52  
    1.53    char* error() const                   { return _error; }
    1.54  
    1.55 @@ -421,7 +421,7 @@
    1.56    void seek_to_offset(jlong pos);
    1.57  
    1.58    // writer functions
    1.59 -  void write_raw(void* s, int len);
    1.60 +  void write_raw(void* s, size_t len);
    1.61    void write_u1(u1 x)                   { write_raw((void*)&x, 1); }
    1.62    void write_u2(u2 x);
    1.63    void write_u4(u4 x);
    1.64 @@ -468,35 +468,40 @@
    1.65    // flush and close dump file
    1.66    if (is_open()) {
    1.67      flush();
    1.68 -    ::close(file_descriptor());
    1.69 +    os::close(file_descriptor());
    1.70      set_file_descriptor(-1);
    1.71    }
    1.72  }
    1.73  
    1.74  // write directly to the file
    1.75 -void DumpWriter::write_internal(void* s, int len) {
    1.76 +void DumpWriter::write_internal(void* s, size_t len) {
    1.77    if (is_open()) {
    1.78 -    int n = ::write(file_descriptor(), s, len);
    1.79 -    if (n > 0) {
    1.80 +    const char* pos = (char*)s;
    1.81 +    ssize_t n = 0;
    1.82 +    while (len > 0) {
    1.83 +      uint tmp = (uint)MIN2(len, (size_t)UINT_MAX);
    1.84 +      n = os::write(file_descriptor(), pos, tmp);
    1.85 +
    1.86 +      if (n < 0) {
    1.87 +        // EINTR cannot happen here, os::write will take care of that
    1.88 +        set_error(strerror(errno));
    1.89 +        os::close(file_descriptor());
    1.90 +        set_file_descriptor(-1);
    1.91 +        return;
    1.92 +      }
    1.93 +
    1.94        _bytes_written += n;
    1.95 -    }
    1.96 -    if (n != len) {
    1.97 -      if (n < 0) {
    1.98 -        set_error(strerror(errno));
    1.99 -      } else {
   1.100 -        set_error("file size limit");
   1.101 -      }
   1.102 -      ::close(file_descriptor());
   1.103 -      set_file_descriptor(-1);
   1.104 +      pos += n;
   1.105 +      len -= n;
   1.106      }
   1.107    }
   1.108  }
   1.109  
   1.110  // write raw bytes
   1.111 -void DumpWriter::write_raw(void* s, int len) {
   1.112 +void DumpWriter::write_raw(void* s, size_t len) {
   1.113    if (is_open()) {
   1.114 -    // flush buffer to make toom
   1.115 -    if ((position()+ len) >= buffer_size()) {
   1.116 +    // flush buffer to make room
   1.117 +    if ((position() + len) >= buffer_size()) {
   1.118        flush();
   1.119      }
   1.120  
   1.121 @@ -519,13 +524,12 @@
   1.122    }
   1.123  }
   1.124  
   1.125 -
   1.126  jlong DumpWriter::current_offset() {
   1.127    if (is_open()) {
   1.128      // the offset is the file offset plus whatever we have buffered
   1.129      jlong offset = os::current_file_offset(file_descriptor());
   1.130      assert(offset >= 0, "lseek failed");
   1.131 -    return offset + (jlong)position();
   1.132 +    return offset + position();
   1.133    } else {
   1.134      return (jlong)-1;
   1.135    }
   1.136 @@ -774,7 +778,7 @@
   1.137    HandleMark hm;
   1.138    instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
   1.139  
   1.140 -  int size = 0;
   1.141 +  u4 size = 0;
   1.142  
   1.143    for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {
   1.144      if (!fld.access_flags().is_static()) {
   1.145 @@ -799,7 +803,7 @@
   1.146        }
   1.147      }
   1.148    }
   1.149 -  return (u4)size;
   1.150 +  return size;
   1.151  }
   1.152  
   1.153  // dumps static fields of the given class
   1.154 @@ -1031,8 +1035,7 @@
   1.155    }
   1.156  
   1.157    // If the byte ordering is big endian then we can copy most types directly
   1.158 -  int length_in_bytes = array->length() * type2aelembytes(type);
   1.159 -  assert(length_in_bytes > 0, "nothing to copy");
   1.160 +  u4 length_in_bytes = (u4)array->length() * type2aelembytes(type);
   1.161  
   1.162    switch (type) {
   1.163      case T_INT : {
   1.164 @@ -1285,22 +1288,18 @@
   1.165      }
   1.166    }
   1.167  
   1.168 -  // create a HPROF_GC_INSTANCE record for each object
   1.169    if (o->is_instance()) {
   1.170 +    // create a HPROF_GC_INSTANCE record for each object
   1.171      DumperSupport::dump_instance(writer(), o);
   1.172      mark_end_of_record();
   1.173 -  } else {
   1.174 +  } else if (o->is_objArray()) {
   1.175      // create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array
   1.176 -    if (o->is_objArray()) {
   1.177 -      DumperSupport::dump_object_array(writer(), objArrayOop(o));
   1.178 -      mark_end_of_record();
   1.179 -    } else {
   1.180 -      // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
   1.181 -      if (o->is_typeArray()) {
   1.182 -        DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
   1.183 -        mark_end_of_record();
   1.184 -      }
   1.185 -    }
   1.186 +    DumperSupport::dump_object_array(writer(), objArrayOop(o));
   1.187 +    mark_end_of_record();
   1.188 +  } else if (o->is_typeArray()) {
   1.189 +    // create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array
   1.190 +    DumperSupport::dump_prim_array(writer(), typeArrayOop(o));
   1.191 +    mark_end_of_record();
   1.192    }
   1.193  }
   1.194  
   1.195 @@ -1448,11 +1447,11 @@
   1.196      assert(dump_start() >= 0, "no dump start recorded");
   1.197  
   1.198      // calculate the size of the dump record
   1.199 -    jlong dump_end = writer()->current_offset();
   1.200 -    jlong dump_len = (dump_end - dump_start() - 4);
   1.201 +    julong dump_end = writer()->current_offset();
   1.202 +    julong dump_len = (dump_end - dump_start() - 4);
   1.203  
   1.204      // record length must fit in a u4
   1.205 -    if (dump_len > (jlong)(4L*(jlong)G)) {
   1.206 +    if (dump_len > max_juint) {
   1.207        warning("record is too large");
   1.208      }
   1.209  
   1.210 @@ -1461,7 +1460,7 @@
   1.211      writer()->write_u4((u4)dump_len);
   1.212  
   1.213      // adjust the total size written to keep the bytes written correct.
   1.214 -    writer()->adjust_bytes_written(-((long) sizeof(u4)));
   1.215 +    writer()->adjust_bytes_written(-((jlong) sizeof(u4)));
   1.216  
   1.217      // seek to dump end so we can continue
   1.218      writer()->seek_to_offset(dump_end);
   1.219 @@ -1477,12 +1476,12 @@
   1.220    if (writer()->is_open()) {
   1.221      if (is_segmented_dump()) {
   1.222        // don't use current_offset that would be too expensive on a per record basis
   1.223 -      jlong dump_end = writer()->bytes_written() + writer()->bytes_unwritten();
   1.224 -      assert(dump_end == writer()->current_offset(), "checking");
   1.225 -      jlong dump_len = (dump_end - dump_start() - 4);
   1.226 -      assert(dump_len >= 0 && dump_len <= max_juint, "bad dump length");
   1.227 +      julong dump_end = writer()->bytes_written() + writer()->bytes_unwritten();
   1.228 +      assert(dump_end == (julong)writer()->current_offset(), "checking");
   1.229 +      julong dump_len = (dump_end - dump_start() - 4);
   1.230 +      assert(dump_len <= max_juint, "bad dump length");
   1.231  
   1.232 -      if (dump_len > (jlong)HeapDumpSegmentSize) {
   1.233 +      if (dump_len > HeapDumpSegmentSize) {
   1.234          write_current_dump_record_length();
   1.235          write_dump_header();
   1.236        }
   1.237 @@ -1868,13 +1867,8 @@
   1.238    if (print_to_tty()) {
   1.239      timer()->stop();
   1.240      if (error() == NULL) {
   1.241 -      char msg[256];
   1.242 -      sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]",
   1.243 -        JLONG_FORMAT, timer()->seconds());
   1.244 -PRAGMA_DIAG_PUSH
   1.245 -PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
   1.246 -      tty->print_cr(msg, writer.bytes_written());
   1.247 -PRAGMA_DIAG_POP
   1.248 +      tty->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",
   1.249 +                    writer.bytes_written(), timer()->seconds());
   1.250      } else {
   1.251        tty->print_cr("Dump file is incomplete: %s", writer.error());
   1.252      }

mercurial