ostream.hpp 10.7 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30
#ifndef SHARE_VM_UTILITIES_OSTREAM_HPP
#define SHARE_VM_UTILITIES_OSTREAM_HPP

#include "memory/allocation.hpp"
#include "runtime/timer.hpp"

31
class GCId;
32 33
DEBUG_ONLY(class ResourceMark;)

D
duke 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
// Output streams for printing
//
// Printing guidelines:
// Where possible, please use tty->print() and tty->print_cr().
// For product mode VM warnings use warning() which internally uses tty.
// In places where tty is not initialized yet or too much overhead,
// we may use jio_printf:
//     jio_fprintf(defaultStream::output_stream(), "Message");
// This allows for redirection via -XX:+DisplayVMOutputToStdout and
// -XX:+DisplayVMOutputToStderr
class outputStream : public ResourceObj {
 protected:
   int _indentation; // current indentation
   int _width;       // width of the page
   int _position;    // position on the current line
   int _newlines;    // number of '\n' output so far
   julong _precount; // number of chars output, less _position
   TimeStamp _stamp; // for time stamps

   void update_position(const char* s, size_t len);
   static const char* do_vsnprintf(char* buffer, size_t buflen,
                                   const char* format, va_list ap,
                                   bool add_cr,
57
                                   size_t& result_len)  ATTRIBUTE_PRINTF(3, 0);
D
duke 已提交
58 59 60 61 62 63 64

 public:
   // creation
   outputStream(int width = 80);
   outputStream(int width, bool has_time_stamps);

   // indentation
65
   outputStream& indent();
D
duke 已提交
66 67
   void inc() { _indentation++; };
   void dec() { _indentation--; };
68 69
   void inc(int n) { _indentation += n; };
   void dec(int n) { _indentation -= n; };
D
duke 已提交
70 71 72
   int  indentation() const    { return _indentation; }
   void set_indentation(int i) { _indentation = i;    }
   void fill_to(int col);
73
   void move_to(int col, int slop = 6, int min_space = 2);
D
duke 已提交
74 75 76 77 78 79 80 81 82 83

   // sizing
   int width()    const { return _width;    }
   int position() const { return _position; }
   int newlines() const { return _newlines; }
   julong count() const { return _precount + _position; }
   void set_count(julong count) { _precount = count - _position; }
   void set_position(int pos)   { _position = pos; }

   // printing
84 85 86 87
   void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
   void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
   void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
   void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
D
duke 已提交
88 89 90 91
   void print_raw(const char* str)            { write(str, strlen(str)); }
   void print_raw(const char* str, int len)   { write(str,         len); }
   void print_raw_cr(const char* str)         { write(str, strlen(str)); cr(); }
   void print_raw_cr(const char* str, int len){ write(str,         len); cr(); }
92
   void print_data(void* data, size_t len, bool with_ascii);
D
duke 已提交
93
   void put(char ch);
94
   void sp(int count = 1);
D
duke 已提交
95 96 97 98 99 100
   void cr();
   void bol() { if (_position > 0)  cr(); }

   // Time stamp
   TimeStamp& time_stamp() { return _stamp; }
   void stamp();
101 102 103 104
   void stamp(bool guard, const char* prefix, const char* suffix);
   void stamp(bool guard) {
     stamp(guard, "", ": ");
   }
D
duke 已提交
105 106 107 108 109 110
   // Date stamp
   void date_stamp(bool guard, const char* prefix, const char* suffix);
   // A simplified call that includes a suffix of ": "
   void date_stamp(bool guard) {
     date_stamp(guard, "", ": ");
   }
111
   void gclog_stamp(const GCId& gc_id);
D
duke 已提交
112 113 114 115 116 117 118 119

   // portable printing of 64 bit integers
   void print_jlong(jlong value);
   void print_julong(julong value);

   // flushing
   virtual void flush() {}
   virtual void write(const char* str, size_t len) = 0;
120
   virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation
121
   virtual ~outputStream() {}   // close properly on deletion
D
duke 已提交
122 123 124 125 126 127

   void dec_cr() { dec(); cr(); }
   void inc_cr() { inc(); cr(); }
};

// standard output
128
// ANSI C++ name collision
D
duke 已提交
129 130 131
extern outputStream* tty;           // tty output
extern outputStream* gclog_or_tty;  // stream for gc log if -Xloggc:<f>, or tty

132 133 134 135 136 137 138 139 140 141 142 143 144
class streamIndentor : public StackObj {
 private:
  outputStream* _str;
  int _amount;

 public:
  streamIndentor(outputStream* str, int amt = 2) : _str(str), _amount(amt) {
    _str->inc(_amount);
  }
  ~streamIndentor() { _str->dec(_amount); }
};


D
duke 已提交
145 146
// advisory locking for the shared tty stream:
class ttyLocker: StackObj {
147
  friend class ttyUnlocker;
D
duke 已提交
148 149 150 151 152 153
 private:
  intx _holder;

 public:
  static intx  hold_tty();                // returns a "holder" token
  static void  release_tty(intx holder);  // must witness same token
154
  static bool  release_tty_if_locked();   // returns true if lock was released
D
duke 已提交
155 156 157 158 159 160
  static void  break_tty_lock_for_safepoint(intx holder);

