--- old/src/hotspot/share/logging/logMessageBuffer.cpp 2020-02-24 07:47:42.345092930 +0000 +++ new/src/hotspot/share/logging/logMessageBuffer.cpp 2020-02-24 07:47:42.085091509 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, 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 @@ -26,17 +26,9 @@ #include "memory/allocation.inline.hpp" #include "runtime/thread.inline.hpp" -template -static void grow(T*& buffer, size_t& capacity, size_t minimum_length = 0) { - size_t new_size = capacity * 2; - if (new_size < minimum_length) { - new_size = minimum_length; - } - buffer = REALLOC_C_HEAP_ARRAY(T, buffer, new_size, mtLogging); - capacity = new_size; -} -LogMessageBuffer::LogMessageBuffer() : _message_buffer_size(0), +LogMessageBuffer::LogMessageBuffer(Arena* arena) : _arena(arena), + _message_buffer_size(0), _message_buffer_capacity(0), _message_buffer(NULL), _line_count(0), @@ -49,8 +41,13 @@ LogMessageBuffer::~LogMessageBuffer() { if (_allocated) { - FREE_C_HEAP_ARRAY(char, _message_buffer); - FREE_C_HEAP_ARRAY(LogLine, _lines); + if (!_arena) { + FREE_C_HEAP_ARRAY(char, _message_buffer); + FREE_C_HEAP_ARRAY(LogLine, _lines); + } else { + FREE_ARENA_ARRAY(_arena, char, _message_buffer, _message_buffer_capacity); + FREE_ARENA_ARRAY(_arena, LogLine, _lines, _line_capacity); + } } } @@ -61,13 +58,40 @@ void LogMessageBuffer::initialize_buffers() { assert(!_allocated, "buffer already initialized/allocated"); + if (!_arena) { + _message_buffer = NEW_C_HEAP_ARRAY(char, InitialMessageBufferCapacity, mtLogging); + _lines = NEW_C_HEAP_ARRAY(LogLine, InitialLineCapacity, mtLogging); + } + else { + _message_buffer = NEW_ARENA_ARRAY(_arena, char, InitialMessageBufferCapacity); + _lines = NEW_ARENA_ARRAY(_arena, LogLine, InitialLineCapacity); + } + _allocated = true; - _message_buffer = NEW_C_HEAP_ARRAY(char, InitialMessageBufferCapacity, mtLogging); - _lines = NEW_C_HEAP_ARRAY(LogLine, InitialLineCapacity, mtLogging); _message_buffer_capacity = InitialMessageBufferCapacity; _line_capacity = InitialLineCapacity; } +size_t LogMessageBuffer::initial_buffer_size() { + return sizeof(char) * InitialMessageBufferCapacity + + sizeof(LogLine) * InitialLineCapacity; +} + +template +void LogMessageBuffer::grow(T*& buffer, size_t& capacity, size_t minimum_length) { + size_t new_size = capacity * 2; + if (new_size < minimum_length) { + new_size = minimum_length; + } + if (!_arena) { + buffer = REALLOC_C_HEAP_ARRAY(T, buffer, new_size, mtLogging); + } + else { + buffer = REALLOC_ARENA_ARRAY(_arena, T, buffer, capacity, new_size); + } + capacity = new_size; +} + void LogMessageBuffer::Iterator::skip_messages_with_finer_level() { for (; _current_line_index < _message._line_count; _current_line_index++) { if (_message._lines[_current_line_index].level >= _level) { @@ -76,6 +100,46 @@ } } +void LogMessageBuffer::write_n(LogLevelType level, const char * s, size_t len) { + if (!_allocated) { + initialize_buffers(); + } + + if (level > _least_detailed_level) { + _least_detailed_level = level; + } + + size_t written; + for (int attempts = 0; attempts < 2; attempts++) { + written = 0; + size_t remain = _message_buffer_capacity - _message_buffer_size; + char* curr = _message_buffer + _message_buffer_size; + + if (_prefix_fn != NULL) { + written += _prefix_fn(curr, remain); + } + curr += written; + + written += len + 1; // add tailing zero + if (written > remain) { + grow(_message_buffer, _message_buffer_capacity, _message_buffer_size + written); + continue; + } + + strncpy(curr, s, len); + curr[len] = '\0'; + break; + } + + if (_line_count == _line_capacity) { + grow(_lines, _line_capacity); + } + _lines[_line_count].level = level; + _lines[_line_count].message_offset = _message_buffer_size; + _message_buffer_size += written; + _line_count++; +} + void LogMessageBuffer::write(LogLevelType level, const char* fmt, ...) { va_list args; va_start(args, fmt);