Skip to content

Commit e16c510

Browse files
committed
8367231: [BACKOUT] JDK-8366363: MemBaseline accesses VMT without using lock
Reviewed-by: kbarrett, dholmes
1 parent 67bb22f commit e16c510

File tree

12 files changed

+65
-185
lines changed

12 files changed

+65
-185
lines changed

src/hotspot/share/nmt/memBaseline.cpp

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
#include "memory/metaspaceUtils.hpp"
2828
#include "nmt/memBaseline.hpp"
2929
#include "nmt/memTracker.hpp"
30-
#include "nmt/regionsTree.inline.hpp"
30+
#include "runtime/javaThread.hpp"
31+
#include "runtime/safepoint.hpp"
3132

3233
/*
3334
* Sizes are sorted in descenting order for reporting
@@ -103,6 +104,38 @@ class MallocAllocationSiteWalker : public MallocSiteWalker {
103104
}
104105
};
105106

107+
// Walk all virtual memory regions for baselining
108+
class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {
109+
private:
110+
typedef LinkedListImpl<ReservedMemoryRegion, AnyObj::C_HEAP, mtNMT,
111+
AllocFailStrategy::RETURN_NULL> EntryList;
112+
EntryList _virtual_memory_regions;
113+
DEBUG_ONLY(address _last_base;)
114+
public:
115+
VirtualMemoryAllocationWalker() {
116+
DEBUG_ONLY(_last_base = nullptr);
117+
}
118+
119+
bool do_allocation_site(const ReservedMemoryRegion* rgn) {
120+
assert(rgn->base() >= _last_base, "region unordered?");
121+
DEBUG_ONLY(_last_base = rgn->base());
122+
if (rgn->size() > 0) {
123+
if (_virtual_memory_regions.add(*rgn) != nullptr) {
124+
return true;
125+
} else {
126+
return false;
127+
}
128+
} else {
129+
// Ignore empty sites.
130+
return true;
131+
}
132+
}
133+
134+
LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() {
135+
return &_virtual_memory_regions;
136+
}
137+
};
138+
106139
void MemBaseline::baseline_summary() {
107140
MallocMemorySummary::snapshot(&_malloc_memory_snapshot);
108141
VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);
@@ -125,16 +158,15 @@ bool MemBaseline::baseline_allocation_sites() {
125158
// The malloc sites are collected in size order
126159
_malloc_sites_order = by_size;
127160

128-
assert(_vma_allocations == nullptr, "must");
129-
130-
{
131-
MemTracker::NmtVirtualMemoryLocker locker;
132-
_vma_allocations = new (mtNMT, std::nothrow) RegionsTree(*VirtualMemoryTracker::Instance::tree());
133-
if (_vma_allocations == nullptr) {
134-
return false;
135-
}
161+
// Virtual memory allocation sites
162+
VirtualMemoryAllocationWalker virtual_memory_walker;
163+
if (!VirtualMemoryTracker::Instance::walk_virtual_memory(&virtual_memory_walker)) {
164+
return false;
136165
}
137166

167+
// Virtual memory allocations are collected in call stack order
168+
_virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations());
169+
138170
if (!aggregate_virtual_memory_allocation_sites()) {
139171
return false;
140172
}
@@ -170,28 +202,20 @@ int compare_allocation_site(const VirtualMemoryAllocationSite& s1,
170202
bool MemBaseline::aggregate_virtual_memory_allocation_sites() {
171203
SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites;
172204

205+
VirtualMemoryAllocationIterator itr = virtual_memory_allocations();
206+
const ReservedMemoryRegion* rgn;
173207
VirtualMemoryAllocationSite* site;
174-
bool failed_oom = false;
175-
_vma_allocations->visit_reserved_regions([&](ReservedMemoryRegion& rgn) {
176-
VirtualMemoryAllocationSite tmp(*rgn.call_stack(), rgn.mem_tag());
208+
while ((rgn = itr.next()) != nullptr) {
209+
VirtualMemoryAllocationSite tmp(*rgn->call_stack(), rgn->mem_tag());
177210
site = allocation_sites.find(tmp);
178211
if (site == nullptr) {
179212
LinkedListNode<VirtualMemoryAllocationSite>* node =
180213
allocation_sites.add(tmp);
181-
if (node == nullptr) {
182-
failed_oom = true;
183-
return false;
184-
}
214+
if (node == nullptr) return false;
185215
site = node->data();
186216
}
187-
site->reserve_memory(rgn.size());
188-
189-
site->commit_memory(_vma_allocations->committed_size(rgn));
190-
return true;
191-
});
192-
193-
if (failed_oom) {
194-
return false;
217+
site->reserve_memory(rgn->size());
218+
site->commit_memory(VirtualMemoryTracker::Instance::committed_size(rgn));
195219
}
196220

197221
_virtual_memory_sites.move(&allocation_sites);

src/hotspot/share/nmt/memBaseline.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
typedef LinkedListIterator<MallocSite> MallocSiteIterator;
3737
typedef LinkedListIterator<VirtualMemoryAllocationSite> VirtualMemorySiteIterator;
38+
typedef LinkedListIterator<ReservedMemoryRegion> VirtualMemoryAllocationIterator;
3839

3940
/*
4041
* Baseline a memory snapshot
@@ -70,7 +71,7 @@ class MemBaseline {
7071
LinkedListImpl<MallocSite> _malloc_sites;
7172

7273
// All virtual memory allocations
73-
RegionsTree* _vma_allocations;
74+
LinkedListImpl<ReservedMemoryRegion> _virtual_memory_allocations;
7475

7576
// Virtual memory allocations by allocation sites, always in by_address
7677
// order
@@ -85,7 +86,6 @@ class MemBaseline {
8586
// create a memory baseline
8687
MemBaseline():
8788
_instance_class_count(0), _array_class_count(0), _thread_count(0),
88-
_vma_allocations(nullptr),
8989
_baseline_type(Not_baselined) {
9090
}
9191

@@ -110,9 +110,9 @@ class MemBaseline {
110110

111111
// Virtual memory allocation iterator always returns in virtual memory
112112
// base address order.
113-
RegionsTree* virtual_memory_allocations() {
114-
assert(_vma_allocations != nullptr, "Not detail baseline");
115-
return _vma_allocations;
113+
VirtualMemoryAllocationIterator virtual_memory_allocations() {
114+
assert(!_virtual_memory_allocations.is_empty(), "Not detail baseline");
115+
return VirtualMemoryAllocationIterator(_virtual_memory_allocations.head());
116116
}
117117

118118
// Total reserved memory = total malloc'd memory + total reserved virtual
@@ -185,8 +185,7 @@ class MemBaseline {
185185

186186
_malloc_sites.clear();
187187
_virtual_memory_sites.clear();
188-
delete _vma_allocations;
189-
_vma_allocations = nullptr;
188+
_virtual_memory_allocations.clear();
190189
}
191190

192191
private:

src/hotspot/share/nmt/memReporter.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,11 +394,13 @@ int MemDetailReporter::report_virtual_memory_allocation_sites() {
394394

395395
void MemDetailReporter::report_virtual_memory_map() {
396396
// Virtual memory map always in base address order
397+
VirtualMemoryAllocationIterator itr = _baseline.virtual_memory_allocations();
398+
const ReservedMemoryRegion* rgn;
399+
397400
output()->print_cr("Virtual memory map:");
398-
_baseline.virtual_memory_allocations()->visit_reserved_regions([&](ReservedMemoryRegion& rgn) {
399-
report_virtual_memory_region(&rgn);
400-
return true;
401-
});
401+
while ((rgn = itr.next()) != nullptr) {
402+
report_virtual_memory_region(rgn);
403+
}
402404
}
403405

404406
void MemDetailReporter::report_virtual_memory_region(const ReservedMemoryRegion* reserved_rgn) {

src/hotspot/share/nmt/nmtNativeCallStackStorage.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,3 @@ NativeCallStackStorage::NativeCallStackStorage(bool is_detailed_mode, int table_
5757
NativeCallStackStorage::~NativeCallStackStorage() {
5858
FREE_C_HEAP_ARRAY(LinkPtr, _table);
5959
}
60-
61-
NativeCallStackStorage::NativeCallStackStorage(const NativeCallStackStorage& other)
62-
: _table_size(other._table_size),
63-
_table(nullptr),
64-
_stacks(),
65-
_is_detailed_mode(other._is_detailed_mode),
66-
_fake_stack(other._fake_stack) {
67-
if (_is_detailed_mode) {
68-
_table = NEW_C_HEAP_ARRAY(TableEntryIndex, _table_size, mtNMT);
69-
for (int i = 0; i < _table_size; i++) {
70-
_table[i] = other._table[i];
71-
}
72-
}
73-
_stacks.reserve(other._stacks.length());
74-
for (int i = 0; i < other._stacks.length(); i++) {
75-
_stacks.at_grow(i) = other._stacks.at(i);
76-
}
77-
}

src/hotspot/share/nmt/nmtNativeCallStackStorage.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ class NativeCallStackStorage : public CHeapObjBase {
9595
}
9696

9797
NativeCallStackStorage(bool is_detailed_mode, int table_size = default_table_size);
98-
NativeCallStackStorage(const NativeCallStackStorage& other);
99-
NativeCallStackStorage& operator=(const NativeCallStackStorage& other) = delete;
98+
10099
~NativeCallStackStorage();
101100
};
102101

src/hotspot/share/nmt/regionsTree.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
*
2323
*/
2424
#include "nmt/regionsTree.hpp"
25-
#include "nmt/regionsTree.inline.hpp"
26-
#include "nmt/virtualMemoryTracker.hpp"
2725