  ttyLocker()  { _holder = hold_tty(); }
  ~ttyLocker() { release_tty(_holder); }
};

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
// Release the tty lock if it's held and reacquire it if it was
// locked.  Used to avoid lock ordering problems.
class ttyUnlocker: StackObj {
 private:
  bool _was_locked;
 public:
  ttyUnlocker()  {
    _was_locked = ttyLocker::release_tty_if_locked();
  }
  ~ttyUnlocker() {
    if (_was_locked) {
      ttyLocker::hold_tty();
    }
  }
};

D
duke 已提交
177 178 179 180 181 182 183
// for writing to strings; buffer will expand automatically
class stringStream : public outputStream {
 protected:
  char*  buffer;
  size_t buffer_pos;
  size_t buffer_length;
  bool   buffer_fixed;
184
  DEBUG_ONLY(ResourceMark* rm;)
D
duke 已提交
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
 public:
  stringStream(size_t initial_bufsize = 256);
  stringStream(char* fixed_buffer, size_t fixed_buffer_size);
  ~stringStream();
  virtual void write(const char* c, size_t len);
  size_t      size() { return buffer_pos; }
  const char* base() { return buffer; }
  void  reset() { buffer_pos = 0; _precount = 0; _position = 0; }
  char* as_string();
};

class fileStream : public outputStream {
 protected:
  FILE* _file;
  bool  _need_close;
 public:
201
  fileStream() { _file = NULL; _need_close = false; }
D
duke 已提交
202
  fileStream(const char* file_name);
203
  fileStream(const char* file_name, const char* opentype);
204
  fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; }
D
duke 已提交
205 206
  ~fileStream();
  bool is_open() const { return _file != NULL; }
207
  void set_need_close(bool b) { _need_close = b;}
D
duke 已提交
208
  virtual void write(const char* c, size_t len);
209 210 211 212 213
  size_t read(void *data, size_t size, size_t count) { return ::fread(data, size, count, _file); }
  char* readln(char *data, int count);
  int eof() { return feof(_file); }
  long fileSize();
  void rewind() { ::rewind(_file); }
D
duke 已提交
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
  void flush();
};

// unlike fileStream, fdStream does unbuffered I/O by calling
// open() and write() directly. It is async-safe, but output
// from multiple thread may be mixed together. Used by fatal
// error handler.
class fdStream : public outputStream {
 protected:
  int  _fd;
  bool _need_close;
 public:
  fdStream(const char* file_name);
  fdStream(int fd = -1) { _fd = fd; _need_close = false; }
  ~fdStream();
  bool is_open() const { return _fd != -1; }
  void set_fd(int fd) { _fd = fd; _need_close = false; }
  int fd() const { return _fd; }
  virtual void write(const char* c, size_t len);
  void flush() {};
};

236
class gcLogFileStream : public fileStream {
237
 protected:
238
  const char*  _file_name;
239
  jlong  _bytes_written;
240
  uintx  _cur_file_num;             // current logfile rotation number, from 0 to NumberOfGCLogFiles-1
241
 public:
242 243
  gcLogFileStream(const char* file_name);
  ~gcLogFileStream();
244
  virtual void write(const char* c, size_t len);
245
  virtual void rotate_log(bool force, outputStream* out = NULL);
246
  void dump_loggc_header();
247 248 249 250 251 252 253

  /* If "force" sets true, force log file rotation from outside JVM */
  bool should_rotate(bool force) {
    return force ||
             ((GCLogFileSize != 0) && ((uintx)_bytes_written >= GCLogFileSize));
  }

254 255
};

256 257 258 259 260
#ifndef PRODUCT
// unit test for checking -Xloggc:<filename> parsing result
void test_loggc_filename();
#endif

D
duke 已提交
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
void ostream_init();
void ostream_init_log();
void ostream_exit();
void ostream_abort();

// staticBufferStream uses a user-supplied buffer for all formatting.
// Used for safe formatting during fatal error handling.  Not MT safe.
// Do not share the stream between multiple threads.
class staticBufferStream : public outputStream {
 private:
  char* _buffer;
  size_t _buflen;
  outputStream* _outer_stream;
 public:
  staticBufferStream(char* buffer, size_t buflen,
                     outputStream *outer_stream);
  ~staticBufferStream() {};
  virtual void write(const char* c, size_t len);
  void flush();
280 281 282 283
  void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
  void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
  void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
  void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
D
duke 已提交
284 285 286 287 288 289 290 291
};

// In the non-fixed buffer case an underlying buffer will be created and
// managed in C heap. Not MT-safe.
class bufferedStream : public outputStream {
 protected:
  char*  buffer;
  size_t buffer_pos;
292
  size_t buffer_max;
D
duke 已提交
293 294 295
  size_t buffer_length;
  bool   buffer_fixed;
 public:
296 297
  bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10);
  bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax = 1024*1024*10);
D
duke 已提交
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
  ~bufferedStream();
  virtual void write(const char* c, size_t len);
  size_t      size() { return buffer_pos; }
  const char* base() { return buffer; }
  void  reset() { buffer_pos = 0; _precount = 0; _position = 0; }
  char* as_string();
};

#define O_BUFLEN 2000   // max size of output of individual print() methods

#ifndef PRODUCT

class networkStream : public bufferedStream {

  private:
    int _socket;

  public:
    networkStream();
    ~networkStream();

    bool connect(const char *host, short port);
    bool is_open() const { return _socket != -1; }
    int read(char *buf, size_t len);
    void close();
    virtual void flush();
};

#endif
327 328

#endif // SHARE_VM_UTILITIES_OSTREAM_HPP