File: | jdk/src/hotspot/share/utilities/ostream.cpp |
Warning: | line 617, column 12 Value stored to 'count' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "jvm.h" |
27 | #include "cds/classListWriter.hpp" |
28 | #include "compiler/compileLog.hpp" |
29 | #include "memory/allocation.inline.hpp" |
30 | #include "oops/oop.inline.hpp" |
31 | #include "runtime/arguments.hpp" |
32 | #include "runtime/os.inline.hpp" |
33 | #include "runtime/orderAccess.hpp" |
34 | #include "runtime/safepoint.hpp" |
35 | #include "runtime/vm_version.hpp" |
36 | #include "utilities/defaultStream.hpp" |
37 | #include "utilities/macros.hpp" |
38 | #include "utilities/ostream.hpp" |
39 | #include "utilities/vmError.hpp" |
40 | #include "utilities/xmlstream.hpp" |
41 | |
42 | // Declarations of jvm methods |
43 | extern "C" void jio_print(const char* s, size_t len); |
44 | extern "C" int jio_printf(const char *fmt, ...); |
45 | |
46 | outputStream::outputStream(int width) { |
47 | _width = width; |
48 | _position = 0; |
49 | _newlines = 0; |
50 | _precount = 0; |
51 | _indentation = 0; |
52 | _scratch = NULL__null; |
53 | _scratch_len = 0; |
54 | } |
55 | |
56 | outputStream::outputStream(int width, bool has_time_stamps) { |
57 | _width = width; |
58 | _position = 0; |
59 | _newlines = 0; |
60 | _precount = 0; |
61 | _indentation = 0; |
62 | _scratch = NULL__null; |
63 | _scratch_len = 0; |
64 | if (has_time_stamps) _stamp.update(); |
65 | } |
66 | |
67 | void outputStream::update_position(const char* s, size_t len) { |
68 | for (size_t i = 0; i < len; i++) { |
69 | char ch = s[i]; |
70 | if (ch == '\n') { |
71 | _newlines += 1; |
72 | _precount += _position + 1; |
73 | _position = 0; |
74 | } else if (ch == '\t') { |
75 | int tw = 8 - (_position & 7); |
76 | _position += tw; |
77 | _precount -= tw-1; // invariant: _precount + _position == total count |
78 | } else { |
79 | _position += 1; |
80 | } |
81 | } |
82 | } |
83 | |
84 | // Execute a vsprintf, using the given buffer if necessary. |
85 | // Return a pointer to the formatted string. |
86 | const char* outputStream::do_vsnprintf(char* buffer, size_t buflen, |
87 | const char* format, va_list ap, |
88 | bool add_cr, |
89 | size_t& result_len) { |
90 | assert(buflen >= 2, "buffer too small")do { if (!(buflen >= 2)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 90, "assert(" "buflen >= 2" ") failed", "buffer too small" ); ::breakpoint(); } } while (0); |
91 | |
92 | const char* result; |
93 | if (add_cr) buflen--; |
94 | if (!strchr(format, '%')) { |
95 | // constant format string |
96 | result = format; |
97 | result_len = strlen(result); |
98 | if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate |
99 | } else if (format[0] == '%' && format[1] == 's' && format[2] == '\0') { |
100 | // trivial copy-through format string |
101 | result = va_arg(ap, const char*)__builtin_va_arg(ap, const char*); |
102 | result_len = strlen(result); |
103 | if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate |
104 | } else { |
105 | int required_len = os::vsnprintf(buffer, buflen, format, ap); |
106 | assert(required_len >= 0, "vsnprintf encoding error")do { if (!(required_len >= 0)) { (*g_assert_poison) = 'X'; ; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 106, "assert(" "required_len >= 0" ") failed", "vsnprintf encoding error" ); ::breakpoint(); } } while (0); |
107 | result = buffer; |
108 | if ((size_t)required_len < buflen) { |
109 | result_len = required_len; |
110 | } else { |
111 | DEBUG_ONLY(warning("outputStream::do_vsnprintf output truncated -- buffer length is %d bytes but %d bytes are needed.",warning("outputStream::do_vsnprintf output truncated -- buffer length is %d bytes but %d bytes are needed." , add_cr ? (int)buflen + 1 : (int)buflen, add_cr ? required_len + 2 : required_len + 1); |
112 | add_cr ? (int)buflen + 1 : (int)buflen, add_cr ? required_len + 2 : required_len + 1);)warning("outputStream::do_vsnprintf output truncated -- buffer length is %d bytes but %d bytes are needed." , add_cr ? (int)buflen + 1 : (int)buflen, add_cr ? required_len + 2 : required_len + 1); |
113 | result_len = buflen - 1; |
114 | } |
115 | } |
116 | if (add_cr) { |
117 | if (result != buffer) { |
118 | memcpy(buffer, result, result_len); |
119 | result = buffer; |
120 | } |
121 | buffer[result_len++] = '\n'; |
122 | buffer[result_len] = 0; |
123 | } |
124 | return result; |
125 | } |
126 | |
127 | void outputStream::do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) { |
128 | char buffer[O_BUFLEN2000]; |
129 | size_t len; |
130 | const char* str = do_vsnprintf(buffer, sizeof(buffer), format, ap, add_cr, len); |
131 | write(str, len); |
132 | } |
133 | |
134 | void outputStream::do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) { |
135 | size_t len; |
136 | const char* str = do_vsnprintf(_scratch, _scratch_len, format, ap, add_cr, len); |
137 | write(str, len); |
138 | } |
139 | |
140 | void outputStream::do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) { |
141 | if (_scratch) { |
142 | do_vsnprintf_and_write_with_scratch_buffer(format, ap, add_cr); |
143 | } else { |
144 | do_vsnprintf_and_write_with_automatic_buffer(format, ap, add_cr); |
145 | } |
146 | } |
147 | |
148 | void outputStream::print(const char* format, ...) { |
149 | va_list ap; |
150 | va_start(ap, format)__builtin_va_start(ap, format); |
151 | do_vsnprintf_and_write(format, ap, false); |
152 | va_end(ap)__builtin_va_end(ap); |
153 | } |
154 | |
155 | void outputStream::print_cr(const char* format, ...) { |
156 | va_list ap; |
157 | va_start(ap, format)__builtin_va_start(ap, format); |
158 | do_vsnprintf_and_write(format, ap, true); |
159 | va_end(ap)__builtin_va_end(ap); |
160 | } |
161 | |
162 | void outputStream::vprint(const char *format, va_list argptr) { |
163 | do_vsnprintf_and_write(format, argptr, false); |
164 | } |
165 | |
166 | void outputStream::vprint_cr(const char* format, va_list argptr) { |
167 | do_vsnprintf_and_write(format, argptr, true); |
168 | } |
169 | |
170 | void outputStream::fill_to(int col) { |
171 | int need_fill = col - position(); |
172 | sp(need_fill); |
173 | } |
174 | |
175 | void outputStream::move_to(int col, int slop, int min_space) { |
176 | if (position() >= col + slop) |
177 | cr(); |
178 | int need_fill = col - position(); |
179 | if (need_fill < min_space) |
180 | need_fill = min_space; |
181 | sp(need_fill); |
182 | } |
183 | |
184 | void outputStream::put(char ch) { |
185 | assert(ch != 0, "please fix call site")do { if (!(ch != 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 185, "assert(" "ch != 0" ") failed", "please fix call site" ); ::breakpoint(); } } while (0); |
186 | char buf[] = { ch, '\0' }; |
187 | write(buf, 1); |
188 | } |
189 | |
190 | #define SP_USE_TABSfalse false |
191 | |
192 | void outputStream::sp(int count) { |
193 | if (count < 0) return; |
194 | if (SP_USE_TABSfalse && count >= 8) { |
195 | int target = position() + count; |
196 | while (count >= 8) { |
197 | this->write("\t", 1); |
198 | count -= 8; |
199 | } |
200 | count = target - position(); |
201 | } |
202 | while (count > 0) { |
203 | int nw = (count > 8) ? 8 : count; |
204 | this->write(" ", nw); |
205 | count -= nw; |
206 | } |
207 | } |
208 | |
209 | void outputStream::cr() { |
210 | this->write("\n", 1); |
211 | } |
212 | |
213 | void outputStream::cr_indent() { |
214 | cr(); indent(); |
215 | } |
216 | |
217 | void outputStream::stamp() { |
218 | if (! _stamp.is_updated()) { |
219 | _stamp.update(); // start at 0 on first call to stamp() |
220 | } |
221 | |
222 | // outputStream::stamp() may get called by ostream_abort(), use snprintf |
223 | // to avoid allocating large stack buffer in print(). |
224 | char buf[40]; |
225 | jio_snprintf(buf, sizeof(buf), "%.3f", _stamp.seconds()); |
226 | print_raw(buf); |
227 | } |
228 | |
229 | void outputStream::stamp(bool guard, |
230 | const char* prefix, |
231 | const char* suffix) { |
232 | if (!guard) { |
233 | return; |
234 | } |
235 | print_raw(prefix); |
236 | stamp(); |
237 | print_raw(suffix); |
238 | } |
239 | |
240 | void outputStream::date_stamp(bool guard, |
241 | const char* prefix, |
242 | const char* suffix) { |
243 | if (!guard) { |
244 | return; |
245 | } |
246 | print_raw(prefix); |
247 | static const char error_time[] = "yyyy-mm-ddThh:mm:ss.mmm+zzzz"; |
248 | static const int buffer_length = 32; |
249 | char buffer[buffer_length]; |
250 | const char* iso8601_result = os::iso8601_time(buffer, buffer_length); |
251 | if (iso8601_result != NULL__null) { |
252 | print_raw(buffer); |
253 | } else { |
254 | print_raw(error_time); |
255 | } |
256 | print_raw(suffix); |
257 | return; |
258 | } |
259 | |
260 | outputStream& outputStream::indent() { |
261 | while (_position < _indentation) sp(); |
262 | return *this; |
263 | } |
264 | |
265 | void outputStream::print_jlong(jlong value) { |
266 | print(JLONG_FORMAT"%" "l" "d", value); |
267 | } |
268 | |
269 | void outputStream::print_julong(julong value) { |
270 | print(JULONG_FORMAT"%" "l" "u", value); |
271 | } |
272 | |
273 | /** |
274 | * This prints out hex data in a 'windbg' or 'xxd' form, where each line is: |
275 | * <hex-address>: 8 * <hex-halfword> <ascii translation (optional)> |
276 | * example: |
277 | * 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000 .DOF............ |
278 | * 0000010: 0000 0000 0000 0040 0000 0020 0000 0005 .......@... .... |
279 | * 0000020: 0000 0000 0000 0040 0000 0000 0000 015d .......@.......] |
280 | * ... |
281 | * |
282 | * indent is applied to each line. Ends with a CR. |
283 | */ |
284 | void outputStream::print_data(void* data, size_t len, bool with_ascii) { |
285 | size_t limit = (len + 16) / 16 * 16; |
286 | for (size_t i = 0; i < limit; ++i) { |
287 | if (i % 16 == 0) { |
288 | indent().print(INTPTR_FORMAT_W(07)"%" "07" "l" "x" ":", i); |
289 | } |
290 | if (i % 2 == 0) { |
291 | print(" "); |
292 | } |
293 | if (i < len) { |
294 | print("%02x", ((unsigned char*)data)[i]); |
295 | } else { |
296 | print(" "); |
297 | } |
298 | if ((i + 1) % 16 == 0) { |
299 | if (with_ascii) { |
300 | print(" "); |
301 | for (size_t j = 0; j < 16; ++j) { |
302 | size_t idx = i + j - 15; |
303 | if (idx < len) { |
304 | char c = ((char*)data)[idx]; |
305 | print("%c", c >= 32 && c <= 126 ? c : '.'); |
306 | } |
307 | } |
308 | } |
309 | cr(); |
310 | } |
311 | } |
312 | } |
313 | |
314 | stringStream::stringStream(size_t initial_capacity) : |
315 | outputStream(), |
316 | _buffer(_small_buffer), |
317 | _written(0), |
318 | _capacity(sizeof(_small_buffer)), |
319 | _is_fixed(false) |
320 | { |
321 | if (initial_capacity > _capacity) { |
322 | grow(initial_capacity); |
323 | } |
324 | zero_terminate(); |
325 | } |
326 | |
327 | // useful for output to fixed chunks of memory, such as performance counters |
328 | stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : |
329 | outputStream(), |
330 | _buffer(fixed_buffer), |
331 | _written(0), |
332 | _capacity(fixed_buffer_size), |
333 | _is_fixed(true) |
334 | { |
335 | zero_terminate(); |
336 | } |
337 | |
338 | // Grow backing buffer to desired capacity. Don't call for fixed buffers |
339 | void stringStream::grow(size_t new_capacity) { |
340 | assert(!_is_fixed, "Don't call for caller provided buffers")do { if (!(!_is_fixed)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 340, "assert(" "!_is_fixed" ") failed", "Don't call for caller provided buffers" ); ::breakpoint(); } } while (0); |
341 | assert(new_capacity > _capacity, "Sanity")do { if (!(new_capacity > _capacity)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 341, "assert(" "new_capacity > _capacity" ") failed", "Sanity" ); ::breakpoint(); } } while (0); |
342 | assert(new_capacity > sizeof(_small_buffer), "Sanity")do { if (!(new_capacity > sizeof(_small_buffer))) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 342, "assert(" "new_capacity > sizeof(_small_buffer)" ") failed" , "Sanity"); ::breakpoint(); } } while (0); |
343 | if (_buffer == _small_buffer) { |
344 | _buffer = NEW_C_HEAP_ARRAY(char, new_capacity, mtInternal)(char*) (AllocateHeap((new_capacity) * sizeof(char), mtInternal )); |
345 | _capacity = new_capacity; |
346 | if (_written > 0) { |
347 | ::memcpy(_buffer, _small_buffer, _written); |
348 | } |
349 | zero_terminate(); |
350 | } else { |
351 | _buffer = REALLOC_C_HEAP_ARRAY(char, _buffer, new_capacity, mtInternal)(char*) (ReallocateHeap((char*)(_buffer), (new_capacity) * sizeof (char), mtInternal)); |
352 | _capacity = new_capacity; |
353 | } |
354 | } |
355 | |
356 | void stringStream::write(const char* s, size_t len) { |
357 | assert(_capacity >= _written + 1, "Sanity")do { if (!(_capacity >= _written + 1)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 357, "assert(" "_capacity >= _written + 1" ") failed", "Sanity" ); ::breakpoint(); } } while (0); |
358 | if (len == 0) { |
359 | return; |
360 | } |
361 | const size_t reasonable_max_len = 1 * G; |
362 | if (len >= reasonable_max_len) { |
363 | assert(false, "bad length? (" SIZE_FORMAT ")", len)do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 363, "assert(" "false" ") failed", "bad length? (" "%" "l" "u" ")", len); ::breakpoint(); } } while (0); |
364 | return; |
365 | } |
366 | size_t write_len = 0; |
367 | if (_is_fixed) { |
368 | write_len = MIN2(len, _capacity - _written - 1); |
369 | } else { |
370 | write_len = len; |
371 | size_t needed = _written + len + 1; |
372 | if (needed > _capacity) { |
373 | grow(MAX2(needed, _capacity * 2)); |
374 | } |
375 | } |
376 | assert(_written + write_len + 1 <= _capacity, "stringStream oob")do { if (!(_written + write_len + 1 <= _capacity)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 376, "assert(" "_written + write_len + 1 <= _capacity" ") failed" , "stringStream oob"); ::breakpoint(); } } while (0); |
377 | if (write_len > 0) { |
378 | ::memcpy(_buffer + _written, s, write_len); |
379 | _written += write_len; |
380 | zero_terminate(); |
381 | } |
382 | |
383 | // Note that the following does not depend on write_len. |
384 | // This means that position and count get updated |
385 | // even when overflow occurs. |
386 | update_position(s, len); |
387 | } |
388 | |
389 | void stringStream::zero_terminate() { |
390 | assert(_buffer != NULL &&do { if (!(_buffer != __null && _written < _capacity )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 391, "assert(" "_buffer != __null && _written < _capacity" ") failed", "sanity"); ::breakpoint(); } } while (0) |
391 | _written < _capacity, "sanity")do { if (!(_buffer != __null && _written < _capacity )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 391, "assert(" "_buffer != __null && _written < _capacity" ") failed", "sanity"); ::breakpoint(); } } while (0); |
392 | _buffer[_written] = '\0'; |
393 | } |
394 | |
395 | void stringStream::reset() { |
396 | _written = 0; _precount = 0; _position = 0; |
397 | _newlines = 0; |
398 | zero_terminate(); |
399 | } |
400 | |
401 | char* stringStream::as_string(bool c_heap) const { |
402 | char* copy = c_heap ? |
403 | NEW_C_HEAP_ARRAY(char, _written + 1, mtInternal)(char*) (AllocateHeap((_written + 1) * sizeof(char), mtInternal )) : NEW_RESOURCE_ARRAY(char, _written + 1)(char*) resource_allocate_bytes((_written + 1) * sizeof(char) ); |
404 | ::memcpy(copy, _buffer, _written); |
405 | copy[_written] = 0; // terminating null |
406 | if (c_heap) { |
407 | // Need to ensure our content is written to memory before we return |
408 | // the pointer to it. |
409 | OrderAccess::storestore(); |
410 | } |
411 | return copy; |
412 | } |
413 | |
414 | stringStream::~stringStream() { |
415 | if (!_is_fixed && _buffer != _small_buffer) { |
416 | FREE_C_HEAP_ARRAY(char, _buffer)FreeHeap((char*)(_buffer)); |
417 | } |
418 | } |
419 | |
420 | xmlStream* xtty; |
421 | outputStream* tty; |
422 | extern Mutex* tty_lock; |
423 | |
424 | #define EXTRACHARLEN32 32 |
425 | #define CURRENTAPPX".current" ".current" |
426 | // convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS |
427 | char* get_datetime_string(char *buf, size_t len) { |
428 | os::local_time_string(buf, len); |
429 | int i = (int)strlen(buf); |
430 | while (--i >= 0) { |
431 | if (buf[i] == ' ') buf[i] = '_'; |
432 | else if (buf[i] == ':') buf[i] = '-'; |
433 | } |
434 | return buf; |
435 | } |
436 | |
437 | static const char* make_log_name_internal(const char* log_name, const char* force_directory, |
438 | int pid, const char* tms) { |
439 | const char* basename = log_name; |
440 | char file_sep = os::file_separator()[0]; |
441 | const char* cp; |
442 | char pid_text[32]; |
443 | |
444 | for (cp = log_name; *cp != '\0'; cp++) { |
445 | if (*cp == '/' || *cp == file_sep) { |
446 | basename = cp + 1; |
447 | } |
448 | } |
449 | const char* nametail = log_name; |
450 | // Compute buffer length |
451 | size_t buffer_length; |
452 | if (force_directory != NULL__null) { |
453 | buffer_length = strlen(force_directory) + strlen(os::file_separator()) + |
454 | strlen(basename) + 1; |
455 | } else { |
456 | buffer_length = strlen(log_name) + 1; |
457 | } |
458 | |
459 | const char* pts = strstr(basename, "%p"); |
460 | int pid_pos = (pts == NULL__null) ? -1 : (pts - nametail); |
461 | |
462 | if (pid_pos >= 0) { |
463 | jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid); |
464 | buffer_length += strlen(pid_text); |
465 | } |
466 | |
467 | pts = strstr(basename, "%t"); |
468 | int tms_pos = (pts == NULL__null) ? -1 : (pts - nametail); |
469 | if (tms_pos >= 0) { |
470 | buffer_length += strlen(tms); |
471 | } |
472 | |
473 | // File name is too long. |
474 | if (buffer_length > JVM_MAXPATHLEN4096 + 1) { |
475 | return NULL__null; |
476 | } |
477 | |
478 | // Create big enough buffer. |
479 | char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal)(char*) (AllocateHeap((buffer_length) * sizeof(char), mtInternal )); |
480 | |
481 | strcpy(buf, ""); |
482 | if (force_directory != NULL__null) { |
483 | strcat(buf, force_directory); |
484 | strcat(buf, os::file_separator()); |
485 | nametail = basename; // completely skip directory prefix |
486 | } |
487 | |
488 | // who is first, %p or %t? |
489 | int first = -1, second = -1; |
490 | const char *p1st = NULL__null; |
491 | const char *p2nd = NULL__null; |
492 | |
493 | if (pid_pos >= 0 && tms_pos >= 0) { |
494 | // contains both %p and %t |
495 | if (pid_pos < tms_pos) { |
496 | // case foo%pbar%tmonkey.log |
497 | first = pid_pos; |
498 | p1st = pid_text; |
499 | second = tms_pos; |
500 | p2nd = tms; |
501 | } else { |
502 | // case foo%tbar%pmonkey.log |
503 | first = tms_pos; |
504 | p1st = tms; |
505 | second = pid_pos; |
506 | p2nd = pid_text; |
507 | } |
508 | } else if (pid_pos >= 0) { |
509 | // contains %p only |
510 | first = pid_pos; |
511 | p1st = pid_text; |
512 | } else if (tms_pos >= 0) { |
513 | // contains %t only |
514 | first = tms_pos; |
515 | p1st = tms; |
516 | } |
517 | |
518 | int buf_pos = (int)strlen(buf); |
519 | const char* tail = nametail; |
520 | |
521 | if (first >= 0) { |
522 | tail = nametail + first + 2; |
523 | strncpy(&buf[buf_pos], nametail, first); |
524 | strcpy(&buf[buf_pos + first], p1st); |
525 | buf_pos = (int)strlen(buf); |
526 | if (second >= 0) { |
527 | strncpy(&buf[buf_pos], tail, second - first - 2); |
528 | strcpy(&buf[buf_pos + second - first - 2], p2nd); |
529 | tail = nametail + second + 2; |
530 | } |
531 | } |
532 | strcat(buf, tail); // append rest of name, or all of name |
533 | return buf; |
534 | } |
535 | |
536 | // log_name comes from -XX:LogFile=log_name or |
537 | // -XX:DumpLoadedClassList=<file_name> |
538 | // in log_name, %p => pid1234 and |
539 | // %t => YYYY-MM-DD_HH-MM-SS |
540 | const char* make_log_name(const char* log_name, const char* force_directory) { |
541 | char timestr[32]; |
542 | get_datetime_string(timestr, sizeof(timestr)); |
543 | return make_log_name_internal(log_name, force_directory, os::current_process_id(), |
544 | timestr); |
545 | } |
546 | |
547 | fileStream::fileStream(const char* file_name) { |
548 | _file = fopen(file_name, "w"); |
549 | if (_file != NULL__null) { |
550 | _need_close = true; |
551 | } else { |
552 | warning("Cannot open file %s due to %s\n", file_name, os::strerror(errno(*__errno_location ()))); |
553 | _need_close = false; |
554 | } |
555 | } |
556 | |
557 | fileStream::fileStream(const char* file_name, const char* opentype) { |
558 | _file = fopen(file_name, opentype); |
559 | if (_file != NULL__null) { |
560 | _need_close = true; |
561 | } else { |
562 | warning("Cannot open file %s due to %s\n", file_name, os::strerror(errno(*__errno_location ()))); |
563 | _need_close = false; |
564 | } |
565 | } |
566 | |
567 | void fileStream::write(const char* s, size_t len) { |
568 | if (_file != NULL__null) { |
569 | // Make an unused local variable to avoid warning from gcc compiler. |
570 | size_t count = fwrite(s, 1, len, _file); |
571 | update_position(s, len); |
572 | } |
573 | } |
574 | |
575 | long fileStream::fileSize() { |
576 | long size = -1; |
577 | if (_file != NULL__null) { |
578 | long pos = ::ftell(_file); |
579 | if (pos < 0) return pos; |
580 | if (::fseek(_file, 0, SEEK_END2) == 0) { |
581 | size = ::ftell(_file); |
582 | } |
583 | ::fseek(_file, pos, SEEK_SET0); |
584 | } |
585 | return size; |
586 | } |
587 | |
588 | char* fileStream::readln(char *data, int count ) { |
589 | char * ret = NULL__null; |
590 | if (_file != NULL__null) { |
591 | ret = ::fgets(data, count, _file); |
592 | // Get rid of annoying \n char only if it is present. |
593 | size_t len = ::strlen(data); |
594 | if (len > 0 && data[len - 1] == '\n') { |
595 | data[len - 1] = '\0'; |
596 | } |
597 | } |
598 | return ret; |
599 | } |
600 | |
601 | fileStream::~fileStream() { |
602 | if (_file != NULL__null) { |
603 | if (_need_close) fclose(_file); |
604 | _file = NULL__null; |
605 | } |
606 | } |
607 | |
608 | void fileStream::flush() { |
609 | if (_file != NULL__null) { |
610 | fflush(_file); |
611 | } |
612 | } |
613 | |
614 | void fdStream::write(const char* s, size_t len) { |
615 | if (_fd != -1) { |
616 | // Make an unused local variable to avoid warning from gcc compiler. |
617 | size_t count = ::write(_fd, s, (int)len); |
Value stored to 'count' during its initialization is never read | |
618 | update_position(s, len); |
619 | } |
620 | } |
621 | |
622 | defaultStream* defaultStream::instance = NULL__null; |
623 | int defaultStream::_output_fd = 1; |
624 | int defaultStream::_error_fd = 2; |
625 | FILE* defaultStream::_output_stream = stdoutstdout; |
626 | FILE* defaultStream::_error_stream = stderrstderr; |
627 | |
628 | #define LOG_MAJOR_VERSION160 160 |
629 | #define LOG_MINOR_VERSION1 1 |
630 | |
631 | void defaultStream::init() { |
632 | _inited = true; |
633 | if (LogVMOutput || LogCompilation) { |
634 | init_log(); |
635 | } |
636 | } |
637 | |
638 | bool defaultStream::has_log_file() { |
639 | // lazily create log file (at startup, LogVMOutput is false even |
640 | // if +LogVMOutput is used, because the flags haven't been parsed yet) |
641 | // For safer printing during fatal error handling, do not init logfile |
642 | // if a VM error has been reported. |
643 | if (!_inited && !VMError::is_error_reported()) init(); |
644 | return _log_file != NULL__null; |
645 | } |
646 | |
647 | fileStream* defaultStream::open_file(const char* log_name) { |
648 | const char* try_name = make_log_name(log_name, NULL__null); |
649 | if (try_name == NULL__null) { |
650 | warning("Cannot open file %s: file name is too long.\n", log_name); |
651 | return NULL__null; |
652 | } |
653 | |
654 | fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); |
655 | FREE_C_HEAP_ARRAY(char, try_name)FreeHeap((char*)(try_name)); |
656 | if (file->is_open()) { |
657 | return file; |
658 | } |
659 | |
660 | // Try again to open the file in the temp directory. |
661 | delete file; |
662 | // Note: This feature is for maintainer use only. No need for L10N. |
663 | jio_printf("Warning: Cannot open log file: %s\n", log_name); |
664 | try_name = make_log_name(log_name, os::get_temp_directory()); |
665 | if (try_name == NULL__null) { |
666 | warning("Cannot open file %s: file name is too long for directory %s.\n", log_name, os::get_temp_directory()); |
667 | return NULL__null; |
668 | } |
669 | |
670 | jio_printf("Warning: Forcing option -XX:LogFile=%s\n", try_name); |
671 | |
672 | file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); |
673 | FREE_C_HEAP_ARRAY(char, try_name)FreeHeap((char*)(try_name)); |
674 | if (file->is_open()) { |
675 | return file; |
676 | } |
677 | |
678 | delete file; |
679 | return NULL__null; |
680 | } |
681 | |
682 | void defaultStream::init_log() { |
683 | // %%% Need a MutexLocker? |
684 | const char* log_name = LogFile != NULL__null ? LogFile : "hotspot_%p.log"; |
685 | fileStream* file = open_file(log_name); |
686 | |
687 | if (file != NULL__null) { |
688 | _log_file = file; |
689 | _outer_xmlStream = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file); |
690 | start_log(); |
691 | } else { |
692 | // and leave xtty as NULL |
693 | LogVMOutput = false; |
694 | DisplayVMOutput = true; |
695 | LogCompilation = false; |
696 | } |
697 | } |
698 | |
699 | void defaultStream::start_log() { |
700 | xmlStream*xs = _outer_xmlStream; |
701 | if (this == tty) xtty = xs; |
702 | // Write XML header. |
703 | xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>"); |
704 | // (For now, don't bother to issue a DTD for this private format.) |
705 | |
706 | // Calculate the start time of the log as ms since the epoch: this is |
707 | // the current time in ms minus the uptime in ms. |
708 | jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds(); |
709 | xs->head("hotspot_log version='%d %d'" |
710 | " process='%d' time_ms='" INT64_FORMAT"%" "l" "d" "'", |
711 | LOG_MAJOR_VERSION160, LOG_MINOR_VERSION1, |
712 | os::current_process_id(), (int64_t)time_ms); |
713 | // Write VM version header immediately. |
714 | xs->head("vm_version"); |
715 | xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr(); |
716 | xs->tail("name"); |
717 | xs->head("release"); xs->text("%s", VM_Version::vm_release()); xs->cr(); |
718 | xs->tail("release"); |
719 | xs->head("info"); xs->text("%s", VM_Version::internal_vm_info_string()); xs->cr(); |
720 | xs->tail("info"); |
721 | xs->tail("vm_version"); |
722 | // Record information about the command-line invocation. |
723 | xs->head("vm_arguments"); // Cf. Arguments::print_on() |
724 | if (Arguments::num_jvm_flags() > 0) { |
725 | xs->head("flags"); |
726 | Arguments::print_jvm_flags_on(xs->text()); |
727 | xs->tail("flags"); |
728 | } |
729 | if (Arguments::num_jvm_args() > 0) { |
730 | xs->head("args"); |
731 | Arguments::print_jvm_args_on(xs->text()); |
732 | xs->tail("args"); |
733 | } |
734 | if (Arguments::java_command() != NULL__null) { |
735 | xs->head("command"); xs->text()->print_cr("%s", Arguments::java_command()); |
736 | xs->tail("command"); |
737 | } |
738 | if (Arguments::sun_java_launcher() != NULL__null) { |
739 | xs->head("launcher"); xs->text()->print_cr("%s", Arguments::sun_java_launcher()); |
740 | xs->tail("launcher"); |
741 | } |
742 | if (Arguments::system_properties() != NULL__null) { |
743 | xs->head("properties"); |
744 | // Print it as a java-style property list. |
745 | // System properties don't generally contain newlines, so don't bother with unparsing. |
746 | outputStream *text = xs->text(); |
747 | for (SystemProperty* p = Arguments::system_properties(); p != NULL__null; p = p->next()) { |
748 | assert(p->key() != NULL, "p->key() is NULL")do { if (!(p->key() != __null)) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 748, "assert(" "p->key() != __null" ") failed", "p->key() is NULL" ); ::breakpoint(); } } while (0); |
749 | if (p->is_readable()) { |
750 | // Print in two stages to avoid problems with long |
751 | // keys/values. |
752 | text->print_raw(p->key()); |
753 | text->put('='); |
754 | assert(p->value() != NULL, "p->value() is NULL")do { if (!(p->value() != __null)) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 754, "assert(" "p->value() != __null" ") failed", "p->value() is NULL" ); ::breakpoint(); } } while (0); |
755 | text->print_raw_cr(p->value()); |
756 | } |
757 | } |
758 | xs->tail("properties"); |
759 | } |
760 | xs->tail("vm_arguments"); |
761 | // tty output per se is grouped under the <tty>...</tty> element. |
762 | xs->head("tty"); |
763 | // All further non-markup text gets copied to the tty: |
764 | xs->_text = this; // requires friend declaration! |
765 | } |
766 | |
767 | // finish_log() is called during normal VM shutdown. finish_log_on_error() is |
768 | // called by ostream_abort() after a fatal error. |
769 | // |
770 | void defaultStream::finish_log() { |
771 | xmlStream* xs = _outer_xmlStream; |
772 | xs->done("tty"); |
773 | |
774 | // Other log forks are appended here, at the End of Time: |
775 | CompileLog::finish_log(xs->out()); // write compile logging, if any, now |
776 | |
777 | xs->done("hotspot_log"); |
778 | xs->flush(); |
779 | |
780 | fileStream* file = _log_file; |
781 | _log_file = NULL__null; |
782 | |
783 | delete _outer_xmlStream; |
784 | _outer_xmlStream = NULL__null; |
785 | |
786 | file->flush(); |
787 | delete file; |
788 | } |
789 | |
790 | void defaultStream::finish_log_on_error(char *buf, int buflen) { |
791 | xmlStream* xs = _outer_xmlStream; |
792 | |
793 | if (xs && xs->out()) { |
794 | |
795 | xs->done_raw("tty"); |
796 | |
797 | // Other log forks are appended here, at the End of Time: |
798 | CompileLog::finish_log_on_error(xs->out(), buf, buflen); // write compile logging, if any, now |
799 | |
800 | xs->done_raw("hotspot_log"); |
801 | xs->flush(); |
802 | |
803 | fileStream* file = _log_file; |
804 | _log_file = NULL__null; |
805 | _outer_xmlStream = NULL__null; |
806 | |
807 | if (file) { |
808 | file->flush(); |
809 | |
810 | // Can't delete or close the file because delete and fclose aren't |
811 | // async-safe. We are about to die, so leave it to the kernel. |
812 | // delete file; |
813 | } |
814 | } |
815 | } |
816 | |
817 | intx defaultStream::hold(intx writer_id) { |
818 | bool has_log = has_log_file(); // check before locking |
819 | if (// impossible, but who knows? |
820 | writer_id == NO_WRITER || |
821 | |
822 | // bootstrap problem |
823 | tty_lock == NULL__null || |
824 | |
825 | // can't grab a lock if current Thread isn't set |
826 | Thread::current_or_null() == NULL__null || |
827 | |
828 | // developer hook |
829 | !SerializeVMOutput || |
830 | |
831 | // VM already unhealthy |
832 | VMError::is_error_reported() || |
833 | |
834 | // safepoint == global lock (for VM only) |
835 | (SafepointSynchronize::is_synchronizing() && |
836 | Thread::current()->is_VM_thread()) |
837 | ) { |
838 | // do not attempt to lock unless we know the thread and the VM is healthy |
839 | return NO_WRITER; |
840 | } |
841 | if (_writer == writer_id) { |
842 | // already held, no need to re-grab the lock |
843 | return NO_WRITER; |
844 | } |
845 | tty_lock->lock_without_safepoint_check(); |
846 | // got the lock |
847 | if (writer_id != _last_writer) { |
848 | if (has_log) { |
849 | _log_file->bol(); |
850 | // output a hint where this output is coming from: |
851 | _log_file->print_cr("<writer thread='" UINTX_FORMAT"%" "l" "u" "'/>", writer_id); |
852 | } |
853 | _last_writer = writer_id; |
854 | } |
855 | _writer = writer_id; |
856 | return writer_id; |
857 | } |
858 | |
859 | void defaultStream::release(intx holder) { |
860 | if (holder == NO_WRITER) { |
861 | // nothing to release: either a recursive lock, or we scribbled (too bad) |
862 | return; |
863 | } |
864 | if (_writer != holder) { |
865 | return; // already unlocked, perhaps via break_tty_lock_for_safepoint |
866 | } |
867 | _writer = NO_WRITER; |
868 | tty_lock->unlock(); |
869 | } |
870 | |
871 | void defaultStream::write(const char* s, size_t len) { |
872 | intx thread_id = os::current_thread_id(); |
873 | intx holder = hold(thread_id); |
874 | |
875 | if (DisplayVMOutput && |
876 | (_outer_xmlStream == NULL__null || !_outer_xmlStream->inside_attrs())) { |
877 | // print to output stream. It can be redirected by a vfprintf hook |
878 | jio_print(s, len); |
879 | } |
880 | |
881 | // print to log file |
882 | if (has_log_file()) { |
883 | int nl0 = _newlines; |
884 | xmlTextStream::write(s, len); |
885 | // flush the log file too, if there were any newlines |
886 | if (nl0 != _newlines){ |
887 | flush(); |
888 | } |
889 | } else { |
890 | update_position(s, len); |
891 | } |
892 | |
893 | release(holder); |
894 | } |
895 | |
896 | intx ttyLocker::hold_tty() { |
897 | if (defaultStream::instance == NULL__null) return defaultStream::NO_WRITER; |
898 | intx thread_id = os::current_thread_id(); |
899 | return defaultStream::instance->hold(thread_id); |
900 | } |
901 | |
902 | void ttyLocker::release_tty(intx holder) { |
903 | if (holder == defaultStream::NO_WRITER) return; |
904 | defaultStream::instance->release(holder); |
905 | } |
906 | |
907 | bool ttyLocker::release_tty_if_locked() { |
908 | intx thread_id = os::current_thread_id(); |
909 | if (defaultStream::instance->writer() == thread_id) { |
910 | // release the lock and return true so callers know if was |
911 | // previously held. |
912 | release_tty(thread_id); |
913 | return true; |
914 | } |
915 | return false; |
916 | } |
917 | |
918 | void ttyLocker::break_tty_lock_for_safepoint(intx holder) { |
919 | if (defaultStream::instance != NULL__null && |
920 | defaultStream::instance->writer() == holder) { |
921 | if (xtty != NULL__null) { |
922 | xtty->print_cr("<!-- safepoint while printing -->"); |
923 | } |
924 | defaultStream::instance->release(holder); |
925 | } |
926 | // (else there was no lock to break) |
927 | } |
928 | |
929 | void ostream_init() { |
930 | if (defaultStream::instance == NULL__null) { |
931 | defaultStream::instance = new(ResourceObj::C_HEAP, mtInternal) defaultStream(); |
932 | tty = defaultStream::instance; |
933 | |
934 | // We want to ensure that time stamps in GC logs consider time 0 |
935 | // the time when the JVM is initialized, not the first time we ask |
936 | // for a time stamp. So, here, we explicitly update the time stamp |
937 | // of tty. |
938 | tty->time_stamp().update_to(1); |
939 | } |
940 | } |
941 | |
942 | void ostream_init_log() { |
943 | // Note : this must be called AFTER ostream_init() |
944 | |
945 | ClassListWriter::init(); |
946 | |
947 | // If we haven't lazily initialized the logfile yet, do it now, |
948 | // to avoid the possibility of lazy initialization during a VM |
949 | // crash, which can affect the stability of the fatal error handler. |
950 | defaultStream::instance->has_log_file(); |
951 | } |
952 | |
953 | // ostream_exit() is called during normal VM exit to finish log files, flush |
954 | // output and free resource. |
955 | void ostream_exit() { |
956 | static bool ostream_exit_called = false; |
957 | if (ostream_exit_called) return; |
958 | ostream_exit_called = true; |
959 | ClassListWriter::delete_classlist(); |
960 | if (tty != defaultStream::instance) { |
961 | delete tty; |
962 | } |
963 | if (defaultStream::instance != NULL__null) { |
964 | delete defaultStream::instance; |
965 | } |
966 | tty = NULL__null; |
967 | xtty = NULL__null; |
968 | defaultStream::instance = NULL__null; |
969 | } |
970 | |
971 | // ostream_abort() is called by os::abort() when VM is about to die. |
972 | void ostream_abort() { |
973 | // Here we can't delete tty, just flush its output |
974 | if (tty) tty->flush(); |
975 | |
976 | if (defaultStream::instance != NULL__null) { |
977 | static char buf[4096]; |
978 | defaultStream::instance->finish_log_on_error(buf, sizeof(buf)); |
979 | } |
980 | } |
981 | |
982 | bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() { |
983 | buffer_length = initial_size; |
984 | buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal)(char*) (AllocateHeap((buffer_length) * sizeof(char), mtInternal )); |
985 | buffer_pos = 0; |
986 | buffer_fixed = false; |
987 | buffer_max = bufmax; |
988 | truncated = false; |
989 | } |
990 | |
991 | bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() { |
992 | buffer_length = fixed_buffer_size; |
993 | buffer = fixed_buffer; |
994 | buffer_pos = 0; |
995 | buffer_fixed = true; |
996 | buffer_max = bufmax; |
997 | truncated = false; |
998 | } |
999 | |
1000 | void bufferedStream::write(const char* s, size_t len) { |
1001 | |
1002 | if (truncated) { |
1003 | return; |
1004 | } |
1005 | |
1006 | if(buffer_pos + len > buffer_max) { |
1007 | flush(); // Note: may be a noop. |
1008 | } |
1009 | |
1010 | size_t end = buffer_pos + len; |
1011 | if (end >= buffer_length) { |
1012 | if (buffer_fixed) { |
1013 | // if buffer cannot resize, silently truncate |
1014 | len = buffer_length - buffer_pos - 1; |
1015 | truncated = true; |
1016 | } else { |
1017 | // For small overruns, double the buffer. For larger ones, |
1018 | // increase to the requested size. |
1019 | if (end < buffer_length * 2) { |
1020 | end = buffer_length * 2; |
1021 | } |
1022 | // Impose a cap beyond which the buffer cannot grow - a size which |
1023 | // in all probability indicates a real error, e.g. faulty printing |
1024 | // code looping, while not affecting cases of just-very-large-but-its-normal |
1025 | // output. |
1026 | const size_t reasonable_cap = MAX2(100 * M, buffer_max * 2); |
1027 | if (end > reasonable_cap) { |
1028 | // In debug VM, assert right away. |
1029 | assert(false, "Exceeded max buffer size for this string.")do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 1029, "assert(" "false" ") failed", "Exceeded max buffer size for this string." ); ::breakpoint(); } } while (0); |
1030 | // Release VM: silently truncate. We do this since these kind of errors |
1031 | // are both difficult to predict with testing (depending on logging content) |
1032 | // and usually not serious enough to kill a production VM for it. |
1033 | end = reasonable_cap; |
1034 | size_t remaining = end - buffer_pos; |
1035 | if (len >= remaining) { |
1036 | len = remaining - 1; |
1037 | truncated = true; |
1038 | } |
1039 | } |
1040 | if (buffer_length < end) { |
1041 | buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal)(char*) (ReallocateHeap((char*)(buffer), (end) * sizeof(char) , mtInternal)); |
1042 | buffer_length = end; |
1043 | } |
1044 | } |
1045 | } |
1046 | if (len > 0) { |
1047 | memcpy(buffer + buffer_pos, s, len); |
1048 | buffer_pos += len; |
1049 | update_position(s, len); |
1050 | } |
1051 | } |
1052 | |
1053 | char* bufferedStream::as_string() { |
1054 | char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1)(char*) resource_allocate_bytes((buffer_pos+1) * sizeof(char) ); |
1055 | strncpy(copy, buffer, buffer_pos); |
1056 | copy[buffer_pos] = 0; // terminating null |
1057 | return copy; |
1058 | } |
1059 | |
1060 | bufferedStream::~bufferedStream() { |
1061 | if (!buffer_fixed) { |
1062 | FREE_C_HEAP_ARRAY(char, buffer)FreeHeap((char*)(buffer)); |
1063 | } |
1064 | } |
1065 | |
1066 | #ifndef PRODUCT |
1067 | |
1068 | #if defined(LINUX1) || defined(AIX) || defined(_ALLBSD_SOURCE) |
1069 | #include <sys/types.h> |
1070 | #include <sys/socket.h> |
1071 | #include <netinet/in.h> |
1072 | #include <arpa/inet.h> |
1073 | #elif defined(_WINDOWS) |
1074 | #include <winsock2.h> |
1075 | #endif |
1076 | |
1077 | // Network access |
1078 | networkStream::networkStream() : bufferedStream(1024*10, 1024*10) { |
1079 | |
1080 | _socket = -1; |
1081 | |
1082 | int result = os::socket(AF_INET2, SOCK_STREAMSOCK_STREAM, 0); |
1083 | if (result <= 0) { |
1084 | assert(false, "Socket could not be created!")do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 1084, "assert(" "false" ") failed", "Socket could not be created!" ); ::breakpoint(); } } while (0); |
1085 | } else { |
1086 | _socket = result; |
1087 | } |
1088 | } |
1089 | |
1090 | int networkStream::read(char *buf, size_t len) { |
1091 | return os::recv(_socket, buf, (int)len, 0); |
1092 | } |
1093 | |
1094 | void networkStream::flush() { |
1095 | if (size() != 0) { |
1096 | int result = os::raw_send(_socket, (char *)base(), size(), 0); |
1097 | assert(result != -1, "connection error")do { if (!(result != -1)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 1097, "assert(" "result != -1" ") failed", "connection error" ); ::breakpoint(); } } while (0); |
1098 | assert(result == (int)size(), "didn't send enough data")do { if (!(result == (int)size())) { (*g_assert_poison) = 'X' ;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/ostream.cpp" , 1098, "assert(" "result == (int)size()" ") failed", "didn't send enough data" ); ::breakpoint(); } } while (0); |
1099 | } |
1100 | reset(); |
1101 | } |
1102 | |
1103 | networkStream::~networkStream() { |
1104 | close(); |
1105 | } |
1106 | |
1107 | void networkStream::close() { |
1108 | if (_socket != -1) { |
1109 | flush(); |
1110 | os::socket_close(_socket); |
1111 | _socket = -1; |
1112 | } |
1113 | } |
1114 | |
1115 | bool networkStream::connect(const char *ip, short port) { |
1116 | |
1117 | struct sockaddr_in server; |
1118 | server.sin_family = AF_INET2; |
1119 | server.sin_port = htons(port)(__extension__ ({ unsigned short int __v, __x = (unsigned short int) (port); if (__builtin_constant_p (__x)) __v = ((unsigned short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff ) << 8))); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0" (__x) : "cc"); __v; })); |
1120 | |
1121 | server.sin_addr.s_addr = inet_addr(ip); |
1122 | if (server.sin_addr.s_addr == (uint32_t)-1) { |
1123 | struct hostent* host = os::get_host_by_name((char*)ip); |
1124 | if (host != NULL__null) { |
1125 | memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length); |
1126 | } else { |
1127 | return false; |
1128 | } |
1129 | } |
1130 | |
1131 | |
1132 | int result = os::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in)); |
1133 | return (result >= 0); |
1134 | } |
1135 | |
1136 | #endif |