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 // Append strings returned by gen, separating each with separator. 170 // Stops when gen returns null. 171 template <typename Generator> 172 void join(Generator gen, const char* separator) { 173 bool first = true; 174 const char* str = gen(); 175 while (str != nullptr) { 176 const char* sep = first ? "" : separator; 177 print("%s%s", sep, str); 178 first = false; 179 str = gen(); 180 } 181 } 182 }; 183 184 // standard output 185 // ANSI C++ name collision 186 extern outputStream* tty; // tty output 187 188 // outputStream indentation. When used, indentation is automatically applied 189 // when printing on the stream using the following APIs: 190 // print(), print_cr(), print_raw(), print_raw_cr() 191 class StreamIndentor { 192 private: 193 outputStream* const _stream; 194 const int _indentation; 195 const bool _old_autoindent; 196 NONCOPYABLE(StreamIndentor); 197 198 public: 199 StreamIndentor(outputStream* os, int indentation) : 200 _stream(os), 201 _indentation(indentation), 202 _old_autoindent(_stream->set_autoindent(true)) { 203 204 _stream->inc(_indentation); 205 } 206 207 ~StreamIndentor() { 208 _stream->dec(_indentation); 209 _stream->set_autoindent(_old_autoindent); 210 } 211 }; 212 213 // advisory locking for the shared tty stream: 214 class ttyLocker: StackObj { 215 friend class ttyUnlocker; 216 private: 217 intx _holder; 218 219 public: 220 static intx hold_tty(); // returns a "holder" token 221 static void release_tty(intx holder); // must witness same token 222 static bool release_tty_if_locked(); // returns true if lock was released 223 static void break_tty_lock_for_safepoint(intx holder); 224 225 ttyLocker() { _holder = hold_tty(); } 226 ~ttyLocker() { release_tty(_holder); } 227 }; 228 229 // Release the tty lock if it's held and reacquire it if it was 230 // locked. Used to avoid lock ordering problems. 231 class ttyUnlocker: StackObj { 232 private: 233 bool _was_locked; 234 public: 235 ttyUnlocker() { 236 _was_locked = ttyLocker::release_tty_if_locked(); 237 } 238 ~ttyUnlocker() { 239 if (_was_locked) { 240 ttyLocker::hold_tty(); 241 } 242 } 243 }; 244 245 // for writing to strings; buffer will expand automatically. 246 // Buffer will always be zero-terminated. 247 class stringStream : public outputStream { 248 DEBUG_ONLY(bool _is_frozen = false); 249 char* _buffer; 250 size_t _written; // Number of characters written, excluding termin. zero 251 size_t _capacity; 252 const bool _is_fixed; 253 char _small_buffer[48]; 254 255 // Grow backing buffer to desired capacity. 256 void grow(size_t new_capacity); 257 258 // zero terminate at buffer_pos. 259 void zero_terminate(); 260 261 public: 262 // Create a stringStream using an internal buffer of initially initial_bufsize size; 263 // will be enlarged on demand. There is no maximum cap. 264 stringStream(size_t initial_capacity = 0); 265 // Creates a stringStream using a caller-provided buffer. Will truncate silently if 266 // it overflows. 267 stringStream(char* fixed_buffer, size_t fixed_buffer_size); 268 ~stringStream(); 269 virtual void write(const char* c, size_t len); 270 // Return number of characters written into buffer, excluding terminating zero and 271 // subject to truncation in static buffer mode. 272 size_t size() const { return _written; } 273 // Returns internal buffer containing the accumulated string. 274 // Returned buffer is only guaranteed to be valid as long as stream is not modified 275 const char* base() const { return _buffer; } 276 // Freezes stringStream (no further modifications possible) and returns pointer to it. 277 // No-op if stream is frozen already. 278 // Returns the internal buffer containing the accumulated string. 279 const char* freeze() NOT_DEBUG(const) { 280 DEBUG_ONLY(_is_frozen = true); 281 return _buffer; 282 }; 283 void reset(); 284 bool is_empty() const { return _buffer[0] == '\0'; } 285 // Copy to a resource, or C-heap, array as requested 286 char* as_string(bool c_heap = false) const; 287 char* as_string(Arena* arena) const; 288 }; 289 290 class fileStream : public outputStream { 291 protected: 292 FILE* _file; 293 bool _need_close; 294 public: 295 fileStream() { _file = nullptr; _need_close = false; } 296 fileStream(const char* file_name); 297 fileStream(const char* file_name, const char* opentype); 298 fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; } 299 ~fileStream(); 300 bool is_open() const { return _file != nullptr; } 301 virtual void write(const char* c, size_t len); 302 // unlike other classes in this file, fileStream can perform input as well as output 303 size_t read(void* data, size_t size) { 304 if (_file == nullptr) return 0; 305 return ::fread(data, 1, size, _file); 306 } 307 size_t read(void *data, size_t size, size_t count) { 308 return read(data, size * count); 309 } 310 void close() { 311 if (_file == nullptr || !_need_close) return; 312 fclose(_file); 313 _need_close = false; 314 } 315 long fileSize(); 316 void flush(); 317 }; 318 319 // unlike fileStream, fdStream does unbuffered I/O by calling 320 // open() and write() directly. It is async-safe, but output 321 // from multiple thread may be mixed together. Used by fatal 322 // error handler. 323 class fdStream : public outputStream { 324 protected: 325 int _fd; 326 static fdStream _stdout_stream; 327 static fdStream _stderr_stream; 328 public: 329 fdStream(int fd = -1) : _fd(fd) { } 330 bool is_open() const { return _fd != -1; } 331 void set_fd(int fd) { _fd = fd; } 332 int fd() const { return _fd; } 333 virtual void write(const char* c, size_t len); 334 void flush() {}; 335 336 // predefined streams for unbuffered IO to stdout, stderr 337 static fdStream* stdout_stream() { return &_stdout_stream; } 338 static fdStream* stderr_stream() { return &_stderr_stream; } 339 }; 340 341 // A /dev/null equivalent stream 342 class nullStream : public outputStream { 343 public: 344 void write(const char* c, size_t len) {} 345 void flush() {}; 346 }; 347 348 void ostream_init(); 349 void ostream_init_log(); 350 void ostream_exit(); 351 void ostream_abort(); 352 const char* make_log_name(const char* log_name, const char* force_directory); 353 354 // In the non-fixed buffer case an underlying buffer will be created and 355 // managed in C heap. Not MT-safe. 356 class bufferedStream : public outputStream { 357 protected: 358 char* buffer; 359 size_t buffer_pos; 360 size_t buffer_max; 361 size_t buffer_length; 362 bool truncated; 363 public: 364 bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10); 365 ~bufferedStream(); 366 virtual void write(const char* c, size_t len); 367 size_t size() { return buffer_pos; } 368 const char* base() { return buffer; } 369 void reset() { buffer_pos = 0; _precount = 0; _position = 0; } 370 char* as_string(); 371 }; 372 373 #define O_BUFLEN 2000 // max size of output of individual print() methods 374 375 #ifndef PRODUCT 376 377 class networkStream : public bufferedStream { 378 379 private: 380 int _socket; 381 382 public: 383 networkStream(); 384 ~networkStream(); 385 386 bool connect(const char *host, short port); 387 bool is_open() const { return _socket != -1; } 388 ssize_t read(char *buf, size_t len); 389 void close(); 390 virtual void flush(); 391 }; 392 393 #endif 394 395 #endif // SHARE_UTILITIES_OSTREAM_HPP