--- old/src/hotspot/share/prims/jvm.cpp 2018-05-01 09:30:57.523120776 +0900 +++ new/src/hotspot/share/prims/jvm.cpp 2018-05-01 09:30:57.359120165 +0900 @@ -2719,10 +2719,10 @@ int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) { // Reject count values that are negative signed values converted to // unsigned; see bug 4399518, 4417214 - if ((intptr_t)count <= 0) return -1; + if ((intptr_t)count < 0) return -1; int result = os::vsnprintf(str, count, fmt, args); - if (result > 0 && (size_t)result >= count) { + if (count > 0 && result > 0 && (size_t)result >= count) { result = -1; } --- old/src/hotspot/share/utilities/events.hpp 2018-05-01 09:30:58.090122885 +0900 +++ new/src/hotspot/share/utilities/events.hpp 2018-05-01 09:30:57.931122294 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,10 +143,10 @@ } }; -// A simple ring buffer of fixed size text messages. -class StringEventLog : public EventLogBase { +// A simple ring buffer of text messages. +class StringEventLog : public EventLogBase { public: - StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase(name, count) {} + StringEventLog(const char* name, int count = LogEventsBufferEntries) : EventLogBase(name, count) {} void logv(Thread* thread, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0) { if (!should_log()) return; @@ -282,9 +282,9 @@ out->cr(); } -// Implement a printing routine for the StringLogMessage +// Implement a printing routine for the FormatBufferDynamic template <> -inline void EventLogBase::print(outputStream* out, StringLogMessage& lm) { +inline void EventLogBase::print(outputStream* out, FormatBufferDynamic& lm) { out->print_raw(lm); out->cr(); } --- old/src/hotspot/share/utilities/formatBuffer.cpp 2018-05-01 09:30:58.964126137 +0900 +++ new/src/hotspot/share/utilities/formatBuffer.cpp 2018-05-01 09:30:58.493124385 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,3 +36,10 @@ jio_vsnprintf(_buf, FormatBufferBase::BufferSize, format, argp); va_end(argp); } + +FormatBufferDynamic::~FormatBufferDynamic() { + if (_buf != NULL) { + os::free(_buf); + } +} + --- old/src/hotspot/share/utilities/formatBuffer.hpp 2018-05-01 09:31:00.377131394 +0900 +++ new/src/hotspot/share/utilities/formatBuffer.hpp 2018-05-01 09:31:00.093130337 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,22 @@ FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); }; +// Use malloc() for buffer +class FormatBufferDynamic : public FormatBufferBase { + protected: + int bufsz; + + public: + inline FormatBufferDynamic(); + ~FormatBufferDynamic(); + inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); + inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); + + char* buffer() { return _buf; } + int size() { return bufsz; } +}; + class FormatBufferDummy {}; // Use stack for buffer @@ -69,6 +85,55 @@ inline FormatBuffer(); }; +FormatBufferDynamic::FormatBufferDynamic() : FormatBufferBase(NULL), bufsz(-1) { + // do nothing +} + +void FormatBufferDynamic::append(const char* format, ...) { + va_list argp; + + va_start(argp, format); + int append_len = jio_vsnprintf(NULL, 0, format, argp) + 1; + va_end(argp); + + char *append_str = (char *)os::malloc(append_len, mtInternal); + va_start(argp, format); + jio_vsnprintf(append_str, append_len, format, argp); + va_end(argp); + + if (_buf == NULL) { + bufsz = append_len; + _buf = append_str; + } else { + bufsz += append_len - 1; + _buf = (char *)os::realloc(_buf, bufsz, mtInternal); + strcat(_buf, append_str); + os::free(append_str); + } +} + +void FormatBufferDynamic::print(const char * format, ...) { + va_list argp; + va_start(argp, format); + printv(format, argp); + va_end(argp); +} + +void FormatBufferDynamic::printv(const char * format, va_list argp) { + if (_buf != NULL) { + os::free(_buf); + bufsz = -1; + } + + va_list argp_local; + va_copy(argp_local, argp); + bufsz = jio_vsnprintf(NULL, 0, format, argp_local) + 1; + va_end(argp_local); + + _buf = (char *)os::malloc(bufsz, mtInternal); + jio_vsnprintf(_buf, bufsz, format, argp); +} + template FormatBuffer::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) { va_list argp;