8176298: Log tags in -Xlog:help not sorted
authormlarsson
Mon, 19 Feb 2018 09:16:04 +0100
changeset 49015 a12c9536d8a6
parent 49014 407a8495d4b3
child 49016 ea85eed8b012
8176298: Log tags in -Xlog:help not sorted Reviewed-by: ecaspole, gtriantafill, stuefe
src/hotspot/share/logging/logConfiguration.cpp
src/hotspot/share/logging/logTag.cpp
src/hotspot/share/logging/logTag.hpp
test/hotspot/gtest/logging/test_logTag.cpp
--- 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!";
+  }
+}