1 /* 2 * Copyright (c) 1997, 2025, 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 #include "utilities/macros.hpp" 32 33 DEBUG_ONLY(class ResourceMark;) 34 35 // Output streams for printing 36 // 37 // Printing guidelines: 38 // Where possible, please use tty->print() and tty->print_cr(). 39 // For product mode VM warnings use warning() which internally uses tty. 40 // In places where tty is not initialized yet or too much overhead, 41 // we may use jio_printf: 42 // jio_fprintf(defaultStream::output_stream(), "Message"); 43 // This allows for redirection via -XX:+DisplayVMOutputToStdout and 44 // -XX:+DisplayVMOutputToStderr. 45 46 class outputStream : public CHeapObjBase { 47 friend class StreamIndentor; 48 49 private: 50 NONCOPYABLE(outputStream); 51 int _indentation; // current indentation 52 bool _autoindent; // if true, every line starts with indentation 53 54 protected: 55 int _position; // visual position on the current line 56 uint64_t _precount; // number of chars output, less than _position 57 TimeStamp _stamp; // for time stamps 58 char* _scratch; // internal scratch buffer for printf 59 size_t _scratch_len; // size of internal scratch buffer 60 61 // Returns whether a newline was seen or not 62 bool update_position(const char* s, size_t len); 63 64 // Processes the given format string and the supplied arguments 65 // to produce a formatted string in the supplied buffer. Returns 66 // the formatted string (in the buffer). If the formatted string 67 // would be longer than the buffer, it is truncated. 68 // 69 // If the format string is a plain string (no format specifiers) 70 // or is exactly "%s" to print a supplied argument string, then 71 // the buffer is ignored, and we return the string directly. 72 // However, if `add_cr` is true then we have to copy the string 73 // into the buffer, which risks truncation if the string is too long. 74 // 75 // The `result_len` reference is always set to the length of the returned string. 76 // 77 // If add_cr is true then the cr will always be placed in the buffer (buffer minimum size is 2). 78 // 79 // In a debug build, if truncation occurs a VM warning is issued. 80 static const char* do_vsnprintf(char* buffer, size_t buflen, 81 const char* format, va_list ap, 82 bool add_cr, 83 size_t& result_len) ATTRIBUTE_PRINTF(3, 0); 84 85 // calls do_vsnprintf and writes output to stream; uses an on-stack buffer. 86 void do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0); 87 // calls do_vsnprintf and writes output to stream; uses the user-provided buffer; 88 void do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0); 89 // calls do_vsnprintf, then writes output to stream. 90 void do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0); 91 92 // Automatic indentation. Returns old autoindent state. 93 bool set_autoindent(bool value); 94 95 public: 96 class TestSupport; // Unit test support 97 98 // creation 99 outputStream(bool has_time_stamps = false); 100 101 // indentation 102 outputStream& indent(); 103 void inc() { _indentation++; }; 104 void dec() { _indentation--; }; 105 void inc(int n) { _indentation += n; }; 106 void dec(int n) { _indentation -= n; }; 107 int indentation() const { return _indentation; } 108 void set_indentation(int i) { _indentation = i; } 109 int fill_to(int col); 110 void move_to(int col, int slop = 6, int min_space = 2); 111 112 // sizing 113 int position() const { return _position; } 114 julong count() const { return _precount + _position; } 115 void set_count(julong count) { _precount = count - _position; } 116 void set_position(int pos) { _position = pos; } 117 118 // printing 119 // Note that (v)print_cr forces the use of internal buffering to allow 120 // appending of the "cr". This can lead to truncation if the buffer is 121 // too small. 122 123 void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); 124 void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); 125 void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); 126 void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0); 127 void print_raw(const char* str) { print_raw(str, strlen(str)); } 128 void print_raw(const char* str, size_t len); 129 void print_raw_cr(const char* str) { print_raw(str); cr(); } 130 void print_raw_cr(const char* str, size_t len) { print_raw(str, len); cr(); } 131 void print_data(void* data, size_t len, bool with_ascii, bool rel_addr=true); 132 void put(char ch); 133 void sp(int count = 1); 134 void cr(); 135 void bol() { if (_position > 0) cr(); } 136 137 138 // Time stamp 139 TimeStamp& time_stamp() { return _stamp; } 140 void stamp(); 141 void stamp(bool guard, const char* prefix, const char* suffix); 142 void stamp(bool guard) { 143 stamp(guard, "", ": "); 144 } 145 // Date stamp 146 void date_stamp(bool guard, const char* prefix, const char* suffix); 147 // A simplified call that includes a suffix of ": " 148 void date_stamp(bool guard) { 149 date_stamp(guard, "", ": "); 150 } 151 152 // portable printing of 64 bit integers 153 void print_jlong(jlong value); 154 void print_julong(julong value); 155 156 // flushing 157 virtual void flush() {} 158 virtual void write(const char* str, size_t len) = 0; 159 virtual void rotate_log(bool force, outputStream* out = nullptr) {} // GC log rotation 160 virtual ~outputStream() {} // close properly on deletion 161 162 // Caller may specify their own scratch buffer to use for printing; otherwise, 163 // an automatic buffer on the stack (with O_BUFLEN len) is used. 164 void set_scratch_buffer(char* p, size_t len) { _scratch = p; _scratch_len = len; } 165 166 void dec_cr() { dec(); cr(); } 167 void inc_cr() { inc(); cr(); } 168 }; 169 170 // standard output 171 // ANSI C++ name collision 172 extern outputStream* tty; // tty output 173 174 // outputStream indentation. When used, indentation is automatically applied 175 // when printing on the stream using the following APIs: 176 // print(), print_cr(), print_raw(), print_raw_cr() 177 class StreamIndentor { 178 private: 179 outputStream* const _stream; 180 const int _indentation; 181 const bool _old_autoindent; 182 NONCOPYABLE(StreamIndentor); 183 184 public: 185 StreamIndentor(outputStream* os, int indentation) : 186 _stream(os), 187 _indentation(indentation), 188 _old_autoindent(_stream->set_autoindent(true)) { 189 190 _stream->inc(_indentation); 191 } 192 193 ~StreamIndentor() { 194 _stream->dec(_indentation); 195 _stream->set_autoindent(_old_autoindent); 196 } 197 }; 198 199 // advisory locking for the shared tty stream: 200 class ttyLocker: StackObj { 201 friend class ttyUnlocker; 202 private: 203 intx _holder; 204 205 public: 206 static intx hold_tty(); // returns a "holder" token 207 static void release_tty(intx holder); // must witness same token 208 static bool release_tty_if_locked(); // returns true if lock was released 209 static void break_tty_lock_for_safepoint(intx holder); 210 211 ttyLocker() { _holder = hold_tty(); } 212 ~ttyLocker() { release_tty(_holder); } 213 }; 214 215 // Release the tty lock if it's held and reacquire it if it was 216 // locked. Used to avoid lock ordering problems. 217 class ttyUnlocker: StackObj { 218 private: 219 bool _was_locked; 220 public: 221 ttyUnlocker() { 222 _was_locked = ttyLocker::release_tty_if_locked(); 223 } 224 ~ttyUnlocker() { 225 if (_was_locked) { 226 ttyLocker::hold_tty(); 227 } 228 } 229 }; 230 231 // for writing to strings; buffer will expand automatically. 232 // Buffer will always be zero-terminated. 233 class stringStream : public outputStream { 234 DEBUG_ONLY(bool _is_frozen = false); 235 char* _buffer; 236 size_t _written; // Number of characters written, excluding termin. zero 237 size_t _capacity; 238 const bool _is_fixed; 239 char _small_buffer[48]; 240 241 // Grow backing buffer to desired capacity. 242 void grow(size_t new_capacity); 243 244 // zero terminate at buffer_pos. 245 void zero_terminate(); 246 247 public: 248 // Create a stringStream using an internal buffer of initially initial_bufsize size; 249 // will be enlarged on demand. There is no maximum cap. 250 stringStream(size_t initial_capacity = 0); 251 // Creates a stringStream using a caller-provided buffer. Will truncate silently if 252 // it overflows. 253 stringStream(char* fixed_buffer, size_t fixed_buffer_size); 254 ~stringStream(); 255 virtual void write(const char* c, size_t len); 256 // Return number of characters written into buffer, excluding terminating zero and 257 // subject to truncation in static buffer mode. 258 size_t size() const { return _written; } 259 // Returns internal buffer containing the accumulated string. 260 // Returned buffer is only guaranteed to be valid as long as stream is not modified 261 const char* base() const { return _buffer; } 262 // Freezes stringStream (no further modifications possible) and returns pointer to it. 263 // No-op if stream is frozen already. 264 // Returns the internal buffer containing the accumulated string. 265 const char* freeze() NOT_DEBUG(const) { 266 DEBUG_ONLY(_is_frozen = true); 267 return _buffer; 268 }; 269 void reset(); 270 bool is_empty() const { return _buffer[0] == '\0'; } 271 // Copy to a resource, or C-heap, array as requested 272 char* as_string(bool c_heap = false) const; 273 char* as_string(Arena* arena) const; 274 }; 275 276 class fileStream : public outputStream { 277 protected: 278 FILE* _file; 279 bool _need_close; 280 public: 281 fileStream() { _file = nullptr; _need_close = false; } 282 fileStream(const char* file_name); 283 fileStream(const char* file_name, const char* opentype); 284 fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; } 285 ~fileStream(); 286 bool is_open() const { return _file != nullptr; } 287 virtual void write(const char* c, size_t len); 288 // unlike other classes in this file, fileStream can perform input as well as output 289 size_t read(void* data, size_t size) { 290 if (_file == nullptr) return 0; 291 return ::fread(data, 1, size, _file); 292 } 293 size_t read(void *data, size_t size, size_t count) { 294 return read(data, size * count); 295 } 296 void close() { 297 if (_file == nullptr || !_need_close) return; 298 fclose(_file); 299 _need_close = false; 300 } 301 long fileSize(); 302 void flush(); 303 }; 304 305 // unlike fileStream, fdStream does unbuffered I/O by calling 306 // open() and write() directly. It is async-safe, but output 307 // from multiple thread may be mixed together. Used by fatal 308 // error handler. 309 class fdStream : public outputStream { 310 protected: 311 int _fd; 312 static fdStream _stdout_stream; 313 static fdStream _stderr_stream; 314 public: 315 fdStream(int fd = -1) : _fd(fd) { } 316 bool is_open() const { return _fd != -1; } 317 void set_fd(int fd) { _fd = fd; } 318 int fd() const { return _fd; } 319 virtual void write(const char* c, size_t len); 320 void flush() {}; 321 322 // predefined streams for unbuffered IO to stdout, stderr 323 static fdStream* stdout_stream() { return &_stdout_stream; } 324 static fdStream* stderr_stream() { return &_stderr_stream; } 325 }; 326 327 // A /dev/null equivalent stream 328 class nullStream : public outputStream { 329 public: 330 void write(const char* c, size_t len) {} 331 void flush() {}; 332 }; 333 334 void ostream_init(); 335 void ostream_init_log(); 336 void ostream_exit(); 337 void ostream_abort(); 338 const char* make_log_name(const char* log_name, const char* force_directory); 339 340 // In the non-fixed buffer case an underlying buffer will be created and 341 // managed in C heap. Not MT-safe. 342 class bufferedStream : public outputStream { 343 protected: 344 char* buffer; 345 size_t buffer_pos; 346 size_t buffer_max; 347 size_t buffer_length; 348 bool truncated; 349 public: 350 bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10); 351 ~bufferedStream(); 352 virtual void write(const char* c, size_t len); 353 size_t size() { return buffer_pos; } 354 const char* base() { return buffer; } 355 void reset() { buffer_pos = 0; _precount = 0; _position = 0; } 356 char* as_string(); 357 }; 358 359 #define O_BUFLEN 2000 // max size of output of individual print() methods 360 361 #ifndef PRODUCT 362 363 class networkStream : public bufferedStream { 364 365 private: 366 int _socket; 367 368 public: 369 networkStream(); 370 ~networkStream(); 371 372 bool connect(const char *host, short port); 373 bool is_open() const { return _socket != -1; } 374 ssize_t read(char *buf, size_t len); 375 void close(); 376 virtual void flush(); 377 }; 378 379 #endif 380 381 #endif // SHARE_UTILITIES_OSTREAM_HPP