changeset 8972:1a1aec8c87b7

8217315: Proper units should print more significant digits Reviewed-by: stuefe, tschatzl
author shade
date Fri, 18 Jan 2019 17:05:41 +0100
parents 4fdf42cda0d5
children acb9351e3a29
files src/share/vm/prims/jni.cpp src/share/vm/utilities/globalDefinitions.cpp src/share/vm/utilities/globalDefinitions.hpp
diffstat 3 files changed, 76 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/prims/jni.cpp	Thu May 02 17:12:38 2019 +0100
+++ b/src/share/vm/prims/jni.cpp	Fri Jan 18 17:05:41 2019 +0100
@@ -5121,6 +5121,7 @@
     run_unit_test(TestMetachunk_test());
     run_unit_test(TestVirtualSpaceNode_test());
     run_unit_test(GlobalDefinitions::test_globals());
+    run_unit_test(GlobalDefinitions::test_proper_unit());
     run_unit_test(GCTimerAllTest::all());
     run_unit_test(arrayOopDesc::test_max_array_length());
     run_unit_test(CollectedHeap::test_is_in());
--- a/src/share/vm/utilities/globalDefinitions.cpp	Thu May 02 17:12:38 2019 +0100
+++ b/src/share/vm/utilities/globalDefinitions.cpp	Fri Jan 18 17:05:41 2019 +0100
@@ -384,4 +384,67 @@
   }
 }
 
+#define EXPECT_EQ(expected, actual) \
+        assert(expected == actual, "Test failed");
+#define EXPECT_STREQ(expected, actual) \
+        assert(strcmp(expected, actual) == 0, "Test failed");
+
+void GlobalDefinitions::test_proper_unit() {
+  EXPECT_EQ(0u,     byte_size_in_proper_unit(0u));
+  EXPECT_STREQ("B", proper_unit_for_byte_size(0u));
+
+  EXPECT_EQ(1u,     byte_size_in_proper_unit(1u));
+  EXPECT_STREQ("B", proper_unit_for_byte_size(1u));
+
+  EXPECT_EQ(1023u,  byte_size_in_proper_unit(K - 1));
+  EXPECT_STREQ("B", proper_unit_for_byte_size(K - 1));
+
+  EXPECT_EQ(1024u,  byte_size_in_proper_unit(K));
+  EXPECT_STREQ("B", proper_unit_for_byte_size(K));
+
+  EXPECT_EQ(1025u,  byte_size_in_proper_unit(K + 1));
+  EXPECT_STREQ("B", proper_unit_for_byte_size(K + 1));
+
+  EXPECT_EQ(51200u, byte_size_in_proper_unit(50*K));
+  EXPECT_STREQ("B", proper_unit_for_byte_size(50*K));
+
+  EXPECT_EQ(1023u,  byte_size_in_proper_unit(M - 1));
+  EXPECT_STREQ("K", proper_unit_for_byte_size(M - 1));
+
+  EXPECT_EQ(1024u,  byte_size_in_proper_unit(M));
+  EXPECT_STREQ("K", proper_unit_for_byte_size(M));
+
+  EXPECT_EQ(1024u,  byte_size_in_proper_unit(M + 1));
+  EXPECT_STREQ("K", proper_unit_for_byte_size(M + 1));
+
+  EXPECT_EQ(1025u,  byte_size_in_proper_unit(M + K));
+  EXPECT_STREQ("K", proper_unit_for_byte_size(M + K));
+
+  EXPECT_EQ(51200u, byte_size_in_proper_unit(50*M));
+  EXPECT_STREQ("K", proper_unit_for_byte_size(50*M));
+
+#ifdef _LP64
+  EXPECT_EQ(1023u,  byte_size_in_proper_unit(G - 1));
+  EXPECT_STREQ("M", proper_unit_for_byte_size(G - 1));
+
+  EXPECT_EQ(1024u,  byte_size_in_proper_unit(G));
+  EXPECT_STREQ("M", proper_unit_for_byte_size(G));
+
+  EXPECT_EQ(1024u,  byte_size_in_proper_unit(G + 1));
+  EXPECT_STREQ("M", proper_unit_for_byte_size(G + 1));
+
+  EXPECT_EQ(1024u,  byte_size_in_proper_unit(G + K));
+  EXPECT_STREQ("M", proper_unit_for_byte_size(G + K));
+
+  EXPECT_EQ(1025u,  byte_size_in_proper_unit(G + M));
+  EXPECT_STREQ("M", proper_unit_for_byte_size(G + M));
+
+  EXPECT_EQ(51200u, byte_size_in_proper_unit(50*G));
+  EXPECT_STREQ("M", proper_unit_for_byte_size(50*G));
+#endif
+}
+
+#undef EXPECT_EQ
+#undef EXPECT_STREQ
+
 #endif // PRODUCT
--- a/src/share/vm/utilities/globalDefinitions.hpp	Thu May 02 17:12:38 2019 +0100
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Fri Jan 18 17:05:41 2019 +0100
@@ -211,15 +211,20 @@
 const jlong NANOSECS_PER_SEC      = CONST64(1000000000);
 const jint  NANOSECS_PER_MILLISEC = 1000000;
 
+// Proper units routines try to maintain at least three significant digits.
+// In worst case, it would print five significant digits with lower prefix.
+// G is close to MAX_SIZE on 32-bit platforms, so its product can easily overflow,
+// and therefore we need to be careful.
+
 inline const char* proper_unit_for_byte_size(size_t s) {
 #ifdef _LP64
-  if (s >= 10*G) {
+  if (s >= 100*G) {
     return "G";
   }
 #endif
-  if (s >= 10*M) {
+  if (s >= 100*M) {
     return "M";
-  } else if (s >= 10*K) {
+  } else if (s >= 100*K) {
     return "K";
   } else {
     return "B";
@@ -229,13 +234,13 @@
 template <class T>
 inline T byte_size_in_proper_unit(T s) {
 #ifdef _LP64
-  if (s >= 10*G) {
+  if (s >= 100*G) {
     return (T)(s/G);
   }
 #endif
-  if (s >= 10*M) {
+  if (s >= 100*M) {
     return (T)(s/M);
-  } else if (s >= 10*K) {
+  } else if (s >= 100*K) {
     return (T)(s/K);
   } else {
     return s;
@@ -1486,6 +1491,7 @@
 class GlobalDefinitions {
 public:
   static void test_globals();
+  static void test_proper_unit();
 };
 
 #endif // PRODUCT