2826
VMATree::SummaryDiff RegionsTree::commit_region(address addr, size_t size, const NativeCallStack& stack) {
2927
return commit_mapping((VMATree::position)addr, size, make_region_data(stack, mtNone), /*use tag inplace*/ true);
@@ -56,13 +54,4 @@ void RegionsTree::print_on(outputStream* st) {
5654
return true;
5755
});
5856
}
59-
#endif
60-
61-
size_t RegionsTree::committed_size(ReservedMemoryRegion& rgn) {
62-
size_t result = 0;
63-
visit_committed_regions(rgn, [&](CommittedMemoryRegion& crgn) {
64-
result += crgn.size();
65-
return true;
66-
});
67-
return result;
68-
}
57+
#endif

src/hotspot/share/nmt/regionsTree.hpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,6 @@ class RegionsTree : public VMATree {
4040
public:
4141
RegionsTree(bool with_storage) : VMATree() , _ncs_storage(with_storage), _with_storage(with_storage) { }
4242

43-
RegionsTree(const RegionsTree& other)
44-
: VMATree(other),
45-
_ncs_storage(other._ncs_storage),
46-
_with_storage(other._with_storage) {}
47-
RegionsTree& operator=(const RegionsTree& other) = delete;
48-
4943
ReservedMemoryRegion find_reserved_region(address addr);
5044

5145
SummaryDiff commit_region(address addr, size_t size, const NativeCallStack& stack);
@@ -97,8 +91,6 @@ class RegionsTree : public VMATree {
9791
NativeCallStackStorage::StackIndex si = node.out_stack_index();
9892
return _ncs_storage.get(si);
9993
}
100-
101-
size_t committed_size(ReservedMemoryRegion& rgn);
10294
};
10395

