8255756: Disabling logging does unnecessary work

Reviewed-by: iklam
This commit is contained in:
Claes Redestad 2020-11-05 21:20:13 +00:00
parent 140c162a0d
commit e66fd6f0aa
5 changed files with 46 additions and 18 deletions

View File

@ -110,9 +110,7 @@ void LogConfiguration::initialize(jlong vm_start_time) {
}
void LogConfiguration::finalize() {
for (size_t i = _n_outputs; i > 0; i--) {
disable_output(i - 1);
}
disable_outputs();
FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
}
@ -272,28 +270,31 @@ void LogConfiguration::configure_output(size_t idx, const LogSelectionList& sele
assert(strlen(output->config_string()) > 0, "should always have a config description");
}
void LogConfiguration::disable_output(size_t idx) {
assert(idx < _n_outputs, "invalid index: " SIZE_FORMAT " (_n_outputs: " SIZE_FORMAT ")", idx, _n_outputs);
LogOutput* out = _outputs[idx];
void LogConfiguration::disable_outputs() {
size_t idx = _n_outputs;
// Remove the output from all tagsets.
// Remove all outputs from all tagsets.
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
ts->set_output_level(out, LogLevel::Off);
ts->update_decorators();
ts->disable_outputs();
}
// Delete the output unless stdout or stderr (idx 0 or 1)
if (idx > 1) {
delete_output(idx);
} else {
out->set_config_string("all=off");
while (idx > 0) {
LogOutput* out = _outputs[--idx];
// Delete the output unless stdout or stderr (idx 0 or 1)
if (idx > 1) {
delete_output(idx);
} else {
out->set_config_string("all=off");
}
}
}
void LogConfiguration::disable_logging() {
ConfigurationLock cl;
for (size_t i = _n_outputs; i > 0; i--) {
disable_output(i - 1);
disable_outputs();
// Update the decorators on all tagsets to get rid of unused decorators
for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
ts->update_decorators();
}
notify_update_listeners();
}

View File

@ -69,8 +69,8 @@ class LogConfiguration : public AllStatic {
// Output should be completely disabled before it is deleted.
static void delete_output(size_t idx);
// Disable all logging to the specified output and then delete it (unless it is stdout/stderr).
static void disable_output(size_t idx);
// Disable all logging to all outputs. All outputs except stdout/stderr will be deleted.
static void disable_outputs();
// Get output index by name. Returns SIZE_MAX if output not found.
static size_t find_output(const char* name);

View File

@ -68,6 +68,25 @@ LogOutputList::LogOutputNode* LogOutputList::find(const LogOutput* output) const
return NULL;
}
void LogOutputList::clear() {
// Grab the linked list
LogOutputNode* cur = _level_start[LogLevel::Last];
// Clear _level_start
for (uint level = LogLevel::First; level < LogLevel::Count; level++) {
_level_start[level] = NULL;
}
// Delete all nodes from the linked list
wait_until_no_readers();
while (cur != NULL) {
LogOutputNode* next = cur->_next;
delete cur;
cur = next;
}
}
void LogOutputList::remove_output(LogOutputList::LogOutputNode* node) {
assert(node != NULL, "Node must be non-null");

View File

@ -88,6 +88,10 @@ class LogOutputList {
// Set (add/update/remove) the output to the specified level.
void set_output_level(LogOutput* output, LogLevelType level);
// Removes all outputs. Equivalent of set_output_level(out, Off)
// for all outputs.
void clear();
class Iterator {
friend class LogOutputList;
private:

View File

@ -98,6 +98,10 @@ class LogTagSet {
return _output_list.level_for(output);
}
void disable_outputs() {
_output_list.clear();
}
void set_output_level(LogOutput* output, LogLevelType level) {
_output_list.set_output_level(output, level);
}