Mercurial > hg > truffle
annotate src/share/vm/utilities/ostream.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1353
diff
changeset
|
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1353
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1353
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1353
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_ostream.cpp.incl" | |
27 | |
28 extern "C" void jio_print(const char* s); // Declarationtion of jvm method | |
29 | |
30 outputStream::outputStream(int width) { | |
31 _width = width; | |
32 _position = 0; | |
33 _newlines = 0; | |
34 _precount = 0; | |
35 _indentation = 0; | |
36 } | |
37 | |
38 outputStream::outputStream(int width, bool has_time_stamps) { | |
39 _width = width; | |
40 _position = 0; | |
41 _newlines = 0; | |
42 _precount = 0; | |
43 _indentation = 0; | |
44 if (has_time_stamps) _stamp.update(); | |
45 } | |
46 | |
47 void outputStream::update_position(const char* s, size_t len) { | |
48 for (size_t i = 0; i < len; i++) { | |
49 char ch = s[i]; | |
50 if (ch == '\n') { | |
51 _newlines += 1; | |
52 _precount += _position + 1; | |
53 _position = 0; | |
54 } else if (ch == '\t') { | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
55 int tw = 8 - (_position & 7); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
56 _position += tw; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
57 _precount -= tw-1; // invariant: _precount + _position == total count |
0 | 58 } else { |
59 _position += 1; | |
60 } | |
61 } | |
62 } | |
63 | |
64 // Execute a vsprintf, using the given buffer if necessary. | |
65 // Return a pointer to the formatted string. | |
66 const char* outputStream::do_vsnprintf(char* buffer, size_t buflen, | |
67 const char* format, va_list ap, | |
68 bool add_cr, | |
69 size_t& result_len) { | |
70 const char* result; | |
71 if (add_cr) buflen--; | |
72 if (!strchr(format, '%')) { | |
73 // constant format string | |
74 result = format; | |
75 result_len = strlen(result); | |
76 if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate | |
77 } else if (format[0] == '%' && format[1] == 's' && format[2] == '\0') { | |
78 // trivial copy-through format string | |
79 result = va_arg(ap, const char*); | |
80 result_len = strlen(result); | |
81 if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate | |
82 } else if (vsnprintf(buffer, buflen, format, ap) >= 0) { | |
83 result = buffer; | |
84 result_len = strlen(result); | |
85 } else { | |
86 DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");) | |
87 result = buffer; | |
88 result_len = buflen - 1; | |
89 buffer[result_len] = 0; | |
90 } | |
91 if (add_cr) { | |
92 if (result != buffer) { | |
93 strncpy(buffer, result, buflen); | |
94 result = buffer; | |
95 } | |
96 buffer[result_len++] = '\n'; | |
97 buffer[result_len] = 0; | |
98 } | |
99 return result; | |
100 } | |
101 | |
102 void outputStream::print(const char* format, ...) { | |
103 char buffer[O_BUFLEN]; | |
104 va_list ap; | |
105 va_start(ap, format); | |
106 size_t len; | |
107 const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len); | |
108 write(str, len); | |
109 va_end(ap); | |
110 } | |
111 | |
112 void outputStream::print_cr(const char* format, ...) { | |
113 char buffer[O_BUFLEN]; | |
114 va_list ap; | |
115 va_start(ap, format); | |
116 size_t len; | |
117 const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, true, len); | |
118 write(str, len); | |
119 va_end(ap); | |
120 } | |
121 | |
122 void outputStream::vprint(const char *format, va_list argptr) { | |
123 char buffer[O_BUFLEN]; | |
124 size_t len; | |
125 const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, false, len); | |
126 write(str, len); | |
127 } | |
128 | |
129 void outputStream::vprint_cr(const char* format, va_list argptr) { | |
130 char buffer[O_BUFLEN]; | |
131 size_t len; | |
132 const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, true, len); | |
133 write(str, len); | |
134 } | |
135 | |
136 void outputStream::fill_to(int col) { | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
137 int need_fill = col - position(); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
138 sp(need_fill); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
139 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
140 |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
141 void outputStream::move_to(int col, int slop, int min_space) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
142 if (position() >= col + slop) |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
143 cr(); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
144 int need_fill = col - position(); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
145 if (need_fill < min_space) |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
146 need_fill = min_space; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
147 sp(need_fill); |
0 | 148 } |
149 | |
150 void outputStream::put(char ch) { | |
151 assert(ch != 0, "please fix call site"); | |
152 char buf[] = { ch, '\0' }; | |
153 write(buf, 1); | |
154 } | |
155 | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
156 #define SP_USE_TABS false |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
157 |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
158 void outputStream::sp(int count) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
159 if (count < 0) return; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
160 if (SP_USE_TABS && count >= 8) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
161 int target = position() + count; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
162 while (count >= 8) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
163 this->write("\t", 1); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
164 count -= 8; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
165 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
166 count = target - position(); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
167 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
168 while (count > 0) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
169 int nw = (count > 8) ? 8 : count; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
170 this->write(" ", nw); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
171 count -= nw; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
172 } |
0 | 173 } |
174 | |
175 void outputStream::cr() { | |
176 this->write("\n", 1); | |
177 } | |
178 | |
179 void outputStream::stamp() { | |
180 if (! _stamp.is_updated()) { | |
181 _stamp.update(); // start at 0 on first call to stamp() | |
182 } | |
183 | |
184 // outputStream::stamp() may get called by ostream_abort(), use snprintf | |
185 // to avoid allocating large stack buffer in print(). | |
186 char buf[40]; | |
187 jio_snprintf(buf, sizeof(buf), "%.3f", _stamp.seconds()); | |
188 print_raw(buf); | |
189 } | |
190 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
191 void outputStream::stamp(bool guard, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
192 const char* prefix, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
193 const char* suffix) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
194 if (!guard) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
195 return; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
196 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
197 print_raw(prefix); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
198 stamp(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
199 print_raw(suffix); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
200 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
102
diff
changeset
|
201 |
0 | 202 void outputStream::date_stamp(bool guard, |
203 const char* prefix, | |
204 const char* suffix) { | |
205 if (!guard) { | |
206 return; | |
207 } | |
208 print_raw(prefix); | |
209 static const char error_time[] = "yyyy-mm-ddThh:mm:ss.mmm+zzzz"; | |
210 static const int buffer_length = 32; | |
211 char buffer[buffer_length]; | |
212 const char* iso8601_result = os::iso8601_time(buffer, buffer_length); | |
213 if (iso8601_result != NULL) { | |
214 print_raw(buffer); | |
215 } else { | |
216 print_raw(error_time); | |
217 } | |
218 print_raw(suffix); | |
219 return; | |
220 } | |
221 | |
222 void outputStream::indent() { | |
223 while (_position < _indentation) sp(); | |
224 } | |
225 | |
226 void outputStream::print_jlong(jlong value) { | |
227 // N.B. Same as INT64_FORMAT | |
228 print(os::jlong_format_specifier(), value); | |
229 } | |
230 | |
231 void outputStream::print_julong(julong value) { | |
232 // N.B. Same as UINT64_FORMAT | |
233 print(os::julong_format_specifier(), value); | |
234 } | |
235 | |
236 stringStream::stringStream(size_t initial_size) : outputStream() { | |
237 buffer_length = initial_size; | |
238 buffer = NEW_RESOURCE_ARRAY(char, buffer_length); | |
239 buffer_pos = 0; | |
240 buffer_fixed = false; | |
241 } | |
242 | |
243 // useful for output to fixed chunks of memory, such as performance counters | |
244 stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() { | |
245 buffer_length = fixed_buffer_size; | |
246 buffer = fixed_buffer; | |
247 buffer_pos = 0; | |
248 buffer_fixed = true; | |
249 } | |
250 | |
251 void stringStream::write(const char* s, size_t len) { | |
252 size_t write_len = len; // number of non-null bytes to write | |
253 size_t end = buffer_pos + len + 1; // position after write and final '\0' | |
254 if (end > buffer_length) { | |
255 if (buffer_fixed) { | |
256 // if buffer cannot resize, silently truncate | |
257 end = buffer_length; | |
258 write_len = end - buffer_pos - 1; // leave room for the final '\0' | |
259 } else { | |
260 // For small overruns, double the buffer. For larger ones, | |
261 // increase to the requested size. | |
262 if (end < buffer_length * 2) { | |
263 end = buffer_length * 2; | |
264 } | |
265 char* oldbuf = buffer; | |
266 buffer = NEW_RESOURCE_ARRAY(char, end); | |
267 strncpy(buffer, oldbuf, buffer_pos); | |
268 buffer_length = end; | |
269 } | |
270 } | |
271 // invariant: buffer is always null-terminated | |
272 guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob"); | |
273 buffer[buffer_pos + write_len] = 0; | |
274 strncpy(buffer + buffer_pos, s, write_len); | |
275 buffer_pos += write_len; | |
276 | |
277 // Note that the following does not depend on write_len. | |
278 // This means that position and count get updated | |
279 // even when overflow occurs. | |
280 update_position(s, len); | |
281 } | |
282 | |
283 char* stringStream::as_string() { | |
284 char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1); | |
285 strncpy(copy, buffer, buffer_pos); | |
286 copy[buffer_pos] = 0; // terminating null | |
287 return copy; | |
288 } | |
289 | |
290 stringStream::~stringStream() {} | |
291 | |
292 xmlStream* xtty; | |
293 outputStream* tty; | |
294 outputStream* gclog_or_tty; | |
295 extern Mutex* tty_lock; | |
296 | |
297 fileStream::fileStream(const char* file_name) { | |
298 _file = fopen(file_name, "w"); | |
299 _need_close = true; | |
300 } | |
301 | |
302 void fileStream::write(const char* s, size_t len) { | |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
356
diff
changeset
|
303 if (_file != NULL) { |
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
356
diff
changeset
|
304 // Make an unused local variable to avoid warning from gcc 4.x compiler. |
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
356
diff
changeset
|
305 size_t count = fwrite(s, 1, len, _file); |
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
356
diff
changeset
|
306 } |
0 | 307 update_position(s, len); |
308 } | |
309 | |
310 fileStream::~fileStream() { | |
311 if (_file != NULL) { | |
312 if (_need_close) fclose(_file); | |
313 _file = NULL; | |
314 } | |
315 } | |
316 | |
317 void fileStream::flush() { | |
318 fflush(_file); | |
319 } | |
320 | |
321 fdStream::fdStream(const char* file_name) { | |
322 _fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
323 _need_close = true; | |
324 } | |
325 | |
326 fdStream::~fdStream() { | |
327 if (_fd != -1) { | |
328 if (_need_close) close(_fd); | |
329 _fd = -1; | |
330 } | |
331 } | |
332 | |
333 void fdStream::write(const char* s, size_t len) { | |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
356
diff
changeset
|
334 if (_fd != -1) { |
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
356
diff
changeset
|
335 // Make an unused local variable to avoid warning from gcc 4.x compiler. |
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
356
diff
changeset
|
336 size_t count = ::write(_fd, s, (int)len); |
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
356
diff
changeset
|
337 } |
0 | 338 update_position(s, len); |
339 } | |
340 | |
341 defaultStream* defaultStream::instance = NULL; | |
342 int defaultStream::_output_fd = 1; | |
343 int defaultStream::_error_fd = 2; | |
344 FILE* defaultStream::_output_stream = stdout; | |
345 FILE* defaultStream::_error_stream = stderr; | |
346 | |
347 #define LOG_MAJOR_VERSION 160 | |
348 #define LOG_MINOR_VERSION 1 | |
349 | |
350 void defaultStream::init() { | |
351 _inited = true; | |
352 if (LogVMOutput || LogCompilation) { | |
353 init_log(); | |
354 } | |
355 } | |
356 | |
357 bool defaultStream::has_log_file() { | |
358 // lazily create log file (at startup, LogVMOutput is false even | |
359 // if +LogVMOutput is used, because the flags haven't been parsed yet) | |
360 // For safer printing during fatal error handling, do not init logfile | |
361 // if a VM error has been reported. | |
362 if (!_inited && !is_error_reported()) init(); | |
363 return _log_file != NULL; | |
364 } | |
365 | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
366 static const char* make_log_name(const char* log_name, const char* force_directory) { |
0 | 367 const char* basename = log_name; |
368 char file_sep = os::file_separator()[0]; | |
369 const char* cp; | |
370 for (cp = log_name; *cp != '\0'; cp++) { | |
371 if (*cp == '/' || *cp == file_sep) { | |
372 basename = cp+1; | |
373 } | |
374 } | |
375 const char* nametail = log_name; | |
376 | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
377 // Compute buffer length |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
378 size_t buffer_length; |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
379 if (force_directory != NULL) { |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
380 buffer_length = strlen(force_directory) + strlen(os::file_separator()) + |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
381 strlen(basename) + 1; |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
382 } else { |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
383 buffer_length = strlen(log_name) + 1; |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
384 } |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
385 |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
386 const char* star = strchr(basename, '*'); |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
387 int star_pos = (star == NULL) ? -1 : (star - nametail); |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
388 |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
389 char pid[32]; |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
390 if (star_pos >= 0) { |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
391 jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id()); |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
392 buffer_length += strlen(pid); |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
393 } |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
394 |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
395 // Create big enough buffer. |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
396 char *buf = NEW_C_HEAP_ARRAY(char, buffer_length); |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
397 |
0 | 398 strcpy(buf, ""); |
399 if (force_directory != NULL) { | |
400 strcat(buf, force_directory); | |
401 strcat(buf, os::file_separator()); | |
402 nametail = basename; // completely skip directory prefix | |
403 } | |
404 | |
405 if (star_pos >= 0) { | |
406 // convert foo*bar.log to foo123bar.log | |
407 int buf_pos = (int) strlen(buf); | |
408 strncpy(&buf[buf_pos], nametail, star_pos); | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
409 strcpy(&buf[buf_pos + star_pos], pid); |
0 | 410 nametail += star_pos + 1; // skip prefix and star |
411 } | |
412 | |
413 strcat(buf, nametail); // append rest of name, or all of name | |
414 return buf; | |
415 } | |
416 | |
417 void defaultStream::init_log() { | |
418 // %%% Need a MutexLocker? | |
419 const char* log_name = LogFile != NULL ? LogFile : "hotspot.log"; | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
420 const char* try_name = make_log_name(log_name, NULL); |
0 | 421 fileStream* file = new(ResourceObj::C_HEAP) fileStream(try_name); |
422 if (!file->is_open()) { | |
423 // Try again to open the file. | |
424 char warnbuf[O_BUFLEN*2]; | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
425 jio_snprintf(warnbuf, sizeof(warnbuf), |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
426 "Warning: Cannot open log file: %s\n", try_name); |
0 | 427 // Note: This feature is for maintainer use only. No need for L10N. |
428 jio_print(warnbuf); | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
429 FREE_C_HEAP_ARRAY(char, try_name); |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
430 try_name = make_log_name("hs_pid*.log", os::get_temp_directory()); |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
431 jio_snprintf(warnbuf, sizeof(warnbuf), |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
432 "Warning: Forcing option -XX:LogFile=%s\n", try_name); |
0 | 433 jio_print(warnbuf); |
434 delete file; | |
435 file = new(ResourceObj::C_HEAP) fileStream(try_name); | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
579
diff
changeset
|
436 FREE_C_HEAP_ARRAY(char, try_name); |
0 | 437 } |
438 if (file->is_open()) { | |
439 _log_file = file; | |
440 xmlStream* xs = new(ResourceObj::C_HEAP) xmlStream(file); | |
441 _outer_xmlStream = xs; | |
442 if (this == tty) xtty = xs; | |
443 // Write XML header. | |
444 xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>"); | |
445 // (For now, don't bother to issue a DTD for this private format.) | |
446 jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds(); | |
447 // %%% Should be: jlong time_ms = os::start_time_milliseconds(), if | |
448 // we ever get round to introduce that method on the os class | |
449 xs->head("hotspot_log version='%d %d'" | |
450 " process='%d' time_ms='"INT64_FORMAT"'", | |
451 LOG_MAJOR_VERSION, LOG_MINOR_VERSION, | |
452 os::current_process_id(), time_ms); | |
453 // Write VM version header immediately. | |
454 xs->head("vm_version"); | |
455 xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr(); | |
456 xs->tail("name"); | |
457 xs->head("release"); xs->text("%s", VM_Version::vm_release()); xs->cr(); | |
458 xs->tail("release"); | |
459 xs->head("info"); xs->text("%s", VM_Version::internal_vm_info_string()); xs->cr(); | |
460 xs->tail("info"); | |
461 xs->tail("vm_version"); | |
462 // Record information about the command-line invocation. | |
463 xs->head("vm_arguments"); // Cf. Arguments::print_on() | |
464 if (Arguments::num_jvm_flags() > 0) { | |
465 xs->head("flags"); | |
466 Arguments::print_jvm_flags_on(xs->text()); | |
467 xs->tail("flags"); | |
468 } | |
469 if (Arguments::num_jvm_args() > 0) { | |
470 xs->head("args"); | |
471 Arguments::print_jvm_args_on(xs->text()); | |
472 xs->tail("args"); | |
473 } | |
474 if (Arguments::java_command() != NULL) { | |
475 xs->head("command"); xs->text()->print_cr("%s", Arguments::java_command()); | |
476 xs->tail("command"); | |
477 } | |
478 if (Arguments::sun_java_launcher() != NULL) { | |
479 xs->head("launcher"); xs->text()->print_cr("%s", Arguments::sun_java_launcher()); | |
480 xs->tail("launcher"); | |
481 } | |
482 if (Arguments::system_properties() != NULL) { | |
483 xs->head("properties"); | |
484 // Print it as a java-style property list. | |
485 // System properties don't generally contain newlines, so don't bother with unparsing. | |
486 for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) { | |
487 xs->text()->print_cr("%s=%s", p->key(), p->value()); | |
488 } | |
489 xs->tail("properties"); | |
490 } | |
491 xs->tail("vm_arguments"); | |
492 // tty output per se is grouped under the <tty>...</tty> element. | |
493 xs->head("tty"); | |
494 // All further non-markup text gets copied to the tty: | |
495 xs->_text = this; // requires friend declaration! | |
496 } else { | |
497 delete(file); | |
498 // and leave xtty as NULL | |
499 LogVMOutput = false; | |
500 DisplayVMOutput = true; | |
501 LogCompilation = false; | |
502 } | |
503 } | |
504 | |
505 // finish_log() is called during normal VM shutdown. finish_log_on_error() is | |
506 // called by ostream_abort() after a fatal error. | |
507 // | |
508 void defaultStream::finish_log() { | |
509 xmlStream* xs = _outer_xmlStream; | |
510 xs->done("tty"); | |
511 | |
512 // Other log forks are appended here, at the End of Time: | |
513 CompileLog::finish_log(xs->out()); // write compile logging, if any, now | |
514 | |
515 xs->done("hotspot_log"); | |
516 xs->flush(); | |
517 | |
518 fileStream* file = _log_file; | |
519 _log_file = NULL; | |
520 | |
521 delete _outer_xmlStream; | |
522 _outer_xmlStream = NULL; | |
523 | |
524 file->flush(); | |
525 delete file; | |
526 } | |
527 | |
528 void defaultStream::finish_log_on_error(char *buf, int buflen) { | |
529 xmlStream* xs = _outer_xmlStream; | |
530 | |
531 if (xs && xs->out()) { | |
532 | |
533 xs->done_raw("tty"); | |
534 | |
535 // Other log forks are appended here, at the End of Time: | |
536 CompileLog::finish_log_on_error(xs->out(), buf, buflen); // write compile logging, if any, now | |
537 | |
538 xs->done_raw("hotspot_log"); | |
539 xs->flush(); | |
540 | |
541 fileStream* file = _log_file; | |
542 _log_file = NULL; | |
543 _outer_xmlStream = NULL; | |
544 | |
545 if (file) { | |
546 file->flush(); | |
547 | |
548 // Can't delete or close the file because delete and fclose aren't | |
549 // async-safe. We are about to die, so leave it to the kernel. | |
550 // delete file; | |
551 } | |
552 } | |
553 } | |
554 | |
555 intx defaultStream::hold(intx writer_id) { | |
556 bool has_log = has_log_file(); // check before locking | |
557 if (// impossible, but who knows? | |
558 writer_id == NO_WRITER || | |
559 | |
560 // bootstrap problem | |
561 tty_lock == NULL || | |
562 | |
563 // can't grab a lock or call Thread::current() if TLS isn't initialized | |
564 ThreadLocalStorage::thread() == NULL || | |
565 | |
566 // developer hook | |
567 !SerializeVMOutput || | |
568 | |
569 // VM already unhealthy | |
570 is_error_reported() || | |
571 | |
572 // safepoint == global lock (for VM only) | |
573 (SafepointSynchronize::is_synchronizing() && | |
574 Thread::current()->is_VM_thread()) | |
575 ) { | |
576 // do not attempt to lock unless we know the thread and the VM is healthy | |
577 return NO_WRITER; | |
578 } | |
579 if (_writer == writer_id) { | |
580 // already held, no need to re-grab the lock | |
581 return NO_WRITER; | |
582 } | |
583 tty_lock->lock_without_safepoint_check(); | |
584 // got the lock | |
585 if (writer_id != _last_writer) { | |
586 if (has_log) { | |
587 _log_file->bol(); | |
588 // output a hint where this output is coming from: | |
589 _log_file->print_cr("<writer thread='"INTX_FORMAT"'/>", writer_id); | |
590 } | |
591 _last_writer = writer_id; | |
592 } | |
593 _writer = writer_id; | |
594 return writer_id; | |
595 } | |
596 | |
597 void defaultStream::release(intx holder) { | |
598 if (holder == NO_WRITER) { | |
599 // nothing to release: either a recursive lock, or we scribbled (too bad) | |
600 return; | |
601 } | |
602 if (_writer != holder) { | |
603 return; // already unlocked, perhaps via break_tty_lock_for_safepoint | |
604 } | |
605 _writer = NO_WRITER; | |
606 tty_lock->unlock(); | |
607 } | |
608 | |
609 | |
610 // Yuck: jio_print does not accept char*/len. | |
611 static void call_jio_print(const char* s, size_t len) { | |
612 char buffer[O_BUFLEN+100]; | |
613 if (len > sizeof(buffer)-1) { | |
614 warning("increase O_BUFLEN in ostream.cpp -- output truncated"); | |
615 len = sizeof(buffer)-1; | |
616 } | |
617 strncpy(buffer, s, len); | |
618 buffer[len] = '\0'; | |
619 jio_print(buffer); | |
620 } | |
621 | |
622 | |
623 void defaultStream::write(const char* s, size_t len) { | |
624 intx thread_id = os::current_thread_id(); | |
625 intx holder = hold(thread_id); | |
626 | |
627 if (DisplayVMOutput && | |
628 (_outer_xmlStream == NULL || !_outer_xmlStream->inside_attrs())) { | |
629 // print to output stream. It can be redirected by a vfprintf hook | |
630 if (s[len] == '\0') { | |
631 jio_print(s); | |
632 } else { | |
633 call_jio_print(s, len); | |
634 } | |
635 } | |
636 | |
637 // print to log file | |
638 if (has_log_file()) { | |
639 int nl0 = _newlines; | |
640 xmlTextStream::write(s, len); | |
641 // flush the log file too, if there were any newlines | |
642 if (nl0 != _newlines){ | |
643 flush(); | |
644 } | |
645 } else { | |
646 update_position(s, len); | |
647 } | |
648 | |
649 release(holder); | |
650 } | |
651 | |
652 intx ttyLocker::hold_tty() { | |
653 if (defaultStream::instance == NULL) return defaultStream::NO_WRITER; | |
654 intx thread_id = os::current_thread_id(); | |
655 return defaultStream::instance->hold(thread_id); | |
656 } | |
657 | |
658 void ttyLocker::release_tty(intx holder) { | |
659 if (holder == defaultStream::NO_WRITER) return; | |
660 defaultStream::instance->release(holder); | |
661 } | |
662 | |
663 void ttyLocker::break_tty_lock_for_safepoint(intx holder) { | |
664 if (defaultStream::instance != NULL && | |
665 defaultStream::instance->writer() == holder) { | |
666 if (xtty != NULL) { | |
667 xtty->print_cr("<!-- safepoint while printing -->"); | |
668 } | |
669 defaultStream::instance->release(holder); | |
670 } | |
671 // (else there was no lock to break) | |
672 } | |
673 | |
674 void ostream_init() { | |
675 if (defaultStream::instance == NULL) { | |
676 defaultStream::instance = new(ResourceObj::C_HEAP) defaultStream(); | |
677 tty = defaultStream::instance; | |
678 | |
679 // We want to ensure that time stamps in GC logs consider time 0 | |
680 // the time when the JVM is initialized, not the first time we ask | |
681 // for a time stamp. So, here, we explicitly update the time stamp | |
682 // of tty. | |
683 tty->time_stamp().update_to(1); | |
684 } | |
685 } | |
686 | |
687 void ostream_init_log() { | |
688 // For -Xloggc:<file> option - called in runtime/thread.cpp | |
689 // Note : this must be called AFTER ostream_init() | |
690 | |
691 gclog_or_tty = tty; // default to tty | |
692 if (Arguments::gc_log_filename() != NULL) { | |
693 fileStream * gclog = new(ResourceObj::C_HEAP) | |
694 fileStream(Arguments::gc_log_filename()); | |
695 if (gclog->is_open()) { | |
696 // now we update the time stamp of the GC log to be synced up | |
697 // with tty. | |
698 gclog->time_stamp().update_to(tty->time_stamp().ticks()); | |
699 gclog_or_tty = gclog; | |
700 } | |
701 } | |
702 | |
703 // If we haven't lazily initialized the logfile yet, do it now, | |
704 // to avoid the possibility of lazy initialization during a VM | |
705 // crash, which can affect the stability of the fatal error handler. | |
706 defaultStream::instance->has_log_file(); | |
707 } | |
708 | |
709 // ostream_exit() is called during normal VM exit to finish log files, flush | |
710 // output and free resource. | |
711 void ostream_exit() { | |
712 static bool ostream_exit_called = false; | |
713 if (ostream_exit_called) return; | |
714 ostream_exit_called = true; | |
715 if (gclog_or_tty != tty) { | |
716 delete gclog_or_tty; | |
717 } | |
718 { | |
719 // we temporaly disable PrintMallocFree here | |
720 // as otherwise it'll lead to using of almost deleted | |
721 // tty or defaultStream::instance in logging facility | |
722 // of HeapFree(), see 6391258 | |
723 DEBUG_ONLY(FlagSetting fs(PrintMallocFree, false);) | |
724 if (tty != defaultStream::instance) { | |
725 delete tty; | |
726 } | |
727 if (defaultStream::instance != NULL) { | |
728 delete defaultStream::instance; | |
729 } | |
730 } | |
731 tty = NULL; | |
732 xtty = NULL; | |
733 gclog_or_tty = NULL; | |
734 defaultStream::instance = NULL; | |
735 } | |
736 | |
737 // ostream_abort() is called by os::abort() when VM is about to die. | |
738 void ostream_abort() { | |
739 // Here we can't delete gclog_or_tty and tty, just flush their output | |
740 if (gclog_or_tty) gclog_or_tty->flush(); | |
741 if (tty) tty->flush(); | |
742 | |
743 if (defaultStream::instance != NULL) { | |
744 static char buf[4096]; | |
745 defaultStream::instance->finish_log_on_error(buf, sizeof(buf)); | |
746 } | |
747 } | |
748 | |
749 staticBufferStream::staticBufferStream(char* buffer, size_t buflen, | |
750 outputStream *outer_stream) { | |
751 _buffer = buffer; | |
752 _buflen = buflen; | |
753 _outer_stream = outer_stream; | |
754 } | |
755 | |
756 void staticBufferStream::write(const char* c, size_t len) { | |
757 _outer_stream->print_raw(c, (int)len); | |
758 } | |
759 | |
760 void staticBufferStream::flush() { | |
761 _outer_stream->flush(); | |
762 } | |
763 | |
764 void staticBufferStream::print(const char* format, ...) { | |
765 va_list ap; | |
766 va_start(ap, format); | |
767 size_t len; | |
768 const char* str = do_vsnprintf(_buffer, _buflen, format, ap, false, len); | |
769 write(str, len); | |
770 va_end(ap); | |
771 } | |
772 | |
773 void staticBufferStream::print_cr(const char* format, ...) { | |
774 va_list ap; | |
775 va_start(ap, format); | |
776 size_t len; | |
777 const char* str = do_vsnprintf(_buffer, _buflen, format, ap, true, len); | |
778 write(str, len); | |
779 va_end(ap); | |
780 } | |
781 | |
782 void staticBufferStream::vprint(const char *format, va_list argptr) { | |
783 size_t len; | |
784 const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, false, len); | |
785 write(str, len); | |
786 } | |
787 | |
788 void staticBufferStream::vprint_cr(const char* format, va_list argptr) { | |
789 size_t len; | |
790 const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, true, len); | |
791 write(str, len); | |
792 } | |
793 | |
222 | 794 bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() { |
0 | 795 buffer_length = initial_size; |
796 buffer = NEW_C_HEAP_ARRAY(char, buffer_length); | |
797 buffer_pos = 0; | |
798 buffer_fixed = false; | |
222 | 799 buffer_max = bufmax; |
0 | 800 } |
801 | |
222 | 802 bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() { |
0 | 803 buffer_length = fixed_buffer_size; |
804 buffer = fixed_buffer; | |
805 buffer_pos = 0; | |
806 buffer_fixed = true; | |
222 | 807 buffer_max = bufmax; |
0 | 808 } |
809 | |
810 void bufferedStream::write(const char* s, size_t len) { | |
222 | 811 |
812 if(buffer_pos + len > buffer_max) { | |
813 flush(); | |
814 } | |
815 | |
0 | 816 size_t end = buffer_pos + len; |
817 if (end >= buffer_length) { | |
818 if (buffer_fixed) { | |
819 // if buffer cannot resize, silently truncate | |
820 len = buffer_length - buffer_pos - 1; | |
821 } else { | |
822 // For small overruns, double the buffer. For larger ones, | |
823 // increase to the requested size. | |
824 if (end < buffer_length * 2) { | |
825 end = buffer_length * 2; | |
826 } | |
827 buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end); | |
828 buffer_length = end; | |
829 } | |
830 } | |
831 memcpy(buffer + buffer_pos, s, len); | |
832 buffer_pos += len; | |
833 update_position(s, len); | |
834 } | |
835 | |
836 char* bufferedStream::as_string() { | |
837 char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1); | |
838 strncpy(copy, buffer, buffer_pos); | |
839 copy[buffer_pos] = 0; // terminating null | |
840 return copy; | |
841 } | |
842 | |
843 bufferedStream::~bufferedStream() { | |
844 if (!buffer_fixed) { | |
845 FREE_C_HEAP_ARRAY(char, buffer); | |
846 } | |
847 } | |
848 | |
849 #ifndef PRODUCT | |
850 | |
851 #if defined(SOLARIS) || defined(LINUX) | |
852 #include <sys/types.h> | |
853 #include <sys/socket.h> | |
854 #include <netinet/in.h> | |
855 #include <arpa/inet.h> | |
856 #endif | |
857 | |
858 // Network access | |
222 | 859 networkStream::networkStream() : bufferedStream(1024*10, 1024*10) { |
0 | 860 |
861 _socket = -1; | |
862 | |
863 hpi::initialize_socket_library(); | |
864 | |
865 int result = hpi::socket(AF_INET, SOCK_STREAM, 0); | |
866 if (result <= 0) { | |
867 assert(false, "Socket could not be created!"); | |
868 } else { | |
869 _socket = result; | |
870 } | |
871 } | |
872 | |
873 int networkStream::read(char *buf, size_t len) { | |
874 return hpi::recv(_socket, buf, (int)len, 0); | |
875 } | |
876 | |
877 void networkStream::flush() { | |
878 if (size() != 0) { | |
222 | 879 int result = hpi::raw_send(_socket, (char *)base(), (int)size(), 0); |
880 assert(result != -1, "connection error"); | |
881 assert(result == (int)size(), "didn't send enough data"); | |
0 | 882 } |
883 reset(); | |
884 } | |
885 | |
886 networkStream::~networkStream() { | |
887 close(); | |
888 } | |
889 | |
890 void networkStream::close() { | |
891 if (_socket != -1) { | |
892 flush(); | |
893 hpi::socket_close(_socket); | |
894 _socket = -1; | |
895 } | |
896 } | |
897 | |
898 bool networkStream::connect(const char *ip, short port) { | |
899 | |
900 struct sockaddr_in server; | |
901 server.sin_family = AF_INET; | |
902 server.sin_port = htons(port); | |
903 | |
904 server.sin_addr.s_addr = inet_addr(ip); | |
80
092ea87cc974
6679422: networkStream::connect() in ostream.cpp is not 64-bit clean
jcoomes
parents:
0
diff
changeset
|
905 if (server.sin_addr.s_addr == (uint32_t)-1) { |
0 | 906 #ifdef _WINDOWS |
907 struct hostent* host = hpi::get_host_by_name((char*)ip); | |
908 #else | |
909 struct hostent* host = gethostbyname(ip); | |
910 #endif | |
911 if (host != NULL) { | |
912 memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length); | |
913 } else { | |
914 return false; | |
915 } | |
916 } | |
917 | |
918 | |
919 int result = hpi::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in)); | |
920 return (result >= 0); | |
921 } | |
922 | |
923 #endif |