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 }