1 | /* |
2 | * Copyright (c) 1997, 2019, 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 | #ifndef SHARE_UTILITIES_OSTREAM_HPP |
26 | #define SHARE_UTILITIES_OSTREAM_HPP |
27 | |
28 | #include "memory/allocation.hpp" |
29 | #include "runtime/timer.hpp" |
30 | #include "utilities/globalDefinitions.hpp" |
31 | |
32 | DEBUG_ONLY(class ResourceMark;) |
33 | |
34 | // Output streams for printing |
35 | // |
36 | // Printing guidelines: |
37 | // Where possible, please use tty->print() and tty->print_cr(). |
38 | // For product mode VM warnings use warning() which internally uses tty. |
39 | // In places where tty is not initialized yet or too much overhead, |
40 | // we may use jio_printf: |
41 | // jio_fprintf(defaultStream::output_stream(), "Message"); |
42 | // This allows for redirection via -XX:+DisplayVMOutputToStdout and |
43 | // -XX:+DisplayVMOutputToStderr |
44 | class outputStream : public ResourceObj { |
45 | private: |
46 | outputStream(const outputStream&); |
47 | outputStream& operator=(const outputStream&); |
48 | |
49 | protected: |
50 | int _indentation; // current indentation |
51 | int _width; // width of the page |
52 | int _position; // position on the current line |
53 | int _newlines; // number of '\n' output so far |
54 | julong _precount; // number of chars output, less _position |
55 | TimeStamp _stamp; // for time stamps |
56 | char* _scratch; // internal scratch buffer for printf |
57 | size_t _scratch_len; // size of internal scratch buffer |
58 | |
59 | void update_position(const char* s, size_t len); |
60 | static const char* do_vsnprintf(char* buffer, size_t buflen, |
61 | const char* format, va_list ap, |
62 | bool add_cr, |
63 | size_t& result_len) ATTRIBUTE_PRINTF(3, 0); |
64 | |
65 | // calls do_vsnprintf and writes output to stream; uses an on-stack buffer. |
66 | void do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0); |
67 | // calls do_vsnprintf and writes output to stream; uses the user-provided buffer; |
68 | void do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0); |
69 | // calls do_vsnprintf, then writes output to stream. |
70 | void do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0); |
71 | |
72 | public: |
73 | // creation |
74 | outputStream(int width = 80); |
75 | outputStream(int width, bool has_time_stamps); |
76 | |
77 | // indentation |
78 | outputStream& indent(); |
79 | void inc() { _indentation++; }; |
80 | void dec() { _indentation--; }; |
81 | void inc(int n) { _indentation += n; }; |
82 | void dec(int n) { _indentation -= n; }; |
83 | int indentation() const { return _indentation; } |
84 | void set_indentation(int i) { _indentation = i; } |
85 | void fill_to(int col); |
86 | void move_to(int col, int slop = 6, int min_space = 2); |
87 | |
88 | // sizing |
89 | int width() const { return _width; } |
90 | int position() const { return _position; } |
91 | int newlines() const { return _newlines; } |
92 | julong count() const { return _precount + _position; } |
93 | void set_count(julong count) { _precount = count - _position; } |
94 | void set_position(int pos) { _position = pos; } |
95 | |
96 | // printing |
97 | void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
98 | void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
99 | void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); |
100 | void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); |
101 | void print_raw(const char* str) { write(str, strlen(str)); } |
102 | void print_raw(const char* str, int len) { write(str, len); } |
103 | void print_raw_cr(const char* str) { write(str, strlen(str)); cr(); } |
104 | void print_raw_cr(const char* str, int len){ write(str, len); cr(); } |
105 | void print_data(void* data, size_t len, bool with_ascii); |
106 | void put(char ch); |
107 | void sp(int count = 1); |
108 | void cr(); |
109 | void cr_indent(); |
110 | void bol() { if (_position > 0) cr(); } |
111 | |
112 | |
113 | // Time stamp |
114 | TimeStamp& time_stamp() { return _stamp; } |
115 | void stamp(); |
116 | void stamp(bool guard, const char* prefix, const char* suffix); |
117 | void stamp(bool guard) { |
118 | stamp(guard, "" , ": " ); |
119 | } |
120 | // Date stamp |
121 | void date_stamp(bool guard, const char* prefix, const char* suffix); |
122 | // A simplified call that includes a suffix of ": " |
123 | void date_stamp(bool guard) { |
124 | date_stamp(guard, "" , ": " ); |
125 | } |
126 | |
127 | // portable printing of 64 bit integers |
128 | void print_jlong(jlong value); |
129 | void print_julong(julong value); |
130 | |
131 | // flushing |
132 | virtual void flush() {} |
133 | virtual void write(const char* str, size_t len) = 0; |
134 | virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation |
135 | virtual ~outputStream() {} // close properly on deletion |
136 | |
137 | // Caller may specify their own scratch buffer to use for printing; otherwise, |
138 | // an automatic buffer on the stack (with O_BUFLEN len) is used. |
139 | void set_scratch_buffer(char* p, size_t len) { _scratch = p; _scratch_len = len; } |
140 | |
141 | void dec_cr() { dec(); cr(); } |
142 | void inc_cr() { inc(); cr(); } |
143 | }; |
144 | |
145 | // standard output |
146 | // ANSI C++ name collision |
147 | extern outputStream* tty; // tty output |
148 | |
149 | class streamIndentor : public StackObj { |
150 | private: |
151 | outputStream* _str; |
152 | int _amount; |
153 | |
154 | public: |
155 | streamIndentor(outputStream* str, int amt = 2) : _str(str), _amount(amt) { |
156 | _str->inc(_amount); |
157 | } |
158 | ~streamIndentor() { _str->dec(_amount); } |
159 | }; |
160 | |
161 | // advisory locking for the shared tty stream: |
162 | class ttyLocker: StackObj { |
163 | friend class ttyUnlocker; |
164 | private: |
165 | intx _holder; |
166 | |
167 | public: |
168 | static intx hold_tty(); // returns a "holder" token |
169 | static void release_tty(intx holder); // must witness same token |
170 | static bool release_tty_if_locked(); // returns true if lock was released |
171 | static void break_tty_lock_for_safepoint(intx holder); |
172 | |
173 | ttyLocker() { _holder = hold_tty(); } |
174 | ~ttyLocker() { release_tty(_holder); } |
175 | }; |
176 | |
177 | // Release the tty lock if it's held and reacquire it if it was |
178 | // locked. Used to avoid lock ordering problems. |
179 | class ttyUnlocker: StackObj { |
180 | private: |
181 | bool _was_locked; |
182 | public: |
183 | ttyUnlocker() { |
184 | _was_locked = ttyLocker::release_tty_if_locked(); |
185 | } |
186 | ~ttyUnlocker() { |
187 | if (_was_locked) { |
188 | ttyLocker::hold_tty(); |
189 | } |
190 | } |
191 | }; |
192 | |
193 | // for writing to strings; buffer will expand automatically. |
194 | // Buffer will always be zero-terminated. |
195 | class stringStream : public outputStream { |
196 | protected: |
197 | char* buffer; |
198 | size_t buffer_pos; |
199 | size_t buffer_length; |
200 | bool buffer_fixed; |
201 | |
202 | // zero terminate at buffer_pos. |
203 | void zero_terminate(); |
204 | |
205 | public: |
206 | // Create a stringStream using an internal buffer of initially initial_bufsize size; |
207 | // will be enlarged on demand. There is no maximum cap. |
208 | stringStream(size_t initial_bufsize = 256); |
209 | // Creates a stringStream using a caller-provided buffer. Will truncate silently if |
210 | // it overflows. |
211 | stringStream(char* fixed_buffer, size_t fixed_buffer_size); |
212 | ~stringStream(); |
213 | virtual void write(const char* c, size_t len); |
214 | // Return number of characters written into buffer, excluding terminating zero and |
215 | // subject to truncation in static buffer mode. |
216 | size_t size() const { return buffer_pos; } |
217 | const char* base() const { return buffer; } |
218 | void reset(); |
219 | char* as_string() const; |
220 | }; |
221 | |
222 | class fileStream : public outputStream { |
223 | protected: |
224 | FILE* _file; |
225 | bool _need_close; |
226 | public: |
227 | fileStream() { _file = NULL; _need_close = false; } |
228 | fileStream(const char* file_name); |
229 | fileStream(const char* file_name, const char* opentype); |
230 | fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; } |
231 | ~fileStream(); |
232 | bool is_open() const { return _file != NULL; } |
233 | virtual void write(const char* c, size_t len); |
234 | size_t read(void *data, size_t size, size_t count) { return ::fread(data, size, count, _file); } |
235 | char* readln(char *data, int count); |
236 | int eof() { return feof(_file); } |
237 | long fileSize(); |
238 | void rewind() { ::rewind(_file); } |
239 | void flush(); |
240 | }; |
241 | |
242 | CDS_ONLY(extern fileStream* classlist_file;) |
243 | |
244 | // unlike fileStream, fdStream does unbuffered I/O by calling |
245 | // open() and write() directly. It is async-safe, but output |
246 | // from multiple thread may be mixed together. Used by fatal |
247 | // error handler. |
248 | class fdStream : public outputStream { |
249 | protected: |
250 | int _fd; |
251 | public: |
252 | fdStream(int fd = -1) : _fd(fd) { } |
253 | bool is_open() const { return _fd != -1; } |
254 | void set_fd(int fd) { _fd = fd; } |
255 | int fd() const { return _fd; } |
256 | virtual void write(const char* c, size_t len); |
257 | void flush() {}; |
258 | }; |
259 | |
260 | void ostream_init(); |
261 | void ostream_init_log(); |
262 | void ostream_exit(); |
263 | void ostream_abort(); |
264 | |
265 | // In the non-fixed buffer case an underlying buffer will be created and |
266 | // managed in C heap. Not MT-safe. |
267 | class bufferedStream : public outputStream { |
268 | protected: |
269 | char* buffer; |
270 | size_t buffer_pos; |
271 | size_t buffer_max; |
272 | size_t buffer_length; |
273 | bool buffer_fixed; |
274 | bool truncated; |
275 | public: |
276 | bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10); |
277 | bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax = 1024*1024*10); |
278 | ~bufferedStream(); |
279 | virtual void write(const char* c, size_t len); |
280 | size_t size() { return buffer_pos; } |
281 | const char* base() { return buffer; } |
282 | void reset() { buffer_pos = 0; _precount = 0; _position = 0; } |
283 | char* as_string(); |
284 | }; |
285 | |
286 | #define O_BUFLEN 2000 // max size of output of individual print() methods |
287 | |
288 | #ifndef PRODUCT |
289 | |
290 | class networkStream : public bufferedStream { |
291 | |
292 | private: |
293 | int _socket; |
294 | |
295 | public: |
296 | networkStream(); |
297 | ~networkStream(); |
298 | |
299 | bool connect(const char *host, short port); |
300 | bool is_open() const { return _socket != -1; } |
301 | int read(char *buf, size_t len); |
302 | void close(); |
303 | virtual void flush(); |
304 | }; |
305 | |
306 | #endif |
307 | |
308 | #endif // SHARE_UTILITIES_OSTREAM_HPP |
309 | |