Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

gc log code

By: a guest on Dec 12th, 2011  |  syntax: C++  |  size: 27.06 KB  |  views: 121  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*
  2.  * Copyright (c) 1997, 2010, 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. #include "precompiled.hpp"
  26. #include "compiler/compileLog.hpp"
  27. #include "oops/oop.inline.hpp"
  28. #include "runtime/arguments.hpp"
  29. #include "utilities/defaultStream.hpp"
  30. #include "utilities/ostream.hpp"
  31. #include "utilities/top.hpp"
  32. #include "utilities/xmlstream.hpp"
  33. #ifdef TARGET_OS_FAMILY_linux
  34. # include "os_linux.inline.hpp"
  35. #endif
  36. #ifdef TARGET_OS_FAMILY_solaris
  37. # include "os_solaris.inline.hpp"
  38. #endif
  39. #ifdef TARGET_OS_FAMILY_windows
  40. # include "os_windows.inline.hpp"
  41. #endif
  42.  
  43. extern "C" void jio_print(const char* s); // Declarationtion of jvm method
  44.  
  45. outputStream::outputStream(int width) {
  46.   _width       = width;
  47.   _position    = 0;
  48.   _newlines    = 0;
  49.   _precount    = 0;
  50.   _indentation = 0;
  51. }
  52.  
  53. outputStream::outputStream(int width, bool has_time_stamps) {
  54.   _width       = width;
  55.   _position    = 0;
  56.   _newlines    = 0;
  57.   _precount    = 0;
  58.   _indentation = 0;
  59.   if (has_time_stamps)  _stamp.update();
  60. }
  61.  
  62. void outputStream::update_position(const char* s, size_t len) {
  63.   for (size_t i = 0; i < len; i++) {
  64.     char ch = s[i];
  65.     if (ch == '\n') {
  66.       _newlines += 1;
  67.       _precount += _position + 1;
  68.       _position = 0;
  69.     } else if (ch == '\t') {
  70.       int tw = 8 - (_position & 7);
  71.       _position += tw;
  72.       _precount -= tw-1;  // invariant:  _precount + _position == total count
  73.     } else {
  74.       _position += 1;
  75.     }
  76.   }
  77. }
  78.  
  79. // Execute a vsprintf, using the given buffer if necessary.
  80. // Return a pointer to the formatted string.
  81. const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
  82.                                        const char* format, va_list ap,
  83.                                        bool add_cr,
  84.                                        size_t& result_len) {
  85.   const char* result;
  86.   if (add_cr)  buflen--;
  87.   if (!strchr(format, '%')) {
  88.     // constant format string
  89.     result = format;
  90.     result_len = strlen(result);
  91.     if (add_cr && result_len >= buflen)  result_len = buflen-1;  // truncate
  92.   } else if (format[0] == '%' && format[1] == 's' && format[2] == '\0') {
  93.     // trivial copy-through format string
  94.     result = va_arg(ap, const char*);
  95.     result_len = strlen(result);
  96.     if (add_cr && result_len >= buflen)  result_len = buflen-1;  // truncate
  97.   } else if (vsnprintf(buffer, buflen, format, ap) >= 0) {
  98.     result = buffer;
  99.     result_len = strlen(result);
  100.   } else {
  101.     DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
  102.     result = buffer;
  103.     result_len = buflen - 1;
  104.     buffer[result_len] = 0;
  105.   }
  106.   if (add_cr) {
  107.     if (result != buffer) {
  108.       strncpy(buffer, result, buflen);
  109.       result = buffer;
  110.     }
  111.     buffer[result_len++] = '\n';
  112.     buffer[result_len] = 0;
  113.   }
  114.   return result;
  115. }
  116.  
  117. void outputStream::print(const char* format, ...) {
  118.   char buffer[O_BUFLEN];
  119.   va_list ap;
  120.   va_start(ap, format);
  121.   size_t len;
  122.   const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len);
  123.   write(str, len);
  124.   va_end(ap);
  125. }
  126.  
  127. void outputStream::print_cr(const char* format, ...) {
  128.   char buffer[O_BUFLEN];
  129.   va_list ap;
  130.   va_start(ap, format);
  131.   size_t len;
  132.   const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, true, len);
  133.   write(str, len);
  134.   va_end(ap);
  135. }
  136.  
  137. void outputStream::vprint(const char *format, va_list argptr) {
  138.   char buffer[O_BUFLEN];
  139.   size_t len;
  140.   const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, false, len);
  141.   write(str, len);
  142. }
  143.  
  144. void outputStream::vprint_cr(const char* format, va_list argptr) {
  145.   char buffer[O_BUFLEN];
  146.   size_t len;
  147.   const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, true, len);
  148.   write(str, len);
  149. }
  150.  
  151. void outputStream::fill_to(int col) {
  152.   int need_fill = col - position();
  153.   sp(need_fill);
  154. }
  155.  
  156. void outputStream::move_to(int col, int slop, int min_space) {
  157.   if (position() >= col + slop)
  158.     cr();
  159.   int need_fill = col - position();
  160.   if (need_fill < min_space)
  161.     need_fill = min_space;
  162.   sp(need_fill);
  163. }
  164.  
  165. void outputStream::put(char ch) {
  166.   assert(ch != 0, "please fix call site");
  167.   char buf[] = { ch, '\0' };
  168.   write(buf, 1);
  169. }
  170.  
  171. #define SP_USE_TABS false
  172.  
  173. void outputStream::sp(int count) {
  174.   if (count < 0)  return;
  175.   if (SP_USE_TABS && count >= 8) {
  176.     int target = position() + count;
  177.     while (count >= 8) {
  178.       this->write("\t", 1);
  179.       count -= 8;
  180.     }
  181.     count = target - position();
  182.   }
  183.   while (count > 0) {
  184.     int nw = (count > 8) ? 8 : count;
  185.     this->write("        ", nw);
  186.     count -= nw;
  187.   }
  188. }
  189.  
  190. void outputStream::cr() {
  191.   this->write("\n", 1);
  192. }
  193.  
  194. void outputStream::stamp() {
  195.   if (! _stamp.is_updated()) {
  196.     _stamp.update(); // start at 0 on first call to stamp()
  197.   }
  198.  
  199.   // outputStream::stamp() may get called by ostream_abort(), use snprintf
  200.   // to avoid allocating large stack buffer in print().
  201.   char buf[40];
  202.   jio_snprintf(buf, sizeof(buf), "%.3f", _stamp.seconds());
  203.   print_raw(buf);
  204. }
  205.  
  206. void outputStream::stamp(bool guard,
  207.                          const char* prefix,
  208.                          const char* suffix) {
  209.   if (!guard) {
  210.     return;
  211.   }
  212.   print_raw(prefix);
  213.   stamp();
  214.   print_raw(suffix);
  215. }
  216.  
  217. void outputStream::date_stamp(bool guard,
  218.                               const char* prefix,
  219.                               const char* suffix) {
  220.   if (!guard) {
  221.     return;
  222.   }
  223.   print_raw(prefix);
  224.   static const char error_time[] = "yyyy-mm-ddThh:mm:ss.mmm+zzzz";
  225.   static const int buffer_length = 32;
  226.   char buffer[buffer_length];
  227.   const char* iso8601_result = os::iso8601_time(buffer, buffer_length);
  228.   if (iso8601_result != NULL) {
  229.     print_raw(buffer);
  230.   } else {
  231.     print_raw(error_time);
  232.   }
  233.   print_raw(suffix);
  234.   return;
  235. }
  236.  
  237. void outputStream::indent() {
  238.   while (_position < _indentation) sp();
  239. }
  240.  
  241. void outputStream::print_jlong(jlong value) {
  242.   // N.B. Same as INT64_FORMAT
  243.   print(os::jlong_format_specifier(), value);
  244. }
  245.  
  246. void outputStream::print_julong(julong value) {
  247.   // N.B. Same as UINT64_FORMAT
  248.   print(os::julong_format_specifier(), value);
  249. }
  250.  
  251. stringStream::stringStream(size_t initial_size) : outputStream() {
  252.   buffer_length = initial_size;
  253.   buffer        = NEW_RESOURCE_ARRAY(char, buffer_length);
  254.   buffer_pos    = 0;
  255.   buffer_fixed  = false;
  256. }
  257.  
  258. // useful for output to fixed chunks of memory, such as performance counters
  259. stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() {
  260.   buffer_length = fixed_buffer_size;
  261.   buffer        = fixed_buffer;
  262.   buffer_pos    = 0;
  263.   buffer_fixed  = true;
  264. }
  265.  
  266. void stringStream::write(const char* s, size_t len) {
  267.   size_t write_len = len;               // number of non-null bytes to write
  268.   size_t end = buffer_pos + len + 1;    // position after write and final '\0'
  269.   if (end > buffer_length) {
  270.     if (buffer_fixed) {
  271.       // if buffer cannot resize, silently truncate
  272.       end = buffer_length;
  273.       write_len = end - buffer_pos - 1; // leave room for the final '\0'
  274.     } else {
  275.       // For small overruns, double the buffer.  For larger ones,
  276.       // increase to the requested size.
  277.       if (end < buffer_length * 2) {
  278.         end = buffer_length * 2;
  279.       }
  280.       char* oldbuf = buffer;
  281.       buffer = NEW_RESOURCE_ARRAY(char, end);
  282.       strncpy(buffer, oldbuf, buffer_pos);
  283.       buffer_length = end;
  284.     }
  285.   }
  286.   // invariant: buffer is always null-terminated
  287.   guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob");
  288.   buffer[buffer_pos + write_len] = 0;
  289.   strncpy(buffer + buffer_pos, s, write_len);
  290.   buffer_pos += write_len;
  291.  
  292.   // Note that the following does not depend on write_len.
  293.   // This means that position and count get updated
  294.   // even when overflow occurs.
  295.   update_position(s, len);
  296. }
  297.  
  298. char* stringStream::as_string() {
  299.   char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
  300.   strncpy(copy, buffer, buffer_pos);
  301.   copy[buffer_pos] = 0;  // terminating null
  302.   return copy;
  303. }
  304.  
  305. stringStream::~stringStream() {}
  306.  
  307. xmlStream*   xtty;
  308. outputStream* tty;
  309. outputStream* gclog_or_tty;
  310. extern Mutex* tty_lock;
  311.  
  312. fileStream::fileStream(const char* file_name) {
  313.   _file = fopen(file_name, "w");
  314.   _need_close = true;
  315. }
  316.  
  317. void fileStream::write(const char* s, size_t len) {
  318.   if (_file != NULL)  {
  319.     // Make an unused local variable to avoid warning from gcc 4.x compiler.
  320.     size_t count = fwrite(s, 1, len, _file);
  321.   }
  322.   update_position(s, len);
  323. }
  324.  
  325. fileStream::~fileStream() {
  326.   if (_file != NULL) {
  327.     if (_need_close) fclose(_file);
  328.     _file = NULL;
  329.   }
  330. }
  331.  
  332. void fileStream::flush() {
  333.   fflush(_file);
  334. }
  335.  
  336. fdStream::fdStream(const char* file_name) {
  337.   _fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  338.   _need_close = true;
  339. }
  340.  
  341. fdStream::~fdStream() {
  342.   if (_fd != -1) {
  343.     if (_need_close) close(_fd);
  344.     _fd = -1;
  345.   }
  346. }
  347.  
  348. void fdStream::write(const char* s, size_t len) {
  349.   if (_fd != -1) {
  350.     // Make an unused local variable to avoid warning from gcc 4.x compiler.
  351.     size_t count = ::write(_fd, s, (int)len);
  352.   }
  353.   update_position(s, len);
  354. }
  355.  
  356. defaultStream* defaultStream::instance = NULL;
  357. int defaultStream::_output_fd = 1;
  358. int defaultStream::_error_fd  = 2;
  359. FILE* defaultStream::_output_stream = stdout;
  360. FILE* defaultStream::_error_stream  = stderr;
  361.  
  362. #define LOG_MAJOR_VERSION 160
  363. #define LOG_MINOR_VERSION 1
  364.  
  365. void defaultStream::init() {
  366.   _inited = true;
  367.   if (LogVMOutput || LogCompilation) {
  368.     init_log();
  369.   }
  370. }
  371.  
  372. bool defaultStream::has_log_file() {
  373.   // lazily create log file (at startup, LogVMOutput is false even
  374.   // if +LogVMOutput is used, because the flags haven't been parsed yet)
  375.   // For safer printing during fatal error handling, do not init logfile
  376.   // if a VM error has been reported.
  377.   if (!_inited && !is_error_reported())  init();
  378.   return _log_file != NULL;
  379. }
  380.  
  381. static const char* make_log_name(const char* log_name, const char* force_directory) {
  382.   const char* basename = log_name;
  383.   char file_sep = os::file_separator()[0];
  384.   const char* cp;
  385.   for (cp = log_name; *cp != '\0'; cp++) {
  386.     if (*cp == '/' || *cp == file_sep) {
  387.       basename = cp+1;
  388.     }
  389.   }
  390.   const char* nametail = log_name;
  391.  
  392.   // Compute buffer length
  393.   size_t buffer_length;
  394.   if (force_directory != NULL) {
  395.     buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
  396.                     strlen(basename) + 1;
  397.   } else {
  398.     buffer_length = strlen(log_name) + 1;
  399.   }
  400.  
  401.   const char* star = strchr(basename, '*');
  402.   int star_pos = (star == NULL) ? -1 : (star - nametail);
  403.  
  404.   char pid[32];
  405.   if (star_pos >= 0) {
  406.     jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id());
  407.     buffer_length += strlen(pid);
  408.   }
  409.  
  410.   // Create big enough buffer.
  411.   char *buf = NEW_C_HEAP_ARRAY(char, buffer_length);
  412.  
  413.   strcpy(buf, "");
  414.   if (force_directory != NULL) {
  415.     strcat(buf, force_directory);
  416.     strcat(buf, os::file_separator());
  417.     nametail = basename;       // completely skip directory prefix
  418.   }
  419.  
  420.   if (star_pos >= 0) {
  421.     // convert foo*bar.log to foo123bar.log
  422.     int buf_pos = (int) strlen(buf);
  423.     strncpy(&buf[buf_pos], nametail, star_pos);
  424.     strcpy(&buf[buf_pos + star_pos], pid);
  425.     nametail += star_pos + 1;  // skip prefix and star
  426.   }
  427.  
  428.   strcat(buf, nametail);      // append rest of name, or all of name
  429.   return buf;
  430. }
  431.  
  432. void defaultStream::init_log() {
  433.   // %%% Need a MutexLocker?
  434.   const char* log_name = LogFile != NULL ? LogFile : "hotspot.log";
  435.   const char* try_name = make_log_name(log_name, NULL);
  436.   fileStream* file = new(ResourceObj::C_HEAP) fileStream(try_name);
  437.   if (!file->is_open()) {
  438.     // Try again to open the file.
  439.     char warnbuf[O_BUFLEN*2];
  440.     jio_snprintf(warnbuf, sizeof(warnbuf),
  441.                  "Warning:  Cannot open log file: %s\n", try_name);
  442.     // Note:  This feature is for maintainer use only.  No need for L10N.
  443.     jio_print(warnbuf);
  444.     FREE_C_HEAP_ARRAY(char, try_name);
  445.     try_name = make_log_name("hs_pid*.log", os::get_temp_directory());
  446.     jio_snprintf(warnbuf, sizeof(warnbuf),
  447.                  "Warning:  Forcing option -XX:LogFile=%s\n", try_name);
  448.     jio_print(warnbuf);
  449.     delete file;
  450.     file = new(ResourceObj::C_HEAP) fileStream(try_name);
  451.     FREE_C_HEAP_ARRAY(char, try_name);
  452.   }
  453.   if (file->is_open()) {
  454.     _log_file = file;
  455.     xmlStream* xs = new(ResourceObj::C_HEAP) xmlStream(file);
  456.     _outer_xmlStream = xs;
  457.     if (this == tty)  xtty = xs;
  458.     // Write XML header.
  459.     xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>");
  460.     // (For now, don't bother to issue a DTD for this private format.)
  461.     jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds();
  462.     // %%% Should be: jlong time_ms = os::start_time_milliseconds(), if
  463.     // we ever get round to introduce that method on the os class
  464.     xs->head("hotspot_log version='%d %d'"
  465.              " process='%d' time_ms='"INT64_FORMAT"'",
  466.              LOG_MAJOR_VERSION, LOG_MINOR_VERSION,
  467.              os::current_process_id(), time_ms);
  468.     // Write VM version header immediately.
  469.     xs->head("vm_version");
  470.     xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr();
  471.     xs->tail("name");
  472.     xs->head("release"); xs->text("%s", VM_Version::vm_release()); xs->cr();
  473.     xs->tail("release");
  474.     xs->head("info"); xs->text("%s", VM_Version::internal_vm_info_string()); xs->cr();
  475.     xs->tail("info");
  476.     xs->tail("vm_version");
  477.     // Record information about the command-line invocation.
  478.     xs->head("vm_arguments");  // Cf. Arguments::print_on()
  479.     if (Arguments::num_jvm_flags() > 0) {
  480.       xs->head("flags");
  481.       Arguments::print_jvm_flags_on(xs->text());
  482.       xs->tail("flags");
  483.     }
  484.     if (Arguments::num_jvm_args() > 0) {
  485.       xs->head("args");
  486.       Arguments::print_jvm_args_on(xs->text());
  487.       xs->tail("args");
  488.     }
  489.     if (Arguments::java_command() != NULL) {
  490.       xs->head("command"); xs->text()->print_cr("%s", Arguments::java_command());
  491.       xs->tail("command");
  492.     }
  493.     if (Arguments::sun_java_launcher() != NULL) {
  494.       xs->head("launcher"); xs->text()->print_cr("%s", Arguments::sun_java_launcher());
  495.       xs->tail("launcher");
  496.     }
  497.     if (Arguments::system_properties() !=  NULL) {
  498.       xs->head("properties");
  499.       // Print it as a java-style property list.
  500.       // System properties don't generally contain newlines, so don't bother with unparsing.
  501.       for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
  502.         xs->text()->print_cr("%s=%s", p->key(), p->value());
  503.       }
  504.       xs->tail("properties");
  505.     }
  506.     xs->tail("vm_arguments");
  507.     // tty output per se is grouped under the <tty>...</tty> element.
  508.     xs->head("tty");
  509.     // All further non-markup text gets copied to the tty:
  510.     xs->_text = this;  // requires friend declaration!
  511.   } else {
  512.     delete(file);
  513.     // and leave xtty as NULL
  514.     LogVMOutput = false;
  515.     DisplayVMOutput = true;
  516.     LogCompilation = false;
  517.   }
  518. }
  519.  
  520. // finish_log() is called during normal VM shutdown. finish_log_on_error() is
  521. // called by ostream_abort() after a fatal error.
  522. //
  523. void defaultStream::finish_log() {
  524.   xmlStream* xs = _outer_xmlStream;
  525.   xs->done("tty");
  526.  
  527.   // Other log forks are appended here, at the End of Time:
  528.   CompileLog::finish_log(xs->out());  // write compile logging, if any, now
  529.  
  530.   xs->done("hotspot_log");
  531.   xs->flush();
  532.  
  533.   fileStream* file = _log_file;
  534.   _log_file = NULL;
  535.  
  536.   delete _outer_xmlStream;
  537.   _outer_xmlStream = NULL;
  538.  
  539.   file->flush();
  540.   delete file;
  541. }
  542.  
  543. void defaultStream::finish_log_on_error(char *buf, int buflen) {
  544.   xmlStream* xs = _outer_xmlStream;
  545.  
  546.   if (xs && xs->out()) {
  547.  
  548.     xs->done_raw("tty");
  549.  
  550.     // Other log forks are appended here, at the End of Time:
  551.     CompileLog::finish_log_on_error(xs->out(), buf, buflen);  // write compile logging, if any, now
  552.  
  553.     xs->done_raw("hotspot_log");
  554.     xs->flush();
  555.  
  556.     fileStream* file = _log_file;
  557.     _log_file = NULL;
  558.     _outer_xmlStream = NULL;
  559.  
  560.     if (file) {
  561.       file->flush();
  562.  
  563.       // Can't delete or close the file because delete and fclose aren't
  564.       // async-safe. We are about to die, so leave it to the kernel.
  565.       // delete file;
  566.     }
  567.   }
  568. }
  569.  
  570. intx defaultStream::hold(intx writer_id) {
  571.   bool has_log = has_log_file();  // check before locking
  572.   if (// impossible, but who knows?
  573.       writer_id == NO_WRITER ||
  574.  
  575.       // bootstrap problem
  576.       tty_lock == NULL ||
  577.  
  578.       // can't grab a lock or call Thread::current() if TLS isn't initialized
  579.       ThreadLocalStorage::thread() == NULL ||
  580.  
  581.       // developer hook
  582.       !SerializeVMOutput ||
  583.  
  584.       // VM already unhealthy
  585.       is_error_reported() ||
  586.  
  587.       // safepoint == global lock (for VM only)
  588.       (SafepointSynchronize::is_synchronizing() &&
  589.        Thread::current()->is_VM_thread())
  590.       ) {
  591.     // do not attempt to lock unless we know the thread and the VM is healthy
  592.     return NO_WRITER;
  593.   }
  594.   if (_writer == writer_id) {
  595.     // already held, no need to re-grab the lock
  596.     return NO_WRITER;
  597.   }
  598.   tty_lock->lock_without_safepoint_check();
  599.   // got the lock
  600.   if (writer_id != _last_writer) {
  601.     if (has_log) {
  602.       _log_file->bol();
  603.       // output a hint where this output is coming from:
  604.       _log_file->print_cr("<writer thread='"INTX_FORMAT"'/>", writer_id);
  605.     }
  606.     _last_writer = writer_id;
  607.   }
  608.   _writer = writer_id;
  609.   return writer_id;
  610. }
  611.  
  612. void defaultStream::release(intx holder) {
  613.   if (holder == NO_WRITER) {
  614.     // nothing to release:  either a recursive lock, or we scribbled (too bad)
  615.     return;
  616.   }
  617.   if (_writer != holder) {
  618.     return;  // already unlocked, perhaps via break_tty_lock_for_safepoint
  619.   }
  620.   _writer = NO_WRITER;
  621.   tty_lock->unlock();
  622. }
  623.  
  624.  
  625. // Yuck:  jio_print does not accept char*/len.
  626. static void call_jio_print(const char* s, size_t len) {
  627.   char buffer[O_BUFLEN+100];
  628.   if (len > sizeof(buffer)-1) {
  629.     warning("increase O_BUFLEN in ostream.cpp -- output truncated");
  630.     len = sizeof(buffer)-1;
  631.   }
  632.   strncpy(buffer, s, len);
  633.   buffer[len] = '\0';
  634.   jio_print(buffer);
  635. }
  636.  
  637.  
  638. void defaultStream::write(const char* s, size_t len) {
  639.   intx thread_id = os::current_thread_id();
  640.   intx holder = hold(thread_id);
  641.  
  642.   if (DisplayVMOutput &&
  643.       (_outer_xmlStream == NULL || !_outer_xmlStream->inside_attrs())) {
  644.     // print to output stream. It can be redirected by a vfprintf hook
  645.     if (s[len] == '\0') {
  646.       jio_print(s);
  647.     } else {
  648.       call_jio_print(s, len);
  649.     }
  650.   }
  651.  
  652.   // print to log file
  653.   if (has_log_file()) {
  654.     int nl0 = _newlines;
  655.     xmlTextStream::write(s, len);
  656.     // flush the log file too, if there were any newlines
  657.     if (nl0 != _newlines){
  658.       flush();
  659.     }
  660.   } else {
  661.     update_position(s, len);
  662.   }
  663.  
  664.   release(holder);
  665. }
  666.  
  667. intx ttyLocker::hold_tty() {
  668.   if (defaultStream::instance == NULL)  return defaultStream::NO_WRITER;
  669.   intx thread_id = os::current_thread_id();
  670.   return defaultStream::instance->hold(thread_id);
  671. }
  672.  
  673. void ttyLocker::release_tty(intx holder) {
  674.   if (holder == defaultStream::NO_WRITER)  return;
  675.   defaultStream::instance->release(holder);
  676. }
  677.  
  678. void ttyLocker::break_tty_lock_for_safepoint(intx holder) {
  679.   if (defaultStream::instance != NULL &&
  680.       defaultStream::instance->writer() == holder) {
  681.     if (xtty != NULL) {
  682.       xtty->print_cr("<!-- safepoint while printing -->");
  683.     }
  684.     defaultStream::instance->release(holder);
  685.   }
  686.   // (else there was no lock to break)
  687. }
  688.  
  689. void ostream_init() {
  690.   if (defaultStream::instance == NULL) {
  691.     defaultStream::instance = new(ResourceObj::C_HEAP) defaultStream();
  692.     tty = defaultStream::instance;
  693.  
  694.     // We want to ensure that time stamps in GC logs consider time 0
  695.     // the time when the JVM is initialized, not the first time we ask
  696.     // for a time stamp. So, here, we explicitly update the time stamp
  697.     // of tty.
  698.     tty->time_stamp().update_to(1);
  699.   }
  700. }
  701.  
  702. void ostream_init_log() {
  703.   // For -Xloggc:<file> option - called in runtime/thread.cpp
  704.   // Note : this must be called AFTER ostream_init()
  705.  
  706.   gclog_or_tty = tty; // default to tty
  707.   if (Arguments::gc_log_filename() != NULL) {
  708.     fileStream * gclog = new(ResourceObj::C_HEAP)
  709.                            fileStream(Arguments::gc_log_filename());
  710.     if (gclog->is_open()) {
  711.       // now we update the time stamp of the GC log to be synced up
  712.       // with tty.
  713.       gclog->time_stamp().update_to(tty->time_stamp().ticks());
  714.       gclog_or_tty = gclog;
  715.     }
  716.   }
  717.  
  718.   // If we haven't lazily initialized the logfile yet, do it now,
  719.   // to avoid the possibility of lazy initialization during a VM
  720.   // crash, which can affect the stability of the fatal error handler.
  721.   defaultStream::instance->has_log_file();
  722. }
  723.  
  724. // ostream_exit() is called during normal VM exit to finish log files, flush
  725. // output and free resource.
  726. void ostream_exit() {
  727.   static bool ostream_exit_called = false;
  728.   if (ostream_exit_called)  return;
  729.   ostream_exit_called = true;
  730.   if (gclog_or_tty != tty) {
  731.       delete gclog_or_tty;
  732.   }
  733.   {
  734.       // we temporaly disable PrintMallocFree here
  735.       // as otherwise it'll lead to using of almost deleted
  736.       // tty or defaultStream::instance in logging facility
  737.       // of HeapFree(), see 6391258
  738.       DEBUG_ONLY(FlagSetting fs(PrintMallocFree, false);)
  739.       if (tty != defaultStream::instance) {
  740.           delete tty;
  741.       }
  742.       if (defaultStream::instance != NULL) {
  743.           delete defaultStream::instance;
  744.       }
  745.   }
  746.   tty = NULL;
  747.   xtty = NULL;
  748.   gclog_or_tty = NULL;
  749.   defaultStream::instance = NULL;
  750. }
  751.  
  752. // ostream_abort() is called by os::abort() when VM is about to die.
  753. void ostream_abort() {
  754.   // Here we can't delete gclog_or_tty and tty, just flush their output
  755.   if (gclog_or_tty) gclog_or_tty->flush();
  756.   if (tty) tty->flush();
  757.  
  758.   if (defaultStream::instance != NULL) {
  759.     static char buf[4096];
  760.     defaultStream::instance->finish_log_on_error(buf, sizeof(buf));
  761.   }
  762. }
  763.  
  764. staticBufferStream::staticBufferStream(char* buffer, size_t buflen,
  765.                                        outputStream *outer_stream) {
  766.   _buffer = buffer;
  767.   _buflen = buflen;
  768.   _outer_stream = outer_stream;
  769. }
  770.  
  771. void staticBufferStream::write(const char* c, size_t len) {
  772.   _outer_stream->print_raw(c, (int)len);
  773. }
  774.  
  775. void staticBufferStream::flush() {
  776.   _outer_stream->flush();
  777. }
  778.  
  779. void staticBufferStream::print(const char* format, ...) {
  780.   va_list ap;
  781.   va_start(ap, format);
  782.   size_t len;
  783.   const char* str = do_vsnprintf(_buffer, _buflen, format, ap, false, len);
  784.   write(str, len);
  785.   va_end(ap);
  786. }
  787.  
  788. void staticBufferStream::print_cr(const char* format, ...) {
  789.   va_list ap;
  790.   va_start(ap, format);
  791.   size_t len;
  792.   const char* str = do_vsnprintf(_buffer, _buflen, format, ap, true, len);
  793.   write(str, len);
  794.   va_end(ap);
  795. }
  796.  
  797. void staticBufferStream::vprint(const char *format, va_list argptr) {
  798.   size_t len;
  799.   const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, false, len);
  800.   write(str, len);
  801. }
  802.  
  803. void staticBufferStream::vprint_cr(const char* format, va_list argptr) {
  804.   size_t len;
  805.   const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, true, len);
  806.   write(str, len);
  807. }
  808.  
  809. bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
  810.   buffer_length = initial_size;
  811.   buffer        = NEW_C_HEAP_ARRAY(char, buffer_length);
  812.   buffer_pos    = 0;
  813.   buffer_fixed  = false;
  814.   buffer_max    = bufmax;
  815. }
  816.  
  817. bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() {
  818.   buffer_length = fixed_buffer_size;
  819.   buffer        = fixed_buffer;
  820.   buffer_pos    = 0;
  821.   buffer_fixed  = true;
  822.   buffer_max    = bufmax;
  823. }
  824.  
  825. void bufferedStream::write(const char* s, size_t len) {
  826.  
  827.   if(buffer_pos + len > buffer_max) {
  828.     flush();
  829.   }
  830.  
  831.   size_t end = buffer_pos + len;
  832.   if (end >= buffer_length) {
  833.     if (buffer_fixed) {
  834.       // if buffer cannot resize, silently truncate
  835.       len = buffer_length - buffer_pos - 1;
  836.     } else {
  837.       // For small overruns, double the buffer.  For larger ones,
  838.       // increase to the requested size.
  839.       if (end < buffer_length * 2) {
  840.         end = buffer_length * 2;
  841.       }
  842.       buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end);
  843.       buffer_length = end;
  844.     }
  845.   }
  846.   memcpy(buffer + buffer_pos, s, len);
  847.   buffer_pos += len;
  848.   update_position(s, len);
  849. }
  850.  
  851. char* bufferedStream::as_string() {
  852.   char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
  853.   strncpy(copy, buffer, buffer_pos);
  854.   copy[buffer_pos] = 0;  // terminating null
  855.   return copy;
  856. }
  857.  
  858. bufferedStream::~bufferedStream() {
  859.   if (!buffer_fixed) {
  860.     FREE_C_HEAP_ARRAY(char, buffer);
  861.   }
  862. }
  863.  
  864. #ifndef PRODUCT
  865.  
  866. #if defined(SOLARIS) || defined(LINUX)
  867. #include <sys/types.h>
  868. #include <sys/socket.h>
  869. #include <netinet/in.h>
  870. #include <arpa/inet.h>
  871. #endif
  872.  
  873. // Network access
  874. networkStream::networkStream() : bufferedStream(1024*10, 1024*10) {
  875.  
  876.   _socket = -1;
  877.  
  878.   int result = os::socket(AF_INET, SOCK_STREAM, 0);
  879.   if (result <= 0) {
  880.     assert(false, "Socket could not be created!");
  881.   } else {
  882.     _socket = result;
  883.   }
  884. }
  885.  
  886. int networkStream::read(char *buf, size_t len) {
  887.   return os::recv(_socket, buf, (int)len, 0);
  888. }
  889.  
  890. void networkStream::flush() {
  891.   if (size() != 0) {
  892.     int result = os::raw_send(_socket, (char *)base(), (int)size(), 0);
  893.     assert(result != -1, "connection error");
  894.     assert(result == (int)size(), "didn't send enough data");
  895.   }
  896.   reset();
  897. }
  898.  
  899. networkStream::~networkStream() {
  900.   close();
  901. }
  902.  
  903. void networkStream::close() {
  904.   if (_socket != -1) {
  905.     flush();
  906.     os::socket_close(_socket);
  907.     _socket = -1;
  908.   }
  909. }
  910.  
  911. bool networkStream::connect(const char *ip, short port) {
  912.  
  913.   struct sockaddr_in server;
  914.   server.sin_family = AF_INET;
  915.   server.sin_port = htons(port);
  916.  
  917.   server.sin_addr.s_addr = inet_addr(ip);
  918.   if (server.sin_addr.s_addr == (uint32_t)-1) {
  919.     struct hostent* host = os::get_host_by_name((char*)ip);
  920.     if (host != NULL) {
  921.       memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length);
  922.     } else {
  923.       return false;
  924.     }
  925.   }
  926.  
  927.  
  928.   int result = os::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in));
  929.   return (result >= 0);
  930. }
  931.  
  932. #endif
  933.  
  934.