8176298: Log tags in -Xlog:help not sorted
Reviewed-by: ecaspole, gtriantafill, stuefe
--- a/src/hotspot/share/logging/logConfiguration.cpp Fri Dec 08 13:47:08 2017 +0100
+++ b/src/hotspot/share/logging/logConfiguration.cpp Mon Feb 19 09:16:04 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -454,10 +454,7 @@
out->cr();
out->print("Available log tags:");
- for (size_t i = 1; i < LogTag::Count; i++) {
- out->print("%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast<LogTagType>(i)));
- }
- out->cr();
+ LogTag::list_tags(out);
LogTagSet::describe_tagsets(out);
}
@@ -494,13 +491,12 @@
}
jio_fprintf(out, "\n Decorators can also be specified as 'none' for no decoration.\n\n");
- jio_fprintf(out, "Available log tags:\n");
- for (size_t i = 1; i < LogTag::Count; i++) {
- jio_fprintf(out, "%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast<LogTagType>(i)));
- }
- jio_fprintf(out, "\n Specifying 'all' instead of a tag combination matches all tag combinations.\n\n");
+ fileStream stream(out, false);
+ stream.print_cr("Available log tags:");
+ LogTag::list_tags(&stream);
+ stream.print_cr(" Specifying 'all' instead of a tag combination matches all tag combinations.");
+ stream.cr();
- fileStream stream(out, false);
LogTagSet::describe_tagsets(&stream);
jio_fprintf(out, "\nAvailable log outputs:\n"
--- a/src/hotspot/share/logging/logTag.cpp Fri Dec 08 13:47:08 2017 +0100
+++ b/src/hotspot/share/logging/logTag.cpp Mon Feb 19 09:16:04 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "logging/logTag.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+#include "utilities/quickSort.hpp"
const char* LogTag::_name[] = {
"", // __NO_TAG
@@ -40,3 +42,29 @@
}
return __NO_TAG;
}
+
+static int cmp_logtag(LogTagType a, LogTagType b) {
+ return strcmp(LogTag::name(a), LogTag::name(b));
+}
+
+static const size_t sorted_tagcount = LogTag::Count - 1; // Not counting _NO_TAG
+static LogTagType sorted_tags[sorted_tagcount];
+
+class TagSorter {
+ public:
+ TagSorter() {
+ for (size_t i = 1; i < LogTag::Count; i++) {
+ sorted_tags[i - 1] = static_cast<LogTagType>(i);
+ }
+ QuickSort::sort(sorted_tags, sorted_tagcount, cmp_logtag, true);
+ }
+};
+
+static TagSorter tagsorter; // Sorts tags during static initialization
+
+void LogTag::list_tags(outputStream* out) {
+ for (size_t i = 0; i < sorted_tagcount; i++) {
+ out->print("%s %s", (i == 0 ? "" : ","), _name[sorted_tags[i]]);
+ }
+ out->cr();
+}
--- a/src/hotspot/share/logging/logTag.hpp Fri Dec 08 13:47:08 2017 +0100
+++ b/src/hotspot/share/logging/logTag.hpp Mon Feb 19 09:16:04 2018 +0100
@@ -192,6 +192,7 @@
}
static LogTag::type from_string(const char *str);
+ static void list_tags(outputStream* out);
private:
static const char* _name[];
--- a/test/hotspot/gtest/logging/test_logTag.cpp Fri Dec 08 13:47:08 2017 +0100
+++ b/test/hotspot/gtest/logging/test_logTag.cpp Mon Feb 19 09:16:04 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -23,6 +23,7 @@
#include "precompiled.hpp"
#include "logging/logTag.hpp"
+#include "utilities/ostream.hpp"
#include "unittest.hpp"
TEST(LogTag, from_string) {
@@ -51,3 +52,31 @@
LOG_TAG_LIST
#undef LOG_TAG
}
+
+TEST(LogTag, list_tags) {
+ char buf[LogTag::Count * 16] = {0};
+ stringStream ss(buf, sizeof(buf));
+ LogTag::list_tags(&ss);
+
+ bool listed_tags[LogTag::Count] = { false };
+
+ char* last_tag = NULL;
+ for (char* tag = buf; *tag != '\0';) {
+ char* end = strpbrk(tag, ",\n");
+ ASSERT_TRUE(end != NULL) << "line should end with newline";
+ *end = '\0';
+ if (*tag == ' ') {
+ tag++;
+ }
+
+ EXPECT_TRUE(last_tag == NULL || strcmp(last_tag, tag) < 0) << tag << " should be listed before " << last_tag;
+ listed_tags[LogTag::from_string(tag)] = true;
+
+ last_tag = tag;
+ tag = end + 1;
+ }
+
+ for (size_t i = 1; i < LogTag::Count; i++) {
+ EXPECT_TRUE(listed_tags[i]) << "tag '" << LogTag::name(static_cast<LogTagType>(i)) << "' not listed!";
+ }
+}