--- old/src/share/vm/logging/logStream.cpp 2017-06-30 20:00:25.708717700 +0200 +++ new/src/share/vm/logging/logStream.cpp 2017-06-30 20:00:25.000218300 +0200 @@ -24,11 +24,83 @@ #include "precompiled.hpp" #include "logging/log.hpp" -#include "logging/logStream.inline.hpp" +#include "logging/logStream.hpp" -// Create a log stream without an embedded ResourceMark. -// The function is placed here to be called out-of-line in log.hpp. -outputStream* create_log_stream(LogLevelType level, LogTagSet* tagset) { - return new LogStreamNoResourceMark(level, tagset); +LogStream::LineBuffer::LineBuffer() + : _buf(_smallbuf), _cap(sizeof(_smallbuf)), _pos(0) +{ + _buf[0] = '\0'; +} + +LogStream::LineBuffer::~LineBuffer() { + assert(_pos == 0, "still outstanding bytes in the line buffer"); + if (_buf != _smallbuf) { + os::free(_buf); + } +} + +// try_ensure_cap tries to enlarge the capacity of the internal buffer +// to the given atleast value. May fail if either OOM happens or atleast +// is larger than a reasonable max of 1 M. Caller must not assume +// capacity without checking. +void LogStream::LineBuffer::try_ensure_cap(size_t atleast) { + assert(_cap >= sizeof(_smallbuf), "sanity"); + if (_cap < atleast) { + const size_t reasonable_max = 1 * M; + size_t newcap = align_size_up(atleast + 64, 64); + assert(_cap <= reasonable_max, "sanity"); + // Cap out at a reasonable max to prevent runaway leaks. + if (newcap > reasonable_max) { + newcap = reasonable_max; + } + + char* const newbuf = (char*) os::malloc(newcap, mtLogging); + if (newbuf == NULL) { // OOM. Leave object unchanged. + return; + } + if (_pos > 0) { // preserve old content + memcpy(newbuf, _buf, _pos + 1); // ..including trailing zero + } + if (_buf != _smallbuf) { + os::free(_buf); + } + _buf = newbuf; + _cap = newcap; + } + assert(_cap >= atleast, "sanity"); +} + +void LogStream::LineBuffer::append(const char* s, size_t len) { + assert(_buf[_pos] == '\0', "sanity"); + assert(_pos < _cap, "sanity"); + try_ensure_cap(_pos + len + 1); + // try_ensure_cap may not have enlarged the capacity to the full requested + // extend or may have not worked at all. In that case, just gracefully work + // with what we have already; just truncate if necessary. + if (_pos + len + 1 > _cap) { + len = _cap - _pos - 1; + if (len == 0) { + return; + } + } + memcpy(_buf + _pos, s, len); + _pos += len; + _buf[_pos] = '\0'; +} + +void LogStream::LineBuffer::reset() { + _pos = 0; + _buf[_pos] = '\0'; +} + +void LogStream::write(const char* s, size_t len) { + if (len > 0 && s[len - 1] == '\n') { + _current_line.append(s, len - 1); // omit the newline. + _log_handle.print("%s", _current_line.ptr()); + _current_line.reset(); + } else { + _current_line.append(s, len); + } + update_position(s, len); }