8146905: cleanup ostream, staticBufferStream
Get rid of staticBufferStream and implement the use-caller-provided-scratch-buffer feature in a simpler way. Reviewed-by: simonis, dholmes
This commit is contained in:
parent
4b4e700628
commit
480e92f8b5
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -44,6 +44,8 @@ outputStream::outputStream(int width) {
|
|||||||
_newlines = 0;
|
_newlines = 0;
|
||||||
_precount = 0;
|
_precount = 0;
|
||||||
_indentation = 0;
|
_indentation = 0;
|
||||||
|
_scratch = NULL;
|
||||||
|
_scratch_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
outputStream::outputStream(int width, bool has_time_stamps) {
|
outputStream::outputStream(int width, bool has_time_stamps) {
|
||||||
@ -52,6 +54,8 @@ outputStream::outputStream(int width, bool has_time_stamps) {
|
|||||||
_newlines = 0;
|
_newlines = 0;
|
||||||
_precount = 0;
|
_precount = 0;
|
||||||
_indentation = 0;
|
_indentation = 0;
|
||||||
|
_scratch = NULL;
|
||||||
|
_scratch_len = 0;
|
||||||
if (has_time_stamps) _stamp.update();
|
if (has_time_stamps) _stamp.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,38 +123,47 @@ const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void outputStream::print(const char* format, ...) {
|
void outputStream::do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) {
|
||||||
char buffer[O_BUFLEN];
|
char buffer[O_BUFLEN];
|
||||||
|
size_t len;
|
||||||
|
const char* str = do_vsnprintf(buffer, sizeof(buffer), format, ap, add_cr, len);
|
||||||
|
write(str, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outputStream::do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) {
|
||||||
|
size_t len;
|
||||||
|
const char* str = do_vsnprintf(_scratch, _scratch_len, format, ap, add_cr, len);
|
||||||
|
write(str, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outputStream::do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) {
|
||||||
|
if (_scratch) {
|
||||||
|
do_vsnprintf_and_write_with_scratch_buffer(format, ap, add_cr);
|
||||||
|
} else {
|
||||||
|
do_vsnprintf_and_write_with_automatic_buffer(format, ap, add_cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void outputStream::print(const char* format, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
size_t len;
|
do_vsnprintf_and_write(format, ap, false);
|
||||||
const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len);
|
|
||||||
write(str, len);
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void outputStream::print_cr(const char* format, ...) {
|
void outputStream::print_cr(const char* format, ...) {
|
||||||
char buffer[O_BUFLEN];
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
size_t len;
|
do_vsnprintf_and_write(format, ap, true);
|
||||||
const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, true, len);
|
|
||||||
write(str, len);
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void outputStream::vprint(const char *format, va_list argptr) {
|
void outputStream::vprint(const char *format, va_list argptr) {
|
||||||
char buffer[O_BUFLEN];
|
do_vsnprintf_and_write(format, argptr, false);
|
||||||
size_t len;
|
|
||||||
const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, false, len);
|
|
||||||
write(str, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void outputStream::vprint_cr(const char* format, va_list argptr) {
|
void outputStream::vprint_cr(const char* format, va_list argptr) {
|
||||||
char buffer[O_BUFLEN];
|
do_vsnprintf_and_write(format, argptr, true);
|
||||||
size_t len;
|
|
||||||
const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, true, len);
|
|
||||||
write(str, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void outputStream::fill_to(int col) {
|
void outputStream::fill_to(int col) {
|
||||||
@ -958,53 +971,6 @@ void ostream_abort() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
staticBufferStream::staticBufferStream(char* buffer, size_t buflen,
|
|
||||||
outputStream *outer_stream) {
|
|
||||||
_buffer = buffer;
|
|
||||||
_buflen = buflen;
|
|
||||||
_outer_stream = outer_stream;
|
|
||||||
// compile task prints time stamp relative to VM start
|
|
||||||
_stamp.update_to(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void staticBufferStream::write(const char* c, size_t len) {
|
|
||||||
_outer_stream->print_raw(c, (int)len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void staticBufferStream::flush() {
|
|
||||||
_outer_stream->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void staticBufferStream::print(const char* format, ...) {
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
size_t len;
|
|
||||||
const char* str = do_vsnprintf(_buffer, _buflen, format, ap, false, len);
|
|
||||||
write(str, len);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void staticBufferStream::print_cr(const char* format, ...) {
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
size_t len;
|
|
||||||
const char* str = do_vsnprintf(_buffer, _buflen, format, ap, true, len);
|
|
||||||
write(str, len);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void staticBufferStream::vprint(const char *format, va_list argptr) {
|
|
||||||
size_t len;
|
|
||||||
const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, false, len);
|
|
||||||
write(str, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void staticBufferStream::vprint_cr(const char* format, va_list argptr) {
|
|
||||||
size_t len;
|
|
||||||
const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, true, len);
|
|
||||||
write(str, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
|
bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
|
||||||
buffer_length = initial_size;
|
buffer_length = initial_size;
|
||||||
buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
|
buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -49,6 +49,8 @@ class outputStream : public ResourceObj {
|
|||||||
int _newlines; // number of '\n' output so far
|
int _newlines; // number of '\n' output so far
|
||||||
julong _precount; // number of chars output, less _position
|
julong _precount; // number of chars output, less _position
|
||||||
TimeStamp _stamp; // for time stamps
|
TimeStamp _stamp; // for time stamps
|
||||||
|
char* _scratch; // internal scratch buffer for printf
|
||||||
|
size_t _scratch_len; // size of internal scratch buffer
|
||||||
|
|
||||||
void update_position(const char* s, size_t len);
|
void update_position(const char* s, size_t len);
|
||||||
static const char* do_vsnprintf(char* buffer, size_t buflen,
|
static const char* do_vsnprintf(char* buffer, size_t buflen,
|
||||||
@ -56,6 +58,13 @@ class outputStream : public ResourceObj {
|
|||||||
bool add_cr,
|
bool add_cr,
|
||||||
size_t& result_len) ATTRIBUTE_PRINTF(3, 0);
|
size_t& result_len) ATTRIBUTE_PRINTF(3, 0);
|
||||||
|
|
||||||
|
// calls do_vsnprintf and writes output to stream; uses an on-stack buffer.
|
||||||
|
void do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
|
||||||
|
// calls do_vsnprintf and writes output to stream; uses the user-provided buffer;
|
||||||
|
void do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
|
||||||
|
// calls do_vsnprintf, then writes output to stream.
|
||||||
|
void do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// creation
|
// creation
|
||||||
outputStream(int width = 80);
|
outputStream(int width = 80);
|
||||||
@ -119,6 +128,10 @@ class outputStream : public ResourceObj {
|
|||||||
virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation
|
virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation
|
||||||
virtual ~outputStream() {} // close properly on deletion
|
virtual ~outputStream() {} // close properly on deletion
|
||||||
|
|
||||||
|
// Caller may specify their own scratch buffer to use for printing; otherwise,
|
||||||
|
// an automatic buffer on the stack (with O_BUFLEN len) is used.
|
||||||
|
void set_scratch_buffer(char* p, size_t len) { _scratch = p; _scratch_len = len; }
|
||||||
|
|
||||||
void dec_cr() { dec(); cr(); }
|
void dec_cr() { dec(); cr(); }
|
||||||
void inc_cr() { inc(); cr(); }
|
void inc_cr() { inc(); cr(); }
|
||||||
};
|
};
|
||||||
@ -250,26 +263,6 @@ void ostream_init_log();
|
|||||||
void ostream_exit();
|
void ostream_exit();
|
||||||
void ostream_abort();
|
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();
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// In the non-fixed buffer case an underlying buffer will be created and
|
// In the non-fixed buffer case an underlying buffer will be created and
|
||||||
// managed in C heap. Not MT-safe.
|
// managed in C heap. Not MT-safe.
|
||||||
class bufferedStream : public outputStream {
|
class bufferedStream : public outputStream {
|
||||||
|
@ -987,10 +987,12 @@ void VMError::print_vm_info(outputStream* st) {
|
|||||||
volatile intptr_t VMError::first_error_tid = -1;
|
volatile intptr_t VMError::first_error_tid = -1;
|
||||||
|
|
||||||
// An error could happen before tty is initialized or after it has been
|
// An error could happen before tty is initialized or after it has been
|
||||||
// destroyed. Here we use a very simple unbuffered fdStream for printing.
|
// destroyed.
|
||||||
// Only out.print_raw() and out.print_raw_cr() should be used, as other
|
// Please note: to prevent large stack allocations, the log- and
|
||||||
// printing methods need to allocate large buffer on stack. To format a
|
// output-stream use a global scratch buffer for format printing.
|
||||||
// string, use jio_snprintf() with a static buffer or use staticBufferStream.
|
// (see VmError::report_and_die(). Access to those streams is synchronized
|
||||||
|
// in VmError::report_and_die() - there is only one reporting thread at
|
||||||
|
// any given time.
|
||||||
fdStream VMError::out(defaultStream::output_fd());
|
fdStream VMError::out(defaultStream::output_fd());
|
||||||
fdStream VMError::log; // error log used by VMError::report_and_die()
|
fdStream VMError::log; // error log used by VMError::report_and_die()
|
||||||
|
|
||||||
@ -1100,6 +1102,8 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
|
|||||||
{
|
{
|
||||||
// Don't allocate large buffer on stack
|
// Don't allocate large buffer on stack
|
||||||
static char buffer[O_BUFLEN];
|
static char buffer[O_BUFLEN];
|
||||||
|
out.set_scratch_buffer(buffer, sizeof(buffer));
|
||||||
|
log.set_scratch_buffer(buffer, sizeof(buffer));
|
||||||
|
|
||||||
// How many errors occurred in error handler when reporting first_error.
|
// How many errors occurred in error handler when reporting first_error.
|
||||||
static int recursive_error_count;
|
static int recursive_error_count;
|
||||||
@ -1186,8 +1190,7 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
|
|||||||
|
|
||||||
// print to screen
|
// print to screen
|
||||||
if (!out_done) {
|
if (!out_done) {
|
||||||
staticBufferStream sbs(buffer, sizeof(buffer), &out);
|
report(&out, false);
|
||||||
report(&sbs, false);
|
|
||||||
|
|
||||||
out_done = true;
|
out_done = true;
|
||||||
|
|
||||||
@ -1215,8 +1218,7 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
staticBufferStream sbs(buffer, O_BUFLEN, &log);
|
report(&log, true);
|
||||||
report(&sbs, true);
|
|
||||||
_current_step = 0;
|
_current_step = 0;
|
||||||
_current_step_info = "";
|
_current_step_info = "";
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user