Skip to content

Commit f94a845

Browse files
committed
8261600: NMT: Relax memory order for updating MemoryCounter and fix racy updating of peak values
Reviewed-by: dholmes, shade
1 parent 1a7adc8 commit f94a845

File tree

2 files changed

+53
-19
lines changed

2 files changed

+53
-19
lines changed

src/hotspot/share/services/mallocTracker.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2021, 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
@@ -30,6 +30,36 @@
3030

3131
size_t MallocMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)];
3232

33+
#ifdef ASSERT
34+
void MemoryCounter::update_peak_count(size_t count) {
35+
size_t peak_cnt = peak_count();
36+
while (peak_cnt < count) {
37+
size_t old_cnt = Atomic::cmpxchg(&_peak_count, peak_cnt, count, memory_order_relaxed);
38+
if (old_cnt != peak_cnt) {
39+
peak_cnt = old_cnt;
40+
}
41+
}
42+
}
43+
44+
void MemoryCounter::update_peak_size(size_t sz) {
45+
size_t peak_sz = peak_size();
46+
while (peak_sz < sz) {
47+
size_t old_sz = Atomic::cmpxchg(&_peak_size, peak_sz, sz, memory_order_relaxed);
48+
if (old_sz != peak_sz) {
49+
peak_sz = old_sz;
50+
}
51+
}
52+
}
53+
54+
size_t MemoryCounter::peak_count() const {
55+
return Atomic::load(&_peak_count);
56+
}
57+
58+
size_t MemoryCounter::peak_size() const {
59+
return Atomic::load(&_peak_size);
60+
}
61+
#endif
62+
3363
// Total malloc'd memory amount
3464
size_t MallocMemorySnapshot::total() const {
3565
size_t amount = 0;

src/hotspot/share/services/mallocTracker.hpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2021, 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
@@ -43,8 +43,8 @@ class MemoryCounter {
4343
volatile size_t _count;
4444
volatile size_t _size;
4545

46-
DEBUG_ONLY(size_t _peak_count;)
47-
DEBUG_ONLY(size_t _peak_size; )
46+
DEBUG_ONLY(volatile size_t _peak_count;)
47+
DEBUG_ONLY(volatile size_t _peak_size; )
4848

4949
public:
5050
MemoryCounter() : _count(0), _size(0) {
@@ -53,36 +53,40 @@ class MemoryCounter {
5353
}
5454

5555
inline void allocate(size_t sz) {
56-
Atomic::inc(&_count);
56+
size_t cnt = Atomic::add(&_count, size_t(1), memory_order_relaxed);
5757
if (sz > 0) {
58-
Atomic::add(&_size, sz);
59-
DEBUG_ONLY(_peak_size = MAX2(_peak_size, _size));
58+
size_t sum = Atomic::add(&_size, sz, memory_order_relaxed);
59+
DEBUG_ONLY(update_peak_size(sum);)
6060
}
61-
DEBUG_ONLY(_peak_count = MAX2(_peak_count, _count);)
61+
DEBUG_ONLY(update_peak_count(cnt);)
6262
}
6363

6464
inline void deallocate(size_t sz) {
65-
assert(_count > 0, "Nothing allocated yet");
66-
assert(_size >= sz, "deallocation > allocated");
67-
Atomic::dec(&_count);
65+
assert(count() > 0, "Nothing allocated yet");
66+
assert(size() >= sz, "deallocation > allocated");
67+
Atomic::dec(&_count, memory_order_relaxed);
6868
if (sz > 0) {
69-
Atomic::sub(&_size, sz);
69+
Atomic::sub(&_size, sz, memory_order_relaxed);
7070
}
7171
}
7272

7373
inline void resize(ssize_t sz) {
7474
if (sz != 0) {
75-
assert(sz >= 0 || _size >= size_t(-sz), "Must be");
76-
Atomic::add(&_size, size_t(sz));
77-
DEBUG_ONLY(_peak_size = MAX2(_size, _peak_size);)
75+
assert(sz >= 0 || size() >= size_t(-sz), "Must be");
76+
size_t sum = Atomic::add(&_size, size_t(sz), memory_order_relaxed);
77+
DEBUG_ONLY(update_peak_size(sum);)
7878
}
7979
}
8080

81-
inline size_t count() const { return _count; }
82-
inline size_t size() const { return _size; }
83-
DEBUG_ONLY(inline size_t peak_count() const { return _peak_count; })
84-
DEBUG_ONLY(inline size_t peak_size() const { return _peak_size; })
81+
inline size_t count() const { return Atomic::load(&_count); }
82+
inline size_t size() const { return Atomic::load(&_size); }
8583

84+
#ifdef ASSERT
85+
void update_peak_count(size_t cnt);
86+
void update_peak_size(size_t sz);
87+
size_t peak_count() const;
88+
size_t peak_size() const;
89+
#endif // ASSERT
8690
};
8791

8892
/*

0 commit comments

Comments
 (0)