diff --git a/src/hotspot/share/services/memReporter.cpp b/src/hotspot/share/services/memReporter.cpp index 7aa7311fdf4..92dbb801e02 100644 --- a/src/hotspot/share/services/memReporter.cpp +++ b/src/hotspot/share/services/memReporter.cpp @@ -31,6 +31,16 @@ #include "services/virtualMemoryTracker.hpp" #include "utilities/globalDefinitions.hpp" +// Diff two counters, express them as signed, with range checks +static ssize_t counter_diff(size_t c1, size_t c2) { + assert(c1 <= SSIZE_MAX, "counter out of range: " SIZE_FORMAT ".", c1); + assert(c2 <= SSIZE_MAX, "counter out of range: " SIZE_FORMAT ".", c2); + if (c1 > SSIZE_MAX || c2 > SSIZE_MAX) { + return 0; + } + return c1 - c2; +} + size_t MemReporterBase::reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) { return malloc->malloc_size() + malloc->arena_size() + vm->reserved(); } @@ -462,8 +472,9 @@ void MemSummaryDiffReporter::print_malloc_diff(size_t current_amount, size_t cur } if (current_count > 0) { out->print(" #" SIZE_FORMAT "", current_count); - if (current_count != early_count) { - out->print(" %+d", (int)(current_count - early_count)); + const ssize_t delta_count = counter_diff(current_count, early_count); + if (delta_count != 0) { + out->print(" " SSIZE_PLUS_FORMAT, delta_count); } } } @@ -478,8 +489,9 @@ void MemSummaryDiffReporter::print_arena_diff(size_t current_amount, size_t curr } out->print(" #" SIZE_FORMAT "", current_count); - if (current_count != early_count) { - out->print(" %+d", (int)(current_count - early_count)); + const ssize_t delta_count = counter_diff(current_count, early_count); + if (delta_count != 0) { + out->print(" " SSIZE_PLUS_FORMAT, delta_count); } } @@ -551,30 +563,33 @@ void MemSummaryDiffReporter::diff_summary_of_type(MEMFLAGS flag, if (flag == mtClass) { // report class count out->print("%27s (classes #" SIZE_FORMAT "", " ", _current_baseline.class_count()); - int class_count_diff = (int)(_current_baseline.class_count() - - _early_baseline.class_count()); - if (_current_baseline.class_count() != _early_baseline.class_count()) { - out->print(" %+d", (int)(_current_baseline.class_count() - _early_baseline.class_count())); + const ssize_t class_count_diff = + counter_diff(_current_baseline.class_count(), _early_baseline.class_count()); + if (class_count_diff != 0) { + out->print(" " SSIZE_PLUS_FORMAT, class_count_diff); } out->print_cr(")"); out->print("%27s ( instance classes #" SIZE_FORMAT, " ", _current_baseline.instance_class_count()); - if (_current_baseline.instance_class_count() != _early_baseline.instance_class_count()) { - out->print(" %+d", (int)(_current_baseline.instance_class_count() - _early_baseline.instance_class_count())); + const ssize_t instance_class_count_diff = + counter_diff(_current_baseline.instance_class_count(), _early_baseline.instance_class_count()); + if (instance_class_count_diff != 0) { + out->print(" " SSIZE_PLUS_FORMAT, instance_class_count_diff); } out->print(", array classes #" SIZE_FORMAT, _current_baseline.array_class_count()); - if (_current_baseline.array_class_count() != _early_baseline.array_class_count()) { - out->print(" %+d", (int)(_current_baseline.array_class_count() - _early_baseline.array_class_count())); + const ssize_t array_class_count_diff = + counter_diff(_current_baseline.array_class_count(), _early_baseline.array_class_count()); + if (array_class_count_diff != 0) { + out->print(" " SSIZE_PLUS_FORMAT, array_class_count_diff); } out->print_cr(")"); } else if (flag == mtThread) { // report thread count out->print("%27s (thread #" SIZE_FORMAT "", " ", _current_baseline.thread_count()); - int thread_count_diff = (int)(_current_baseline.thread_count() - - _early_baseline.thread_count()); + const ssize_t thread_count_diff = counter_diff(_current_baseline.thread_count(), _early_baseline.thread_count()); if (thread_count_diff != 0) { - out->print(" %+d", thread_count_diff); + out->print(" " SSIZE_PLUS_FORMAT, thread_count_diff); } out->print_cr(")"); diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index 3771ac0f277..99eab62d2cf 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -130,6 +130,7 @@ class oopDesc; // Format integers which change size between 32- and 64-bit. #define SSIZE_FORMAT "%" PRIdPTR +#define SSIZE_PLUS_FORMAT "%+" PRIdPTR #define SSIZE_FORMAT_W(width) "%" #width PRIdPTR #define SIZE_FORMAT "%" PRIuPTR #define SIZE_FORMAT_X "0x%" PRIxPTR diff --git a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp index 2208953ee8b..9ea81ae7174 100644 --- a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp @@ -129,4 +129,14 @@ inline int g_isfinite(jdouble f) { return _finite(f); } #define USE_VECTORED_EXCEPTION_HANDLING #endif +#ifndef SSIZE_MAX +#ifdef _LP64 +#define SSIZE_MIN LLONG_MIN +#define SSIZE_MAX LLONG_MAX +#else +#define SSIZE_MIN INT_MIN +#define SSIZE_MAX INT_MAX +#endif +#endif // SSIZE_MAX missing + #endif // SHARE_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP diff --git a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp index ff18a1bd8f8..783bb6d326a 100644 --- a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp +++ b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp @@ -264,6 +264,13 @@ TEST(globalDefinitions, format_specifiers) { check_format(UINT64_FORMAT_W(-5), (uint64_t)123, "123 "); check_format(SSIZE_FORMAT, (ssize_t)123, "123"); + check_format(SSIZE_FORMAT, (ssize_t)-123, "-123"); + check_format(SSIZE_FORMAT, (ssize_t)2147483647, "2147483647"); + check_format(SSIZE_FORMAT, (ssize_t)-2147483647, "-2147483647"); + check_format(SSIZE_PLUS_FORMAT, (ssize_t)123, "+123"); + check_format(SSIZE_PLUS_FORMAT, (ssize_t)-123, "-123"); + check_format(SSIZE_PLUS_FORMAT, (ssize_t)2147483647, "+2147483647"); + check_format(SSIZE_PLUS_FORMAT, (ssize_t)-2147483647, "-2147483647"); check_format(SSIZE_FORMAT_W(5), (ssize_t)123, " 123"); check_format(SSIZE_FORMAT_W(-5), (ssize_t)123, "123 "); check_format(SIZE_FORMAT, (size_t)123u, "123");