ostream.cpp revision 4030:203f64878aab
12061Sjkh/*
23029Srgrimes * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
32061Sjkh * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
42061Sjkh *
52061Sjkh * This code is free software; you can redistribute it and/or modify it
62061Sjkh * under the terms of the GNU General Public License version 2 only, as
72061Sjkh * published by the Free Software Foundation.
82061Sjkh *
92160Scsgr * This code is distributed in the hope that it will be useful, but WITHOUT
102160Scsgr * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
112834Swollman * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
122061Sjkh * version 2 for more details (a copy is included in the LICENSE file that
132061Sjkh * accompanied this code).
142160Scsgr *
152626Scsgr * You should have received a copy of the GNU General Public License version
162061Sjkh * 2 along with this work; if not, write to the Free Software Foundation,
172160Scsgr * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
181594Srgrimes *
192061Sjkh * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202160Scsgr * or visit www.oracle.com if you need additional information or have any
212061Sjkh * questions.
221594Srgrimes *
232061Sjkh */
242061Sjkh
252061Sjkh#include "precompiled.hpp"
262061Sjkh#include "compiler/compileLog.hpp"
272061Sjkh#include "oops/oop.inline.hpp"
282061Sjkh#include "runtime/arguments.hpp"
292061Sjkh#include "utilities/defaultStream.hpp"
303029Srgrimes#include "utilities/ostream.hpp"
313029Srgrimes#include "utilities/top.hpp"
322061Sjkh#include "utilities/xmlstream.hpp"
332061Sjkh#ifdef TARGET_OS_FAMILY_linux
342061Sjkh# include "os_linux.inline.hpp"
352061Sjkh#endif
362061Sjkh#ifdef TARGET_OS_FAMILY_solaris
372061Sjkh# include "os_solaris.inline.hpp"
382061Sjkh#endif
392061Sjkh#ifdef TARGET_OS_FAMILY_windows
402061Sjkh# include "os_windows.inline.hpp"
412061Sjkh#endif
422061Sjkh#ifdef TARGET_OS_FAMILY_bsd
432061Sjkh# include "os_bsd.inline.hpp"
442061Sjkh#endif
452160Scsgr
462061Sjkhextern "C" void jio_print(const char* s); // Declarationtion of jvm method
472061Sjkh
482626ScsgroutputStream::outputStream(int width) {
492626Scsgr  _width       = width;
502626Scsgr  _position    = 0;
512626Scsgr  _newlines    = 0;
522061Sjkh  _precount    = 0;
532061Sjkh  _indentation = 0;
542061Sjkh}
552061Sjkh
562061SjkhoutputStream::outputStream(int width, bool has_time_stamps) {
572061Sjkh  _width       = width;
582061Sjkh  _position    = 0;
592061Sjkh  _newlines    = 0;
602061Sjkh  _precount    = 0;
612061Sjkh  _indentation = 0;
622061Sjkh  if (has_time_stamps)  _stamp.update();
632061Sjkh}
642061Sjkh
652061Sjkhvoid outputStream::update_position(const char* s, size_t len) {
662061Sjkh  for (size_t i = 0; i < len; i++) {
672061Sjkh    char ch = s[i];
682061Sjkh    if (ch == '\n') {
692061Sjkh      _newlines += 1;
702834Swollman      _precount += _position + 1;
712834Swollman      _position = 0;
722834Swollman    } else if (ch == '\t') {
732834Swollman      int tw = 8 - (_position & 7);
742834Swollman      _position += tw;
752834Swollman      _precount -= tw-1;  // invariant:  _precount + _position == total count
761594Srgrimes    } else {
772061Sjkh      _position += 1;
782061Sjkh    }
792061Sjkh  }
802061Sjkh}
812061Sjkh
822061Sjkh// Execute a vsprintf, using the given buffer if necessary.
832061Sjkh// Return a pointer to the formatted string.
842061Sjkhconst char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
852061Sjkh                                       const char* format, va_list ap,
862061Sjkh                                       bool add_cr,
872061Sjkh                                       size_t& result_len) {
882061Sjkh  const char* result;
892061Sjkh  if (add_cr)  buflen--;
902061Sjkh  if (!strchr(format, '%')) {
912061Sjkh    // constant format string
922061Sjkh    result = format;
932061Sjkh    result_len = strlen(result);
942061Sjkh    if (add_cr && result_len >= buflen)  result_len = buflen-1;  // truncate
952061Sjkh  } else if (format[0] == '%' && format[1] == 's' && format[2] == '\0') {
962061Sjkh    // trivial copy-through format string
972061Sjkh    result = va_arg(ap, const char*);
983029Srgrimes    result_len = strlen(result);
992061Sjkh    if (add_cr && result_len >= buflen)  result_len = buflen-1;  // truncate
1002061Sjkh  } else if (vsnprintf(buffer, buflen, format, ap) >= 0) {
1012061Sjkh    result = buffer;
1022061Sjkh    result_len = strlen(result);
1032061Sjkh  } else {
1042061Sjkh    DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
1052061Sjkh    result = buffer;
1062302Spaul    result_len = buflen - 1;
1073029Srgrimes    buffer[result_len] = 0;
1082061Sjkh  }
1093029Srgrimes  if (add_cr) {
1102061Sjkh    if (result != buffer) {
1113029Srgrimes      strncpy(buffer, result, buflen);
1122061Sjkh      result = buffer;
1132302Spaul    }
1142302Spaul    buffer[result_len++] = '\n';
1152302Spaul    buffer[result_len] = 0;
1162302Spaul  }
1172302Spaul  return result;
1182302Spaul}
1192302Spaul
1202302Spaulvoid outputStream::print(const char* format, ...) {
1212302Spaul  char buffer[O_BUFLEN];
1222302Spaul  va_list ap;
1232302Spaul  va_start(ap, format);
1242302Spaul  size_t len;
1252302Spaul  const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len);
1262302Spaul  write(str, len);
1272061Sjkh  va_end(ap);
1282061Sjkh}
1292061Sjkh
1302061Sjkhvoid outputStream::print_cr(const char* format, ...) {
1312061Sjkh  char buffer[O_BUFLEN];
1322061Sjkh  va_list ap;
1332061Sjkh  va_start(ap, format);
1342061Sjkh  size_t len;
1352061Sjkh  const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, true, len);
1362061Sjkh  write(str, len);
1372061Sjkh  va_end(ap);
1382061Sjkh}
1392061Sjkh
1402061Sjkhvoid outputStream::vprint(const char *format, va_list argptr) {
1412061Sjkh  char buffer[O_BUFLEN];
1422061Sjkh  size_t len;
1432061Sjkh  const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, false, len);
1442061Sjkh  write(str, len);
1452061Sjkh}
1462061Sjkh
1472061Sjkhvoid outputStream::vprint_cr(const char* format, va_list argptr) {
1482061Sjkh  char buffer[O_BUFLEN];
1492061Sjkh  size_t len;
1502061Sjkh  const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, true, len);
1512061Sjkh  write(str, len);
1522061Sjkh}
1532061Sjkh
1542061Sjkhvoid outputStream::fill_to(int col) {
1552061Sjkh  int need_fill = col - position();
1562061Sjkh  sp(need_fill);
1572061Sjkh}
1582061Sjkh
1592061Sjkhvoid outputStream::move_to(int col, int slop, int min_space) {
1602061Sjkh  if (position() >= col + slop)
1612061Sjkh    cr();
1622061Sjkh  int need_fill = col - position();
1632061Sjkh  if (need_fill < min_space)
1642061Sjkh    need_fill = min_space;
1652061Sjkh  sp(need_fill);
1662061Sjkh}
1672061Sjkh
1682061Sjkhvoid outputStream::put(char ch) {
1692061Sjkh  assert(ch != 0, "please fix call site");
1702061Sjkh  char buf[] = { ch, '\0' };
1712685Srgrimes  write(buf, 1);
1722685Srgrimes}
1732626Scsgr
1742061Sjkh#define SP_USE_TABS false
1752061Sjkh
1762061Sjkhvoid outputStream::sp(int count) {
1772061Sjkh  if (count < 0)  return;
1782061Sjkh  if (SP_USE_TABS && count >= 8) {
1792883Sphk    int target = position() + count;
1802061Sjkh    while (count >= 8) {
1812626Scsgr      this->write("\t", 1);
1822626Scsgr      count -= 8;
1832626Scsgr    }
1842626Scsgr    count = target - position();
1852061Sjkh  }
1862061Sjkh  while (count > 0) {
1872061Sjkh    int nw = (count > 8) ? 8 : count;
1882061Sjkh    this->write("        ", nw);
1892061Sjkh    count -= nw;
1902061Sjkh  }
1912061Sjkh}
1922061Sjkh
1932061Sjkhvoid outputStream::cr() {
1942061Sjkh  this->write("\n", 1);
1952468Spaul}
1962061Sjkh
1972273Spaulvoid outputStream::stamp() {
1982061Sjkh  if (! _stamp.is_updated()) {
1992160Scsgr    _stamp.update(); // start at 0 on first call to stamp()
2002160Scsgr  }
2012160Scsgr
2022160Scsgr  // outputStream::stamp() may get called by ostream_abort(), use snprintf
2032279Spaul  // to avoid allocating large stack buffer in print().
2042061Sjkh  char buf[40];
2052061Sjkh  jio_snprintf(buf, sizeof(buf), "%.3f", _stamp.seconds());
2062279Spaul  print_raw(buf);
2072468Spaul}
2082468Spaul
2092626Scsgrvoid outputStream::stamp(bool guard,
2102061Sjkh                         const char* prefix,
2112061Sjkh                         const char* suffix) {
2122061Sjkh  if (!guard) {
2132061Sjkh    return;
2142061Sjkh  }
2152061Sjkh  print_raw(prefix);
2162061Sjkh  stamp();
2172061Sjkh  print_raw(suffix);
2182061Sjkh}
2192626Scsgr
2202626Scsgrvoid outputStream::date_stamp(bool guard,
2212626Scsgr                              const char* prefix,
2222626Scsgr                              const char* suffix) {
2232626Scsgr  if (!guard) {
2242626Scsgr    return;
2252626Scsgr  }
2262626Scsgr  print_raw(prefix);
2272626Scsgr  static const char error_time[] = "yyyy-mm-ddThh:mm:ss.mmm+zzzz";
2282626Scsgr  static const int buffer_length = 32;
2292626Scsgr  char buffer[buffer_length];
2302061Sjkh  const char* iso8601_result = os::iso8601_time(buffer, buffer_length);
2312061Sjkh  if (iso8601_result != NULL) {
2322061Sjkh    print_raw(buffer);
2332061Sjkh  } else {
2342061Sjkh    print_raw(error_time);
2352061Sjkh  }
2362273Spaul  print_raw(suffix);
2372061Sjkh  return;
2382061Sjkh}
2392061Sjkh
2402061SjkhoutputStream& outputStream::indent() {
2411594Srgrimes  while (_position < _indentation) sp();
242  return *this;
243}
244
245void outputStream::print_jlong(jlong value) {
246  print(JLONG_FORMAT, value);
247}
248
249void outputStream::print_julong(julong value) {
250  print(JULONG_FORMAT, value);
251}
252
253/**
254 * This prints out hex data in a 'windbg' or 'xxd' form, where each line is:
255 *   <hex-address>: 8 * <hex-halfword> <ascii translation (optional)>
256 * example:
257 * 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000  .DOF............
258 * 0000010: 0000 0000 0000 0040 0000 0020 0000 0005  .......@... ....
259 * 0000020: 0000 0000 0000 0040 0000 0000 0000 015d  .......@.......]
260 * ...
261 *
262 * indent is applied to each line.  Ends with a CR.
263 */
264void outputStream::print_data(void* data, size_t len, bool with_ascii) {
265  size_t limit = (len + 16) / 16 * 16;
266  for (size_t i = 0; i < limit; ++i) {
267    if (i % 16 == 0) {
268      indent().print("%07x:", i);
269    }
270    if (i % 2 == 0) {
271      print(" ");
272    }
273    if (i < len) {
274      print("%02x", ((unsigned char*)data)[i]);
275    } else {
276      print("  ");
277    }
278    if ((i + 1) % 16 == 0) {
279      if (with_ascii) {
280        print("  ");
281        for (size_t j = 0; j < 16; ++j) {
282          size_t idx = i + j - 15;
283          if (idx < len) {
284            char c = ((char*)data)[idx];
285            print("%c", c >= 32 && c <= 126 ? c : '.');
286          }
287        }
288      }
289      print_cr("");
290    }
291  }
292}
293
294stringStream::stringStream(size_t initial_size) : outputStream() {
295  buffer_length = initial_size;
296  buffer        = NEW_RESOURCE_ARRAY(char, buffer_length);
297  buffer_pos    = 0;
298  buffer_fixed  = false;
299}
300
301// useful for output to fixed chunks of memory, such as performance counters
302stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() {
303  buffer_length = fixed_buffer_size;
304  buffer        = fixed_buffer;
305  buffer_pos    = 0;
306  buffer_fixed  = true;
307}
308
309void stringStream::write(const char* s, size_t len) {
310  size_t write_len = len;               // number of non-null bytes to write
311  size_t end = buffer_pos + len + 1;    // position after write and final '\0'
312  if (end > buffer_length) {
313    if (buffer_fixed) {
314      // if buffer cannot resize, silently truncate
315      end = buffer_length;
316      write_len = end - buffer_pos - 1; // leave room for the final '\0'
317    } else {
318      // For small overruns, double the buffer.  For larger ones,
319      // increase to the requested size.
320      if (end < buffer_length * 2) {
321        end = buffer_length * 2;
322      }
323      char* oldbuf = buffer;
324      buffer = NEW_RESOURCE_ARRAY(char, end);
325      strncpy(buffer, oldbuf, buffer_pos);
326      buffer_length = end;
327    }
328  }
329  // invariant: buffer is always null-terminated
330  guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob");
331  buffer[buffer_pos + write_len] = 0;
332  strncpy(buffer + buffer_pos, s, write_len);
333  buffer_pos += write_len;
334
335  // Note that the following does not depend on write_len.
336  // This means that position and count get updated
337  // even when overflow occurs.
338  update_position(s, len);
339}
340
341char* stringStream::as_string() {
342  char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
343  strncpy(copy, buffer, buffer_pos);
344  copy[buffer_pos] = 0;  // terminating null
345  return copy;
346}
347
348stringStream::~stringStream() {}
349
350xmlStream*   xtty;
351outputStream* tty;
352outputStream* gclog_or_tty;
353extern Mutex* tty_lock;
354
355fileStream::fileStream(const char* file_name) {
356  _file = fopen(file_name, "w");
357  _need_close = true;
358}
359
360fileStream::fileStream(const char* file_name, const char* opentype) {
361  _file = fopen(file_name, opentype);
362  _need_close = true;
363}
364
365void fileStream::write(const char* s, size_t len) {
366  if (_file != NULL)  {
367    // Make an unused local variable to avoid warning from gcc 4.x compiler.
368    size_t count = fwrite(s, 1, len, _file);
369  }
370  update_position(s, len);
371}
372
373long fileStream::fileSize() {
374  long size = -1;
375  if (_file != NULL) {
376    long pos  = ::ftell(_file);
377    if (::fseek(_file, 0, SEEK_END) == 0) {
378      size = ::ftell(_file);
379    }
380    ::fseek(_file, pos, SEEK_SET);
381  }
382  return size;
383}
384
385char* fileStream::readln(char *data, int count ) {
386  char * ret = ::fgets(data, count, _file);
387  //Get rid of annoying \n char
388  data[::strlen(data)-1] = '\0';
389  return ret;
390}
391
392fileStream::~fileStream() {
393  if (_file != NULL) {
394    if (_need_close) fclose(_file);
395    _file      = NULL;
396  }
397}
398
399void fileStream::flush() {
400  fflush(_file);
401}
402
403fdStream::fdStream(const char* file_name) {
404  _fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
405  _need_close = true;
406}
407
408fdStream::~fdStream() {
409  if (_fd != -1) {
410    if (_need_close) close(_fd);
411    _fd = -1;
412  }
413}
414
415void fdStream::write(const char* s, size_t len) {
416  if (_fd != -1) {
417    // Make an unused local variable to avoid warning from gcc 4.x compiler.
418    size_t count = ::write(_fd, s, (int)len);
419  }
420  update_position(s, len);
421}
422
423rotatingFileStream::~rotatingFileStream() {
424  if (_file != NULL) {
425    if (_need_close) fclose(_file);
426    _file      = NULL;
427    FREE_C_HEAP_ARRAY(char, _file_name, mtInternal);
428    _file_name = NULL;
429  }
430}
431
432rotatingFileStream::rotatingFileStream(const char* file_name) {
433  _cur_file_num = 0;
434  _bytes_writen = 0L;
435  _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
436  jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
437  _file = fopen(_file_name, "w");
438  _need_close = true;
439}
440
441rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) {
442  _cur_file_num = 0;
443  _bytes_writen = 0L;
444  _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
445  jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
446  _file = fopen(_file_name, opentype);
447  _need_close = true;
448}
449
450void rotatingFileStream::write(const char* s, size_t len) {
451  if (_file != NULL)  {
452    // Make an unused local variable to avoid warning from gcc 4.x compiler.
453    size_t count = fwrite(s, 1, len, _file);
454    Atomic::add((jlong)count, &_bytes_writen);
455  }
456  update_position(s, len);
457}
458
459// rotate_log must be called from VMThread at safepoint. In case need change parameters
460// for gc log rotation from thread other than VMThread, a sub type of VM_Operation
461// should be created and be submitted to VMThread's operation queue. DO NOT call this
462// function directly. Currently, it is safe to rotate log at safepoint through VMThread.
463// That is, no mutator threads and concurrent GC threads run parallel with VMThread to
464// write to gc log file at safepoint. If in future, changes made for mutator threads or
465// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
466// must be synchronized.
467void rotatingFileStream::rotate_log() {
468  if (_bytes_writen < (jlong)GCLogFileSize) return;
469#ifdef ASSERT
470  Thread *thread = Thread::current();
471  assert(thread == NULL ||
472         (thread->is_VM_thread() && SafepointSynchronize::is_at_safepoint()),
473         "Must be VMThread at safepoint");
474#endif
475  if (NumberOfGCLogFiles == 1) {
476    // rotate in same file
477    rewind();
478    _bytes_writen = 0L;
479    return;
480  }
481
482  // rotate file in names file.0, file.1, file.2, ..., file.<MaxGCLogFileNumbers-1>
483  // close current file, rotate to next file
484  if (_file != NULL) {
485    _cur_file_num ++;
486    if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0;
487    jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d",
488             Arguments::gc_log_filename(), _cur_file_num);
489    fclose(_file);
490    _file = NULL;
491  }
492  _file = fopen(_file_name, "w");
493  if (_file != NULL) {
494    _bytes_writen = 0L;
495    _need_close = true;
496  } else {
497    tty->print_cr("failed to open rotation log file %s due to %s\n",
498                  _file_name, strerror(errno));
499    _need_close = false;
500  }
501}
502
503defaultStream* defaultStream::instance = NULL;
504int defaultStream::_output_fd = 1;
505int defaultStream::_error_fd  = 2;
506FILE* defaultStream::_output_stream = stdout;
507FILE* defaultStream::_error_stream  = stderr;
508
509#define LOG_MAJOR_VERSION 160
510#define LOG_MINOR_VERSION 1
511
512void defaultStream::init() {
513  _inited = true;
514  if (LogVMOutput || LogCompilation) {
515    init_log();
516  }
517}
518
519bool defaultStream::has_log_file() {
520  // lazily create log file (at startup, LogVMOutput is false even
521  // if +LogVMOutput is used, because the flags haven't been parsed yet)
522  // For safer printing during fatal error handling, do not init logfile
523  // if a VM error has been reported.
524  if (!_inited && !is_error_reported())  init();
525  return _log_file != NULL;
526}
527
528static const char* make_log_name(const char* log_name, const char* force_directory) {
529  const char* basename = log_name;
530  char file_sep = os::file_separator()[0];
531  const char* cp;
532  for (cp = log_name; *cp != '\0'; cp++) {
533    if (*cp == '/' || *cp == file_sep) {
534      basename = cp+1;
535    }
536  }
537  const char* nametail = log_name;
538
539  // Compute buffer length
540  size_t buffer_length;
541  if (force_directory != NULL) {
542    buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
543                    strlen(basename) + 1;
544  } else {
545    buffer_length = strlen(log_name) + 1;
546  }
547
548  const char* star = strchr(basename, '*');
549  int star_pos = (star == NULL) ? -1 : (star - nametail);
550  int skip = 1;
551  if (star == NULL) {
552    // Try %p
553    star = strstr(basename, "%p");
554    if (star != NULL) {
555      skip = 2;
556    }
557  }
558  star_pos = (star == NULL) ? -1 : (star - nametail);
559
560  char pid[32];
561  if (star_pos >= 0) {
562    jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id());
563    buffer_length += strlen(pid);
564  }
565
566  // Create big enough buffer.
567  char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
568
569  strcpy(buf, "");
570  if (force_directory != NULL) {
571    strcat(buf, force_directory);
572    strcat(buf, os::file_separator());
573    nametail = basename;       // completely skip directory prefix
574  }
575
576  if (star_pos >= 0) {
577    // convert foo*bar.log or foo%pbar.log to foo123bar.log
578    int buf_pos = (int) strlen(buf);
579    strncpy(&buf[buf_pos], nametail, star_pos);
580    strcpy(&buf[buf_pos + star_pos], pid);
581    nametail += star_pos + skip;  // skip prefix and pid format
582  }
583
584  strcat(buf, nametail);      // append rest of name, or all of name
585  return buf;
586}
587
588void defaultStream::init_log() {
589  // %%% Need a MutexLocker?
590  const char* log_name = LogFile != NULL ? LogFile : "hotspot.log";
591  const char* try_name = make_log_name(log_name, NULL);
592  fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
593  if (!file->is_open()) {
594    // Try again to open the file.
595    char warnbuf[O_BUFLEN*2];
596    jio_snprintf(warnbuf, sizeof(warnbuf),
597                 "Warning:  Cannot open log file: %s\n", try_name);
598    // Note:  This feature is for maintainer use only.  No need for L10N.
599    jio_print(warnbuf);
600    FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
601    try_name = make_log_name("hs_pid%p.log", os::get_temp_directory());
602    jio_snprintf(warnbuf, sizeof(warnbuf),
603                 "Warning:  Forcing option -XX:LogFile=%s\n", try_name);
604    jio_print(warnbuf);
605    delete file;
606    file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
607    FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
608  }
609  if (file->is_open()) {
610    _log_file = file;
611    xmlStream* xs = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file);
612    _outer_xmlStream = xs;
613    if (this == tty)  xtty = xs;
614    // Write XML header.
615    xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>");
616    // (For now, don't bother to issue a DTD for this private format.)
617    jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds();
618    // %%% Should be: jlong time_ms = os::start_time_milliseconds(), if
619    // we ever get round to introduce that method on the os class
620    xs->head("hotspot_log version='%d %d'"
621             " process='%d' time_ms='"INT64_FORMAT"'",
622             LOG_MAJOR_VERSION, LOG_MINOR_VERSION,
623             os::current_process_id(), time_ms);
624    // Write VM version header immediately.
625    xs->head("vm_version");
626    xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr();
627    xs->tail("name");
628    xs->head("release"); xs->text("%s", VM_Version::vm_release()); xs->cr();
629    xs->tail("release");
630    xs->head("info"); xs->text("%s", VM_Version::internal_vm_info_string()); xs->cr();
631    xs->tail("info");
632    xs->tail("vm_version");
633    // Record information about the command-line invocation.
634    xs->head("vm_arguments");  // Cf. Arguments::print_on()
635    if (Arguments::num_jvm_flags() > 0) {
636      xs->head("flags");
637      Arguments::print_jvm_flags_on(xs->text());
638      xs->tail("flags");
639    }
640    if (Arguments::num_jvm_args() > 0) {
641      xs->head("args");
642      Arguments::print_jvm_args_on(xs->text());
643      xs->tail("args");
644    }
645    if (Arguments::java_command() != NULL) {
646      xs->head("command"); xs->text()->print_cr("%s", Arguments::java_command());
647      xs->tail("command");
648    }
649    if (Arguments::sun_java_launcher() != NULL) {
650      xs->head("launcher"); xs->text()->print_cr("%s", Arguments::sun_java_launcher());
651      xs->tail("launcher");
652    }
653    if (Arguments::system_properties() !=  NULL) {
654      xs->head("properties");
655      // Print it as a java-style property list.
656      // System properties don't generally contain newlines, so don't bother with unparsing.
657      for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
658        xs->text()->print_cr("%s=%s", p->key(), p->value());
659      }
660      xs->tail("properties");
661    }
662    xs->tail("vm_arguments");
663    // tty output per se is grouped under the <tty>...</tty> element.
664    xs->head("tty");
665    // All further non-markup text gets copied to the tty:
666    xs->_text = this;  // requires friend declaration!
667  } else {
668    delete(file);
669    // and leave xtty as NULL
670    LogVMOutput = false;
671    DisplayVMOutput = true;
672    LogCompilation = false;
673  }
674}
675
676// finish_log() is called during normal VM shutdown. finish_log_on_error() is
677// called by ostream_abort() after a fatal error.
678//
679void defaultStream::finish_log() {
680  xmlStream* xs = _outer_xmlStream;
681  xs->done("tty");
682
683  // Other log forks are appended here, at the End of Time:
684  CompileLog::finish_log(xs->out());  // write compile logging, if any, now
685
686  xs->done("hotspot_log");
687  xs->flush();
688
689  fileStream* file = _log_file;
690  _log_file = NULL;
691
692  delete _outer_xmlStream;
693  _outer_xmlStream = NULL;
694
695  file->flush();
696  delete file;
697}
698
699void defaultStream::finish_log_on_error(char *buf, int buflen) {
700  xmlStream* xs = _outer_xmlStream;
701
702  if (xs && xs->out()) {
703
704    xs->done_raw("tty");
705
706    // Other log forks are appended here, at the End of Time:
707    CompileLog::finish_log_on_error(xs->out(), buf, buflen);  // write compile logging, if any, now
708
709    xs->done_raw("hotspot_log");
710    xs->flush();
711
712    fileStream* file = _log_file;
713    _log_file = NULL;
714    _outer_xmlStream = NULL;
715
716    if (file) {
717      file->flush();
718
719      // Can't delete or close the file because delete and fclose aren't
720      // async-safe. We are about to die, so leave it to the kernel.
721      // delete file;
722    }
723  }
724}
725
726intx defaultStream::hold(intx writer_id) {
727  bool has_log = has_log_file();  // check before locking
728  if (// impossible, but who knows?
729      writer_id == NO_WRITER ||
730
731      // bootstrap problem
732      tty_lock == NULL ||
733
734      // can't grab a lock or call Thread::current() if TLS isn't initialized
735      ThreadLocalStorage::thread() == NULL ||
736
737      // developer hook
738      !SerializeVMOutput ||
739
740      // VM already unhealthy
741      is_error_reported() ||
742
743      // safepoint == global lock (for VM only)
744      (SafepointSynchronize::is_synchronizing() &&
745       Thread::current()->is_VM_thread())
746      ) {
747    // do not attempt to lock unless we know the thread and the VM is healthy
748    return NO_WRITER;
749  }
750  if (_writer == writer_id) {
751    // already held, no need to re-grab the lock
752    return NO_WRITER;
753  }
754  tty_lock->lock_without_safepoint_check();
755  // got the lock
756  if (writer_id != _last_writer) {
757    if (has_log) {
758      _log_file->bol();
759      // output a hint where this output is coming from:
760      _log_file->print_cr("<writer thread='" UINTX_FORMAT "'/>", writer_id);
761    }
762    _last_writer = writer_id;
763  }
764  _writer = writer_id;
765  return writer_id;
766}
767
768void defaultStream::release(intx holder) {
769  if (holder == NO_WRITER) {
770    // nothing to release:  either a recursive lock, or we scribbled (too bad)
771    return;
772  }
773  if (_writer != holder) {
774    return;  // already unlocked, perhaps via break_tty_lock_for_safepoint
775  }
776  _writer = NO_WRITER;
777  tty_lock->unlock();
778}
779
780
781// Yuck:  jio_print does not accept char*/len.
782static void call_jio_print(const char* s, size_t len) {
783  char buffer[O_BUFLEN+100];
784  if (len > sizeof(buffer)-1) {
785    warning("increase O_BUFLEN in ostream.cpp -- output truncated");
786    len = sizeof(buffer)-1;
787  }
788  strncpy(buffer, s, len);
789  buffer[len] = '\0';
790  jio_print(buffer);
791}
792
793
794void defaultStream::write(const char* s, size_t len) {
795  intx thread_id = os::current_thread_id();
796  intx holder = hold(thread_id);
797
798  if (DisplayVMOutput &&
799      (_outer_xmlStream == NULL || !_outer_xmlStream->inside_attrs())) {
800    // print to output stream. It can be redirected by a vfprintf hook
801    if (s[len] == '\0') {
802      jio_print(s);
803    } else {
804      call_jio_print(s, len);
805    }
806  }
807
808  // print to log file
809  if (has_log_file()) {
810    int nl0 = _newlines;
811    xmlTextStream::write(s, len);
812    // flush the log file too, if there were any newlines
813    if (nl0 != _newlines){
814      flush();
815    }
816  } else {
817    update_position(s, len);
818  }
819
820  release(holder);
821}
822
823intx ttyLocker::hold_tty() {
824  if (defaultStream::instance == NULL)  return defaultStream::NO_WRITER;
825  intx thread_id = os::current_thread_id();
826  return defaultStream::instance->hold(thread_id);
827}
828
829void ttyLocker::release_tty(intx holder) {
830  if (holder == defaultStream::NO_WRITER)  return;
831  defaultStream::instance->release(holder);
832}
833
834bool ttyLocker::release_tty_if_locked() {
835  intx thread_id = os::current_thread_id();
836  if (defaultStream::instance->writer() == thread_id) {
837    // release the lock and return true so callers know if was
838    // previously held.
839    release_tty(thread_id);
840    return true;
841  }
842  return false;
843}
844
845void ttyLocker::break_tty_lock_for_safepoint(intx holder) {
846  if (defaultStream::instance != NULL &&
847      defaultStream::instance->writer() == holder) {
848    if (xtty != NULL) {
849      xtty->print_cr("<!-- safepoint while printing -->");
850    }
851    defaultStream::instance->release(holder);
852  }
853  // (else there was no lock to break)
854}
855
856void ostream_init() {
857  if (defaultStream::instance == NULL) {
858    defaultStream::instance = new(ResourceObj::C_HEAP, mtInternal) defaultStream();
859    tty = defaultStream::instance;
860
861    // We want to ensure that time stamps in GC logs consider time 0
862    // the time when the JVM is initialized, not the first time we ask
863    // for a time stamp. So, here, we explicitly update the time stamp
864    // of tty.
865    tty->time_stamp().update_to(1);
866  }
867}
868
869void ostream_init_log() {
870  // For -Xloggc:<file> option - called in runtime/thread.cpp
871  // Note : this must be called AFTER ostream_init()
872
873  gclog_or_tty = tty; // default to tty
874  if (Arguments::gc_log_filename() != NULL) {
875    fileStream * gclog  = UseGCLogFileRotation ?
876                          new(ResourceObj::C_HEAP, mtInternal)
877                             rotatingFileStream(Arguments::gc_log_filename()) :
878                          new(ResourceObj::C_HEAP, mtInternal)
879                             fileStream(Arguments::gc_log_filename());
880    if (gclog->is_open()) {
881      // now we update the time stamp of the GC log to be synced up
882      // with tty.
883      gclog->time_stamp().update_to(tty->time_stamp().ticks());
884    }
885    gclog_or_tty = gclog;
886  }
887
888  // If we haven't lazily initialized the logfile yet, do it now,
889  // to avoid the possibility of lazy initialization during a VM
890  // crash, which can affect the stability of the fatal error handler.
891  defaultStream::instance->has_log_file();
892}
893
894// ostream_exit() is called during normal VM exit to finish log files, flush
895// output and free resource.
896void ostream_exit() {
897  static bool ostream_exit_called = false;
898  if (ostream_exit_called)  return;
899  ostream_exit_called = true;
900  if (gclog_or_tty != tty) {
901      delete gclog_or_tty;
902  }
903  {
904      // we temporaly disable PrintMallocFree here
905      // as otherwise it'll lead to using of almost deleted
906      // tty or defaultStream::instance in logging facility
907      // of HeapFree(), see 6391258
908      DEBUG_ONLY(FlagSetting fs(PrintMallocFree, false);)
909      if (tty != defaultStream::instance) {
910          delete tty;
911      }
912      if (defaultStream::instance != NULL) {
913          delete defaultStream::instance;
914      }
915  }
916  tty = NULL;
917  xtty = NULL;
918  gclog_or_tty = NULL;
919  defaultStream::instance = NULL;
920}
921
922// ostream_abort() is called by os::abort() when VM is about to die.
923void ostream_abort() {
924  // Here we can't delete gclog_or_tty and tty, just flush their output
925  if (gclog_or_tty) gclog_or_tty->flush();
926  if (tty) tty->flush();
927
928  if (defaultStream::instance != NULL) {
929    static char buf[4096];
930    defaultStream::instance->finish_log_on_error(buf, sizeof(buf));
931  }
932}
933
934staticBufferStream::staticBufferStream(char* buffer, size_t buflen,
935                                       outputStream *outer_stream) {
936  _buffer = buffer;
937  _buflen = buflen;
938  _outer_stream = outer_stream;
939  // compile task prints time stamp relative to VM start
940  _stamp.update_to(1);
941}
942
943void staticBufferStream::write(const char* c, size_t len) {
944  _outer_stream->print_raw(c, (int)len);
945}
946
947void staticBufferStream::flush() {
948  _outer_stream->flush();
949}
950
951void staticBufferStream::print(const char* format, ...) {
952  va_list ap;
953  va_start(ap, format);
954  size_t len;
955  const char* str = do_vsnprintf(_buffer, _buflen, format, ap, false, len);
956  write(str, len);
957  va_end(ap);
958}
959
960void staticBufferStream::print_cr(const char* format, ...) {
961  va_list ap;
962  va_start(ap, format);
963  size_t len;
964  const char* str = do_vsnprintf(_buffer, _buflen, format, ap, true, len);
965  write(str, len);
966  va_end(ap);
967}
968
969void staticBufferStream::vprint(const char *format, va_list argptr) {
970  size_t len;
971  const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, false, len);
972  write(str, len);
973}
974
975void staticBufferStream::vprint_cr(const char* format, va_list argptr) {
976  size_t len;
977  const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, true, len);
978  write(str, len);
979}
980
981bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
982  buffer_length = initial_size;
983  buffer        = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
984  buffer_pos    = 0;
985  buffer_fixed  = false;
986  buffer_max    = bufmax;
987}
988
989bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() {
990  buffer_length = fixed_buffer_size;
991  buffer        = fixed_buffer;
992  buffer_pos    = 0;
993  buffer_fixed  = true;
994  buffer_max    = bufmax;
995}
996
997void bufferedStream::write(const char* s, size_t len) {
998
999  if(buffer_pos + len > buffer_max) {
1000    flush();
1001  }
1002
1003  size_t end = buffer_pos + len;
1004  if (end >= buffer_length) {
1005    if (buffer_fixed) {
1006      // if buffer cannot resize, silently truncate
1007      len = buffer_length - buffer_pos - 1;
1008    } else {
1009      // For small overruns, double the buffer.  For larger ones,
1010      // increase to the requested size.
1011      if (end < buffer_length * 2) {
1012        end = buffer_length * 2;
1013      }
1014      buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal);
1015      buffer_length = end;
1016    }
1017  }
1018  memcpy(buffer + buffer_pos, s, len);
1019  buffer_pos += len;
1020  update_position(s, len);
1021}
1022
1023char* bufferedStream::as_string() {
1024  char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
1025  strncpy(copy, buffer, buffer_pos);
1026  copy[buffer_pos] = 0;  // terminating null
1027  return copy;
1028}
1029
1030bufferedStream::~bufferedStream() {
1031  if (!buffer_fixed) {
1032    FREE_C_HEAP_ARRAY(char, buffer, mtInternal);
1033  }
1034}
1035
1036#ifndef PRODUCT
1037
1038#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE)
1039#include <sys/types.h>
1040#include <sys/socket.h>
1041#include <netinet/in.h>
1042#include <arpa/inet.h>
1043#endif
1044
1045// Network access
1046networkStream::networkStream() : bufferedStream(1024*10, 1024*10) {
1047
1048  _socket = -1;
1049
1050  int result = os::socket(AF_INET, SOCK_STREAM, 0);
1051  if (result <= 0) {
1052    assert(false, "Socket could not be created!");
1053  } else {
1054    _socket = result;
1055  }
1056}
1057
1058int networkStream::read(char *buf, size_t len) {
1059  return os::recv(_socket, buf, (int)len, 0);
1060}
1061
1062void networkStream::flush() {
1063  if (size() != 0) {
1064    int result = os::raw_send(_socket, (char *)base(), size(), 0);
1065    assert(result != -1, "connection error");
1066    assert(result == (int)size(), "didn't send enough data");
1067  }
1068  reset();
1069}
1070
1071networkStream::~networkStream() {
1072  close();
1073}
1074
1075void networkStream::close() {
1076  if (_socket != -1) {
1077    flush();
1078    os::socket_close(_socket);
1079    _socket = -1;
1080  }
1081}
1082
1083bool networkStream::connect(const char *ip, short port) {
1084
1085  struct sockaddr_in server;
1086  server.sin_family = AF_INET;
1087  server.sin_port = htons(port);
1088
1089  server.sin_addr.s_addr = inet_addr(ip);
1090  if (server.sin_addr.s_addr == (uint32_t)-1) {
1091    struct hostent* host = os::get_host_by_name((char*)ip);
1092    if (host != NULL) {
1093      memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length);
1094    } else {
1095      return false;
1096    }
1097  }
1098
1099
1100  int result = os::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in));
1101  return (result >= 0);
1102}
1103
1104#endif
1105