Skip to content

Commit 26410c1

Browse files
afshin-zafariEvgeny Astigeevich
authored and
Evgeny Astigeevich
committed
8281213: Unsafe uses of long and size_t in MemReporterBase::diff_in_current_scale
Reviewed-by: eastigeevich, kbarrett
1 parent eca6479 commit 26410c1

File tree

3 files changed

+48
-21
lines changed

3 files changed

+48
-21
lines changed

src/hotspot/share/services/memReporter.cpp

+15-15
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,9 @@ void MemSummaryDiffReporter::print_malloc_diff(size_t current_amount, size_t cur
474474
out->print(" type=%s", NMTUtil::flag_to_name(flags));
475475
}
476476

477-
long amount_diff = diff_in_current_scale(current_amount, early_amount);
477+
int64_t amount_diff = diff_in_current_scale(current_amount, early_amount);
478478
if (amount_diff != 0) {
479-
out->print(" %+ld%s", amount_diff, scale);
479+
out->print(" " INT64_PLUS_FORMAT "%s", amount_diff, scale);
480480
}
481481
if (current_count > 0) {
482482
out->print(" #" SIZE_FORMAT "", current_count);
@@ -493,7 +493,7 @@ void MemSummaryDiffReporter::print_arena_diff(size_t current_amount, size_t curr
493493
outputStream* out = output();
494494
out->print("arena=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale);
495495
if (diff_in_current_scale(current_amount, early_amount) != 0) {
496-
out->print(" %+ld", diff_in_current_scale(current_amount, early_amount));
496+
out->print(" " INT64_PLUS_FORMAT "d", diff_in_current_scale(current_amount, early_amount));
497497
}
498498

499499
out->print(" #" SIZE_FORMAT "", current_count);
@@ -508,15 +508,15 @@ void MemSummaryDiffReporter::print_virtual_memory_diff(size_t current_reserved,
508508
const char* scale = current_scale();
509509
outputStream* out = output();
510510
out->print("reserved=" SIZE_FORMAT "%s", amount_in_current_scale(current_reserved), scale);
511-
long reserved_diff = diff_in_current_scale(current_reserved, early_reserved);
511+
int64_t reserved_diff = diff_in_current_scale(current_reserved, early_reserved);
512512
if (reserved_diff != 0) {
513-
out->print(" %+ld%s", reserved_diff, scale);
513+
out->print(" " INT64_PLUS_FORMAT "%s", reserved_diff, scale);
514514
}
515515

516516
out->print(", committed=" SIZE_FORMAT "%s", amount_in_current_scale(current_committed), scale);
517-
long committed_diff = diff_in_current_scale(current_committed, early_committed);
517+
int64_t committed_diff = diff_in_current_scale(current_committed, early_committed);
518518
if (committed_diff != 0) {
519-
out->print(" %+ld%s", committed_diff, scale);
519+
out->print(" " INT64_PLUS_FORMAT "%s", committed_diff, scale);
520520
}
521521
}
522522

@@ -660,10 +660,10 @@ void MemSummaryDiffReporter::diff_summary_of_type(MEMFLAGS flag,
660660
out->print("%27s (tracking overhead=" SIZE_FORMAT "%s", " ",
661661
amount_in_current_scale(_current_baseline.malloc_tracking_overhead()), scale);
662662

663-
long overhead_diff = diff_in_current_scale(_current_baseline.malloc_tracking_overhead(),
664-
_early_baseline.malloc_tracking_overhead());
663+
int64_t overhead_diff = diff_in_current_scale(_current_baseline.malloc_tracking_overhead(),
664+
_early_baseline.malloc_tracking_overhead());
665665
if (overhead_diff != 0) {
666-
out->print(" %+ld%s", overhead_diff, scale);
666+
out->print(" " INT64_PLUS_FORMAT "%s", overhead_diff, scale);
667667
}
668668
out->print_cr(")");
669669
} else if (flag == mtClass) {
@@ -695,18 +695,18 @@ void MemSummaryDiffReporter::print_metaspace_diff(const char* header,
695695
early_stats.committed());
696696
out->print_cr(")");
697697

698-
long diff_used = diff_in_current_scale(current_stats.used(),
699-
early_stats.used());
698+
int64_t diff_used = diff_in_current_scale(current_stats.used(),
699+
early_stats.used());
700700

701701
size_t current_waste = current_stats.committed() - current_stats.used();
702702
size_t early_waste = early_stats.committed() - early_stats.used();
703-
long diff_waste = diff_in_current_scale(current_waste, early_waste);
703+
int64_t diff_waste = diff_in_current_scale(current_waste, early_waste);
704704

705705
// Diff used
706706
out->print("%27s ( used=" SIZE_FORMAT "%s", " ",
707707
amount_in_current_scale(current_stats.used()), scale);
708708
if (diff_used != 0) {
709-
out->print(" %+ld%s", diff_used, scale);
709+
out->print(" " INT64_PLUS_FORMAT "%s", diff_used, scale);
710710
}
711711
out->print_cr(")");
712712

@@ -716,7 +716,7 @@ void MemSummaryDiffReporter::print_metaspace_diff(const char* header,
716716
out->print("%27s ( waste=" SIZE_FORMAT "%s =%2.2f%%", " ",
717717
amount_in_current_scale(current_waste), scale, waste_percentage);
718718
if (diff_waste != 0) {
719-
out->print(" %+ld%s", diff_waste, scale);
719+
out->print(" " INT64_PLUS_FORMAT "%s", diff_waste, scale);
720720
}
721721
out->print_cr(")");
722722
}

src/hotspot/share/services/memReporter.hpp

+32-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -71,11 +71,37 @@ class MemReporterBase : public StackObj {
7171
}
7272

7373
// Convert diff amount in bytes to current reporting scale
74-
inline long diff_in_current_scale(size_t s1, size_t s2) const {
75-
long amount = (long)(s1 - s2);
76-
long scale = (long)_scale;
77-
amount = (amount > 0) ? (amount + scale / 2) : (amount - scale / 2);
78-
return amount / scale;
74+
// We use int64_t instead of ssize_t because on 32-bit it allows us to express deltas larger than 2 gb.
75+
// On 64-bit we never expect memory sizes larger than INT64_MAX.
76+
int64_t diff_in_current_scale(size_t s1, size_t s2) const {
77+
assert(_scale != 0, "wrong scale");
78+
79+
assert(s1 < INT64_MAX, "exceeded possible memory limits");
80+
assert(s2 < INT64_MAX, "exceeded possible memory limits");
81+
82+
bool is_negative = false;
83+
if (s1 < s2) {
84+
is_negative = true;
85+
swap(s1, s2);
86+
}
87+
88+
size_t amount = s1 - s2;
89+
// We can split amount into p + q, where
90+
// q = amount % _scale
91+
// and p = amount - q (which is also (amount / _scale) * _scale).
92+
// Then use
93+
// size_t scaled = (p + q + _scale/2) / _scale;
94+
// =>
95+
// size_t scaled = (p / _scale) + ((q + _scale/2) / _scale);
96+
// The lefthand side of the addition is exact.
97+
// The righthand side is 0 if q <= (_scale - 1)/2, else 1. (The -1 is to account for odd _scale values.)
98+
size_t scaled = (amount / _scale);
99+
if ((amount % _scale) > (_scale - 1)/2) {
100+
scaled += 1;
101+
}
102+
103+
int64_t result = static_cast<int64_t>(scaled);
104+
return is_negative ? -result : result;
79105
}
80106

81107
// Print summary total, malloc and virtual memory

src/hotspot/share/utilities/globalDefinitions.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class oopDesc;
121121

122122
// Format 64-bit quantities.
123123
#define INT64_FORMAT "%" PRId64
124+
#define INT64_PLUS_FORMAT "%+" PRId64
124125
#define INT64_FORMAT_X "0x%" PRIx64
125126
#define INT64_FORMAT_X_0 "0x%016" PRIx64
126127
#define INT64_FORMAT_W(width) "%" #width PRId64

0 commit comments

Comments
 (0)