/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*
* 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.
*
*/
#include "precompiled.hpp"
#include "compiler/compileLog.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/arguments.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/ostream.hpp"
#include "utilities/xmlstream.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
_position = 0;
_newlines = 0;
_precount = 0;
_indentation = 0;
}
_position = 0;
_newlines = 0;
_precount = 0;
_indentation = 0;
}
char ch = s[i];
if (ch == '\n') {
_newlines += 1;
_position = 0;
} else if (ch == '\t') {
} else {
_position += 1;
}
}
}
// Execute a vsprintf, using the given buffer if necessary.
// Return a pointer to the formatted string.
bool add_cr,
size_t& result_len) {
const char* result;
// constant format string
// trivial copy-through format string
} else {
buffer[result_len] = 0;
}
if (add_cr) {
}
buffer[result_len] = 0;
}
return result;
}
}
}
}
}
}
cr();
}
}
#define SP_USE_TABS false
if (count < 0) return;
while (count >= 8) {
count -= 8;
}
}
while (count > 0) {
}
}
}
if (! _stamp.is_updated()) {
}
// outputStream::stamp() may get called by ostream_abort(), use snprintf
// to avoid allocating large stack buffer in print().
}
const char* prefix,
const char* suffix) {
if (!guard) {
return;
}
stamp();
}
const char* prefix,
const char* suffix) {
if (!guard) {
return;
}
if (iso8601_result != NULL) {
} else {
}
return;
}
return *this;
}
// N.B. Same as INT64_FORMAT
}
// N.B. Same as UINT64_FORMAT
}
/**
* This prints out hex data in a 'windbg' or 'xxd' form, where each line is:
* <hex-address>: 8 * <hex-halfword> <ascii translation (optional)>
* example:
* 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000 .DOF............
* 0000010: 0000 0000 0000 0040 0000 0020 0000 0005 .......@... ....
* 0000020: 0000 0000 0000 0040 0000 0000 0000 015d .......@.......]
* ...
*
* indent is applied to each line. Ends with a CR.
*/
if (i % 16 == 0) {
}
if (i % 2 == 0) {
print(" ");
}
if (i < len) {
} else {
print(" ");
}
if ((i + 1) % 16 == 0) {
if (with_ascii) {
print(" ");
for (size_t j = 0; j < 16; ++j) {
}
}
}
print_cr("");
}
}
}
buffer_pos = 0;
buffer_fixed = false;
}
// useful for output to fixed chunks of memory, such as performance counters
buffer_pos = 0;
buffer_fixed = true;
}
if (end > buffer_length) {
if (buffer_fixed) {
// if buffer cannot resize, silently truncate
end = buffer_length;
} else {
// For small overruns, double the buffer. For larger ones,
// increase to the requested size.
}
buffer_length = end;
}
}
// invariant: buffer is always null-terminated
buffer_pos += write_len;
// Note that the following does not depend on write_len.
// This means that position and count get updated
// even when overflow occurs.
update_position(s, len);
}
return copy;
}
stringStream::~stringStream() {}
_need_close = true;
}
_need_close = true;
}
// Make an unused local variable to avoid warning from gcc 4.x compiler.
}
update_position(s, len);
}
}
}
return size;
}
//Get rid of annoying \n char
return ret;
}
fileStream::~fileStream() {
}
}
}
_need_close = true;
}
if (_fd != -1) {
_fd = -1;
}
}
if (_fd != -1) {
// Make an unused local variable to avoid warning from gcc 4.x compiler.
}
update_position(s, len);
}
_file_name = NULL;
}
}
_cur_file_num = 0;
_bytes_written = 0L;
_need_close = true;
}
_cur_file_num = 0;
_bytes_written = 0L;
_need_close = true;
}
_bytes_written += count;
}
update_position(s, len);
}
// rotate_log must be called from VMThread at safepoint. In case need change parameters
// for gc log rotation from thread other than VMThread, a sub type of VM_Operation
// should be created and be submitted to VMThread's operation queue. DO NOT call this
// function directly. Currently, it is safe to rotate log at safepoint through VMThread.
// That is, no mutator threads and concurrent GC threads run parallel with VMThread to
// write to gc log file at safepoint. If in future, changes made for mutator threads or
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// must be synchronized.
return;
}
#ifdef ASSERT
"Must be VMThread at safepoint");
#endif
if (NumberOfGCLogFiles == 1) {
// rotate in same file
rewind();
_bytes_written = 0L;
return;
}
// rotate file in names file.0, file.1, file.2, ..., file.<MaxGCLogFileNumbers-1>
// close current file, rotate to next file
_cur_file_num ++;
}
_bytes_written = 0L;
_need_close = true;
} else {
_need_close = false;
}
}
_inited = true;
if (LogVMOutput || LogCompilation) {
init_log();
}
}
// lazily create log file (at startup, LogVMOutput is false even
// if +LogVMOutput is used, because the flags haven't been parsed yet)
// For safer printing during fatal error handling, do not init logfile
// if a VM error has been reported.
}
const char* cp;
}
}
// Compute buffer length
if (force_directory != NULL) {
} else {
}
// Try %p
skip = 2;
}
}
if (star_pos >= 0) {
}
// Create big enough buffer.
if (force_directory != NULL) {
}
if (star_pos >= 0) {
// convert foo*bar.log or foo%pbar.log to foo123bar.log
}
return buf;
}
// %%% Need a MutexLocker?
// Try again to open the file.
"Warning: Cannot open log file: %s\n", try_name);
// Note: This feature is for maintainer use only. No need for L10N.
"Warning: Forcing option -XX:LogFile=%s\n", try_name);
delete file;
}
// Write XML header.
// (For now, don't bother to issue a DTD for this private format.)
// %%% Should be: jlong time_ms = os::start_time_milliseconds(), if
// we ever get round to introduce that method on the os class
// Write VM version header immediately.
// Record information about the command-line invocation.
if (Arguments::num_jvm_flags() > 0) {
}
if (Arguments::num_jvm_args() > 0) {
}
}
}
// Print it as a java-style property list.
// System properties don't generally contain newlines, so don't bother with unparsing.
}
}
// tty output per se is grouped under the <tty>...</tty> element.
// All further non-markup text gets copied to the tty:
} else {
delete(file);
// and leave xtty as NULL
LogVMOutput = false;
DisplayVMOutput = true;
LogCompilation = false;
}
}
// finish_log() is called during normal VM shutdown. finish_log_on_error() is
// called by ostream_abort() after a fatal error.
//
// Other log forks are appended here, at the End of Time:
delete _outer_xmlStream;
delete file;
}
// Other log forks are appended here, at the End of Time:
if (file) {
// Can't delete or close the file because delete and fclose aren't
// async-safe. We are about to die, so leave it to the kernel.
// delete file;
}
}
}
if (// impossible, but who knows?
// bootstrap problem
// can't grab a lock or call Thread::current() if TLS isn't initialized
// developer hook
// VM already unhealthy
is_error_reported() ||
// safepoint == global lock (for VM only)
) {
// do not attempt to lock unless we know the thread and the VM is healthy
return NO_WRITER;
}
// already held, no need to re-grab the lock
return NO_WRITER;
}
// got the lock
if (writer_id != _last_writer) {
if (has_log) {
// output a hint where this output is coming from:
}
}
return writer_id;
}
// nothing to release: either a recursive lock, or we scribbled (too bad)
return;
}
return; // already unlocked, perhaps via break_tty_lock_for_safepoint
}
}
// Yuck: jio_print does not accept char*/len.
warning("increase O_BUFLEN in ostream.cpp -- output truncated");
}
}
if (DisplayVMOutput &&
// print to output stream. It can be redirected by a vfprintf hook
if (s[len] == '\0') {
jio_print(s);
} else {
call_jio_print(s, len);
}
}
// print to log file
if (has_log_file()) {
// flush the log file too, if there were any newlines
flush();
}
} else {
update_position(s, len);
}
}
}
}
// release the lock and return true so callers know if was
// previously held.
return true;
}
return false;
}
}
}
// (else there was no lock to break)
}
void ostream_init() {
// We want to ensure that time stamps in GC logs consider time 0
// the time when the JVM is initialized, not the first time we ask
// for a time stamp. So, here, we explicitly update the time stamp
// of tty.
}
}
void ostream_init_log() {
// For -Xloggc:<file> option - called in runtime/thread.cpp
// Note : this must be called AFTER ostream_init()
// now we update the time stamp of the GC log to be synced up
// with tty.
}
}
// If we haven't lazily initialized the logfile yet, do it now,
// to avoid the possibility of lazy initialization during a VM
// crash, which can affect the stability of the fatal error handler.
}
// ostream_exit() is called during normal VM exit to finish log files, flush
// output and free resource.
void ostream_exit() {
static bool ostream_exit_called = false;
if (ostream_exit_called) return;
ostream_exit_called = true;
if (gclog_or_tty != tty) {
delete gclog_or_tty;
}
{
// we temporaly disable PrintMallocFree here
// as otherwise it'll lead to using of almost deleted
// tty or defaultStream::instance in logging facility
// of HeapFree(), see 6391258
delete tty;
}
}
}
gclog_or_tty = NULL;
}
// ostream_abort() is called by os::abort() when VM is about to die.
void ostream_abort() {
// Here we can't delete gclog_or_tty and tty, just flush their output
}
}
// compile task prints time stamp relative to VM start
}
}
_outer_stream->flush();
}
}
}
}
}
buffer_pos = 0;
buffer_fixed = false;
buffer_max = bufmax;
}
bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() {
buffer_pos = 0;
buffer_fixed = true;
buffer_max = bufmax;
}
flush();
}
if (end >= buffer_length) {
if (buffer_fixed) {
// if buffer cannot resize, silently truncate
} else {
// For small overruns, double the buffer. For larger ones,
// increase to the requested size.
}
buffer_length = end;
}
}
buffer_pos += len;
update_position(s, len);
}
return copy;
}
bufferedStream::~bufferedStream() {
if (!buffer_fixed) {
}
}
#ifndef PRODUCT
#endif
// Network access
_socket = -1;
if (result <= 0) {
assert(false, "Socket could not be created!");
} else {
}
}
}
if (size() != 0) {
}
reset();
}
networkStream::~networkStream() {
close();
}
if (_socket != -1) {
flush();
_socket = -1;
}
}
} else {
return false;
}
}
return (result >= 0);
}
#endif