104-
#endif // NMT_REGIONSTREE_HPP
96+
#endif // NMT_REGIONSTREE_HPP

src/hotspot/share/nmt/vmatree.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -744,10 +744,3 @@ void VMATree::SummaryDiff::print_on(outputStream* out) {
744744
}
745745
}
746746
#endif
747-
748-
void VMATree::clear() {
749-
_tree.remove_all();
750-
};
751-
bool VMATree::is_empty() {
752-
return _tree.size() == 0;
753-
};

src/hotspot/share/nmt/vmatree.hpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "nmt/nmtNativeCallStackStorage.hpp"
3131
#include "utilities/globalDefinitions.hpp"
3232
#include "utilities/ostream.hpp"
33-
#include "utilities/rbTree.hpp"
3433
#include "utilities/rbTree.inline.hpp"
3534

3635
#include <cstdint>
@@ -40,7 +39,7 @@
4039
// For example, the state may go from released memory to committed memory,
4140
// or from committed memory of a certain MemTag to committed memory of a different MemTag.
4241
// The set of points is stored in a balanced binary tree for efficient querying and updating.
43-
class VMATree : public CHeapObjBase {
42+
class VMATree {
4443
friend class NMTVMATreeTest;
4544
friend class VMTWithVMATreeTest;
4645
// A position in memory.
@@ -66,6 +65,7 @@ class VMATree : public CHeapObjBase {
6665
static const char* statetype_strings[static_cast<uint8_t>(StateType::st_number_of_states)];
6766

6867
public:
68+
NONCOPYABLE(VMATree);
6969

7070
static const char* statetype_to_string(StateType type) {
7171
assert(type < StateType::st_number_of_states, "must be");
@@ -226,10 +226,6 @@ class VMATree : public CHeapObjBase {
226226

227227
public:
228228
VMATree() : _tree() {}
229-
VMATree(const VMATree& other) : _tree() {
230-
assert(other._tree.copy_into(_tree), "VMATree dies on OOM");
231-
}
232-
VMATree& operator=(VMATree const&) = delete;
233229

234230
struct SingleDiff {
235231
using delta = int64_t;
@@ -333,8 +329,5 @@ class VMATree : public CHeapObjBase {
333329
_tree.visit_range_in_order(from, to, f);
334330
}
335331
VMARBTree& tree() { return _tree; }
336-
337-
void clear();
338-
bool is_empty();
339332
};
340333
#endif

src/hotspot/share/utilities/rbTree.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,6 @@ class AbstractRBTree {
428428
template <typename F>
429429
void visit_in_order(F f);
430430

431-
432431
// Visit all RBNodes in ascending order whose keys are in range [from, to], calling f on each node.
433432
// If f returns `true` the iteration continues, otherwise it is stopped at the current node.
434433
template <typename F>
@@ -476,7 +475,6 @@ class RBTree : public AbstractRBTree<K, RBNode<K, V>, COMPARATOR> {
476475

477476
public:
478477
RBTree() : BaseType(), _allocator() {}
479-
NONCOPYABLE(RBTree);
480478
~RBTree() { remove_all(); }
481479
RBTree(const RBTree& other) : BaseType(), _allocator() {
482480
assert(std::is_copy_constructible<V>(), "Value type must be copy-constructible");
@@ -487,8 +485,6 @@ class RBTree : public AbstractRBTree<K, RBNode<K, V>, COMPARATOR> {
487485
}
488486
RBTree& operator=(const RBTree& other) = delete;
489487

490-
bool copy_into(RBTree& other) const;
491-
492488
typedef typename BaseType::Cursor Cursor;
493489
using BaseType::cursor;
494490
using BaseType::insert_at_cursor;

0 commit comments

Comments
 (0)