Bug Summary

File:jdk/src/hotspot/share/services/virtualMemoryTracker.cpp
Warning:line 599, column 16
Value stored to 'page_sz' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name virtualMemoryTracker.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp
1/*
2 * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24#include "precompiled.hpp"
25#include "logging/log.hpp"
26#include "memory/metaspaceUtils.hpp"
27#include "memory/metaspaceStats.hpp"
28#include "runtime/os.hpp"
29#include "runtime/threadCritical.hpp"
30#include "services/memTracker.hpp"
31#include "services/threadStackTracker.hpp"
32#include "services/virtualMemoryTracker.hpp"
33#include "utilities/ostream.hpp"
34
35size_t VirtualMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(VirtualMemorySnapshot, size_t)(align_up(sizeof(VirtualMemorySnapshot), sizeof(size_t))/sizeof
(size_t))
];
36
37void VirtualMemorySummary::initialize() {
38 assert(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot), "Sanity Check")do { if (!(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 38, "assert(" "sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot)"
") failed", "Sanity Check"); ::breakpoint(); } } while (0)
;
39 // Use placement operator new to initialize static data area.
40 ::new ((void*)_snapshot) VirtualMemorySnapshot();
41}
42
43void VirtualMemorySummary::snapshot(VirtualMemorySnapshot* s) {
44 // Only if thread stack is backed by virtual memory
45 if (ThreadStackTracker::track_as_vm()) {
46 // Snapshot current thread stacks
47 VirtualMemoryTracker::snapshot_thread_stacks();
48 }
49 as_snapshot()->copy_to(s);
50}
51
52SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* VirtualMemoryTracker::_reserved_regions;
53
54int compare_committed_region(const CommittedMemoryRegion& r1, const CommittedMemoryRegion& r2) {
55 return r1.compare(r2);
56}
57
58int compare_reserved_region_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) {
59 return r1.compare(r2);
60}
61
62static bool is_mergeable_with(CommittedMemoryRegion* rgn, address addr, size_t size, const NativeCallStack& stack) {
63 return rgn->adjacent_to(addr, size) && rgn->call_stack()->equals(stack);
64}
65
66static bool is_same_as(CommittedMemoryRegion* rgn, address addr, size_t size, const NativeCallStack& stack) {
67 // It would have made sense to use rgn->equals(...), but equals returns true for overlapping regions.
68 return rgn->same_region(addr, size) && rgn->call_stack()->equals(stack);
69}
70
71static LinkedListNode<CommittedMemoryRegion>* find_preceding_node_from(LinkedListNode<CommittedMemoryRegion>* from, address addr) {
72 LinkedListNode<CommittedMemoryRegion>* preceding = NULL__null;
73
74 for (LinkedListNode<CommittedMemoryRegion>* node = from; node != NULL__null; node = node->next()) {
75 CommittedMemoryRegion* rgn = node->data();
76
77 // We searched past the region start.
78 if (rgn->end() > addr) {
79 break;
80 }
81
82 preceding = node;
83 }
84
85 return preceding;
86}
87
88static bool try_merge_with(LinkedListNode<CommittedMemoryRegion>* node, address addr, size_t size, const NativeCallStack& stack) {
89 if (node != NULL__null) {
90 CommittedMemoryRegion* rgn = node->data();
91
92 if (is_mergeable_with(rgn, addr, size, stack)) {
93 rgn->expand_region(addr, size);
94 return true;
95 }
96 }
97
98 return false;
99}
100
101static bool try_merge_with(LinkedListNode<CommittedMemoryRegion>* node, LinkedListNode<CommittedMemoryRegion>* other) {
102 if (other == NULL__null) {
103 return false;
104 }
105
106 CommittedMemoryRegion* rgn = other->data();
107 return try_merge_with(node, rgn->base(), rgn->size(), *rgn->call_stack());
108}
109
110bool ReservedMemoryRegion::add_committed_region(address addr, size_t size, const NativeCallStack& stack) {
111 assert(addr != NULL, "Invalid address")do { if (!(addr != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 111, "assert(" "addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
112 assert(size > 0, "Invalid size")do { if (!(size > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 112, "assert(" "size > 0" ") failed", "Invalid size"); ::
breakpoint(); } } while (0)
;
113 assert(contain_region(addr, size), "Not contain this region")do { if (!(contain_region(addr, size))) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 113, "assert(" "contain_region(addr, size)" ") failed", "Not contain this region"
); ::breakpoint(); } } while (0)
;
114
115 // Find the region that fully precedes the [addr, addr + size) region.
116 LinkedListNode<CommittedMemoryRegion>* prev = find_preceding_node_from(_committed_regions.head(), addr);
117 LinkedListNode<CommittedMemoryRegion>* next = (prev != NULL__null ? prev->next() : _committed_regions.head());
118
119 if (next != NULL__null) {
120 // Ignore request if region already exists.
121 if (is_same_as(next->data(), addr, size, stack)) {
122 return true;
123 }
124
125 // The new region is after prev, and either overlaps with the
126 // next region (and maybe more regions), or overlaps with no region.
127 if (next->data()->overlap_region(addr, size)) {
128 // Remove _all_ overlapping regions, and parts of regions,
129 // in preparation for the addition of this new region.
130 remove_uncommitted_region(addr, size);
131
132 // The remove could have split a region into two and created a
133 // new prev region. Need to reset the prev and next pointers.
134 prev = find_preceding_node_from((prev != NULL__null ? prev : _committed_regions.head()), addr);
135 next = (prev != NULL__null ? prev->next() : _committed_regions.head());
136 }
137 }
138
139 // At this point the previous overlapping regions have been
140 // cleared, and the full region is guaranteed to be inserted.
141 VirtualMemorySummary::record_committed_memory(size, flag());
142
143 // Try to merge with prev and possibly next.
144 if (try_merge_with(prev, addr, size, stack)) {
145 if (try_merge_with(prev, next)) {
146 // prev was expanded to contain the new region
147 // and next, need to remove next from the list
148 _committed_regions.remove_after(prev);
149 }
150
151 return true;
152 }
153
154 // Didn't merge with prev, try with next.
155 if (try_merge_with(next, addr, size, stack)) {
156 return true;
157 }
158
159 // Couldn't merge with any regions - create a new region.
160 return add_committed_region(CommittedMemoryRegion(addr, size, stack));
161}
162
163bool ReservedMemoryRegion::remove_uncommitted_region(LinkedListNode<CommittedMemoryRegion>* node,
164 address addr, size_t size) {
165 assert(addr != NULL, "Invalid address")do { if (!(addr != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 165, "assert(" "addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
166 assert(size > 0, "Invalid size")do { if (!(size > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 166, "assert(" "size > 0" ") failed", "Invalid size"); ::
breakpoint(); } } while (0)
;
167
168 CommittedMemoryRegion* rgn = node->data();
169 assert(rgn->contain_region(addr, size), "Has to be contained")do { if (!(rgn->contain_region(addr, size))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 169, "assert(" "rgn->contain_region(addr, size)" ") failed"
, "Has to be contained"); ::breakpoint(); } } while (0)
;
170 assert(!rgn->same_region(addr, size), "Can not be the same region")do { if (!(!rgn->same_region(addr, size))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 170, "assert(" "!rgn->same_region(addr, size)" ") failed"
, "Can not be the same region"); ::breakpoint(); } } while (0
)
;
171
172 if (rgn->base() == addr ||
173 rgn->end() == addr + size) {
174 rgn->exclude_region(addr, size);
175 return true;
176 } else {
177 // split this region
178 address top =rgn->end();
179 // use this region for lower part
180 size_t exclude_size = rgn->end() - addr;
181 rgn->exclude_region(addr, exclude_size);
182
183 // higher part
184 address high_base = addr + size;
185 size_t high_size = top - high_base;
186
187 CommittedMemoryRegion high_rgn(high_base, high_size, *rgn->call_stack());
188 LinkedListNode<CommittedMemoryRegion>* high_node = _committed_regions.add(high_rgn);
189 assert(high_node == NULL || node->next() == high_node, "Should be right after")do { if (!(high_node == __null || node->next() == high_node
)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 189, "assert(" "high_node == __null || node->next() == high_node"
") failed", "Should be right after"); ::breakpoint(); } } while
(0)
;
190 return (high_node != NULL__null);
191 }
192
193 return false;
194}
195
196bool ReservedMemoryRegion::remove_uncommitted_region(address addr, size_t sz) {
197 assert(addr != NULL, "Invalid address")do { if (!(addr != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 197, "assert(" "addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
198 assert(sz > 0, "Invalid size")do { if (!(sz > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 198, "assert(" "sz > 0" ") failed", "Invalid size"); ::breakpoint
(); } } while (0)
;
199
200 CommittedMemoryRegion del_rgn(addr, sz, *call_stack());
201 address end = addr + sz;
202
203 LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head();
204 LinkedListNode<CommittedMemoryRegion>* prev = NULL__null;
205 CommittedMemoryRegion* crgn;
206
207 while (head != NULL__null) {
208 crgn = head->data();
209
210 if (crgn->same_region(addr, sz)) {
211 VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
212 _committed_regions.remove_after(prev);
213 return true;
214 }
215
216 // del_rgn contains crgn
217 if (del_rgn.contain_region(crgn->base(), crgn->size())) {
218 VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
219 head = head->next();
220 _committed_regions.remove_after(prev);
221 continue; // don't update head or prev
222 }
223
224 // Found addr in the current crgn. There are 2 subcases:
225 if (crgn->contain_address(addr)) {
226
227 // (1) Found addr+size in current crgn as well. (del_rgn is contained in crgn)
228 if (crgn->contain_address(end - 1)) {
229 VirtualMemorySummary::record_uncommitted_memory(sz, flag());
230 return remove_uncommitted_region(head, addr, sz); // done!
231 } else {
232 // (2) Did not find del_rgn's end in crgn.
233 size_t size = crgn->end() - del_rgn.base();
234 crgn->exclude_region(addr, size);
235 VirtualMemorySummary::record_uncommitted_memory(size, flag());
236 }
237
238 } else if (crgn->contain_address(end - 1)) {
239 // Found del_rgn's end, but not its base addr.
240 size_t size = del_rgn.end() - crgn->base();
241 crgn->exclude_region(crgn->base(), size);
242 VirtualMemorySummary::record_uncommitted_memory(size, flag());
243 return true; // should be done if the list is sorted properly!
244 }
245
246 prev = head;
247 head = head->next();
248 }
249
250 return true;
251}
252
253void ReservedMemoryRegion::move_committed_regions(address addr, ReservedMemoryRegion& rgn) {
254 assert(addr != NULL, "Invalid address")do { if (!(addr != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 254, "assert(" "addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
255
256 // split committed regions
257 LinkedListNode<CommittedMemoryRegion>* head =
258 _committed_regions.head();
259 LinkedListNode<CommittedMemoryRegion>* prev = NULL__null;
260
261 while (head != NULL__null) {
262 if (head->data()->base() >= addr) {
263 break;
264 }
265 prev = head;
266 head = head->next();
267 }
268
269 if (head != NULL__null) {
270 if (prev != NULL__null) {
271 prev->set_next(head->next());
272 } else {
273 _committed_regions.set_head(NULL__null);
274 }
275 }
276
277 rgn._committed_regions.set_head(head);
278}
279
280size_t ReservedMemoryRegion::committed_size() const {
281 size_t committed = 0;
282 LinkedListNode<CommittedMemoryRegion>* head =
283 _committed_regions.head();
284 while (head != NULL__null) {
285 committed += head->data()->size();
286 head = head->next();
287 }
288 return committed;
289}
290
291void ReservedMemoryRegion::set_flag(MEMFLAGS f) {
292 assert((flag() == mtNone || flag() == f),do { if (!((flag() == mtNone || flag() == f))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 294, "assert(" "(flag() == mtNone || flag() == f)" ") failed"
, "Overwrite memory type for region [" "0x%016" "l" "x" "-" "0x%016"
"l" "x" "), %u->%u.", p2i(base()), p2i(end()), (unsigned)
flag(), (unsigned)f); ::breakpoint(); } } while (0)
293 "Overwrite memory type for region [" INTPTR_FORMAT "-" INTPTR_FORMAT "), %u->%u.",do { if (!((flag() == mtNone || flag() == f))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 294, "assert(" "(flag() == mtNone || flag() == f)" ") failed"
, "Overwrite memory type for region [" "0x%016" "l" "x" "-" "0x%016"
"l" "x" "), %u->%u.", p2i(base()), p2i(end()), (unsigned)
flag(), (unsigned)f); ::breakpoint(); } } while (0)
294 p2i(base()), p2i(end()), (unsigned)flag(), (unsigned)f)do { if (!((flag() == mtNone || flag() == f))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 294, "assert(" "(flag() == mtNone || flag() == f)" ") failed"
, "Overwrite memory type for region [" "0x%016" "l" "x" "-" "0x%016"
"l" "x" "), %u->%u.", p2i(base()), p2i(end()), (unsigned)
flag(), (unsigned)f); ::breakpoint(); } } while (0)
;
295 if (flag() != f) {
296 VirtualMemorySummary::move_reserved_memory(flag(), f, size());
297 VirtualMemorySummary::move_committed_memory(flag(), f, committed_size());
298 _flag = f;
299 }
300}
301
302address ReservedMemoryRegion::thread_stack_uncommitted_bottom() const {
303 assert(flag() == mtThreadStack, "Only for thread stack")do { if (!(flag() == mtThreadStack)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 303, "assert(" "flag() == mtThreadStack" ") failed", "Only for thread stack"
); ::breakpoint(); } } while (0)
;
304 LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head();
305 address bottom = base();
306 address top = base() + size();
307 while (head != NULL__null) {
308 address committed_top = head->data()->base() + head->data()->size();
309 if (committed_top < top) {
310 // committed stack guard pages, skip them
311 bottom = head->data()->base() + head->data()->size();
312 head = head->next();
313 } else {
314 assert(top == committed_top, "Sanity")do { if (!(top == committed_top)) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 314, "assert(" "top == committed_top" ") failed", "Sanity")
; ::breakpoint(); } } while (0)
;
315 break;
316 }
317 }
318
319 return bottom;
320}
321
322bool VirtualMemoryTracker::initialize(NMT_TrackingLevel level) {
323 assert(_reserved_regions == NULL, "only call once")do { if (!(_reserved_regions == __null)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 323, "assert(" "_reserved_regions == __null" ") failed", "only call once"
); ::breakpoint(); } } while (0)
;
324 if (level >= NMT_summary) {
325 VirtualMemorySummary::initialize();
326 _reserved_regions = new (std::nothrow, ResourceObj::C_HEAP, mtNMT)
327 SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>();
328 return (_reserved_regions != NULL__null);
329 }
330 return true;
331}
332
333bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size,
334 const NativeCallStack& stack, MEMFLAGS flag) {
335 assert(base_addr != NULL, "Invalid address")do { if (!(base_addr != __null)) { (*g_assert_poison) = 'X';;
report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 335, "assert(" "base_addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
336 assert(size > 0, "Invalid size")do { if (!(size > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 336, "assert(" "size > 0" ") failed", "Invalid size"); ::
breakpoint(); } } while (0)
;
337 assert(_reserved_regions != NULL, "Sanity check")do { if (!(_reserved_regions != __null)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 337, "assert(" "_reserved_regions != __null" ") failed", "Sanity check"
); ::breakpoint(); } } while (0)
;
338 ReservedMemoryRegion rgn(base_addr, size, stack, flag);
339 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
340
341 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("Add reserved region \'%s\' (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ")",
342 rgn.flag_name(), p2i(rgn.base()), rgn.size());
343 if (reserved_rgn == NULL__null) {
344 VirtualMemorySummary::record_reserved_memory(size, flag);
345 return _reserved_regions->add(rgn) != NULL__null;
346 } else {
347 // Deal with recursive reservation
348 // os::reserve_memory() -> pd_reserve_memory() -> os::reserve_memory()
349 // See JDK-8198226.
350 if (reserved_rgn->same_region(base_addr, size) &&
351 (reserved_rgn->flag() == flag || reserved_rgn->flag() == mtNone)) {
352 reserved_rgn->set_call_stack(stack);
353 reserved_rgn->set_flag(flag);
354 return true;
355 } else {
356 assert(reserved_rgn->overlap_region(base_addr, size), "Must be")do { if (!(reserved_rgn->overlap_region(base_addr, size)))
{ (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 356, "assert(" "reserved_rgn->overlap_region(base_addr, size)"
") failed", "Must be"); ::breakpoint(); } } while (0)
;
357
358 // Overlapped reservation.
359 // It can happen when the regions are thread stacks, as JNI
360 // thread does not detach from VM before exits, and leads to
361 // leak JavaThread object
362 if (reserved_rgn->flag() == mtThreadStack) {
363 guarantee(!CheckJNICalls, "Attached JNI thread exited without being detached")do { if (!(!CheckJNICalls)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 363, "guarantee(" "!CheckJNICalls" ") failed", "Attached JNI thread exited without being detached"
); ::breakpoint(); } } while (0)
;
364 // Overwrite with new region
365
366 // Release old region
367 VirtualMemorySummary::record_uncommitted_memory(reserved_rgn->committed_size(), reserved_rgn->flag());
368 VirtualMemorySummary::record_released_memory(reserved_rgn->size(), reserved_rgn->flag());
369
370 // Add new region
371 VirtualMemorySummary::record_reserved_memory(rgn.size(), flag);
372
373 *reserved_rgn = rgn;
374 return true;
375 }
376
377 // CDS mapping region.
378 // CDS reserves the whole region for mapping CDS archive, then maps each section into the region.
379 // NMT reports CDS as a whole.
380 if (reserved_rgn->flag() == mtClassShared) {
381 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("CDS reserved region \'%s\' as a whole (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ")",
382 reserved_rgn->flag_name(), p2i(reserved_rgn->base()), reserved_rgn->size());
383 assert(reserved_rgn->contain_region(base_addr, size), "Reserved CDS region should contain this mapping region")do { if (!(reserved_rgn->contain_region(base_addr, size)))
{ (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 383, "assert(" "reserved_rgn->contain_region(base_addr, size)"
") failed", "Reserved CDS region should contain this mapping region"
); ::breakpoint(); } } while (0)
;
384 return true;
385 }
386
387 // Mapped CDS string region.
388 // The string region(s) is part of the java heap.
389 if (reserved_rgn->flag() == mtJavaHeap) {
390 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("CDS reserved region \'%s\' as a whole (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ")",
391 reserved_rgn->flag_name(), p2i(reserved_rgn->base()), reserved_rgn->size());
392 assert(reserved_rgn->contain_region(base_addr, size), "Reserved heap region should contain this mapping region")do { if (!(reserved_rgn->contain_region(base_addr, size)))
{ (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 392, "assert(" "reserved_rgn->contain_region(base_addr, size)"
") failed", "Reserved heap region should contain this mapping region"
); ::breakpoint(); } } while (0)
;
393 return true;
394 }
395
396 // Print some more details. Don't use UL here to avoid circularities.
397#ifdef ASSERT1
398 tty->print_cr("Error: existing region: [" INTPTR_FORMAT"0x%016" "l" "x" "-" INTPTR_FORMAT"0x%016" "l" "x" "), flag %u.\n"
399 " new region: [" INTPTR_FORMAT"0x%016" "l" "x" "-" INTPTR_FORMAT"0x%016" "l" "x" "), flag %u.",
400 p2i(reserved_rgn->base()), p2i(reserved_rgn->end()), (unsigned)reserved_rgn->flag(),
401 p2i(base_addr), p2i(base_addr + size), (unsigned)flag);
402#endif
403 ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 403); ::breakpoint(); } while (0)
;
404 return false;
405 }
406 }
407}
408
409void VirtualMemoryTracker::set_reserved_region_type(address addr, MEMFLAGS flag) {
410 assert(addr != NULL, "Invalid address")do { if (!(addr != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 410, "assert(" "addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
411 assert(_reserved_regions != NULL, "Sanity check")do { if (!(_reserved_regions != __null)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 411, "assert(" "_reserved_regions != __null" ") failed", "Sanity check"
); ::breakpoint(); } } while (0)
;
412
413 ReservedMemoryRegion rgn(addr, 1);
414 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
415 if (reserved_rgn != NULL__null) {
416 assert(reserved_rgn->contain_address(addr), "Containment")do { if (!(reserved_rgn->contain_address(addr))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 416, "assert(" "reserved_rgn->contain_address(addr)" ") failed"
, "Containment"); ::breakpoint(); } } while (0)
;
417 if (reserved_rgn->flag() != flag) {
418 assert(reserved_rgn->flag() == mtNone, "Overwrite memory type (should be mtNone, is: \"%s\")",do { if (!(reserved_rgn->flag() == mtNone)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 419, "assert(" "reserved_rgn->flag() == mtNone" ") failed"
, "Overwrite memory type (should be mtNone, is: \"%s\")", NMTUtil
::flag_to_name(reserved_rgn->flag())); ::breakpoint(); } }
while (0)
419 NMTUtil::flag_to_name(reserved_rgn->flag()))do { if (!(reserved_rgn->flag() == mtNone)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 419, "assert(" "reserved_rgn->flag() == mtNone" ") failed"
, "Overwrite memory type (should be mtNone, is: \"%s\")", NMTUtil
::flag_to_name(reserved_rgn->flag())); ::breakpoint(); } }
while (0)
;
420 reserved_rgn->set_flag(flag);
421 }
422 }
423}
424
425bool VirtualMemoryTracker::add_committed_region(address addr, size_t size,
426 const NativeCallStack& stack) {
427 assert(addr != NULL, "Invalid address")do { if (!(addr != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 427, "assert(" "addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
428 assert(size > 0, "Invalid size")do { if (!(size > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 428, "assert(" "size > 0" ") failed", "Invalid size"); ::
breakpoint(); } } while (0)
;
429 assert(_reserved_regions != NULL, "Sanity check")do { if (!(_reserved_regions != __null)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 429, "assert(" "_reserved_regions != __null" ") failed", "Sanity check"
); ::breakpoint(); } } while (0)
;
430
431 ReservedMemoryRegion rgn(addr, size);
432 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
433
434 if (reserved_rgn == NULL__null) {
435 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("Add committed region \'%s\', No reserved region found for (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ")",
436 rgn.flag_name(), p2i(rgn.base()), rgn.size());
437 }
438 assert(reserved_rgn != NULL, "Add committed region, No reserved region found")do { if (!(reserved_rgn != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 438, "assert(" "reserved_rgn != __null" ") failed", "Add committed region, No reserved region found"
); ::breakpoint(); } } while (0)
;
439 assert(reserved_rgn->contain_region(addr, size), "Not completely contained")do { if (!(reserved_rgn->contain_region(addr, size))) { (*
g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 439, "assert(" "reserved_rgn->contain_region(addr, size)"
") failed", "Not completely contained"); ::breakpoint(); } }
while (0)
;
440 bool result = reserved_rgn->add_committed_region(addr, size, stack);
441 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("Add committed region \'%s\'(" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ") %s",
442 reserved_rgn->flag_name(), p2i(rgn.base()), rgn.size(), (result ? "Succeeded" : "Failed"));
443 return result;
444}
445
446bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) {
447 assert(addr != NULL, "Invalid address")do { if (!(addr != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 447, "assert(" "addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
448 assert(size > 0, "Invalid size")do { if (!(size > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 448, "assert(" "size > 0" ") failed", "Invalid size"); ::
breakpoint(); } } while (0)
;
449 assert(_reserved_regions != NULL, "Sanity check")do { if (!(_reserved_regions != __null)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 449, "assert(" "_reserved_regions != __null" ") failed", "Sanity check"
); ::breakpoint(); } } while (0)
;
450
451 ReservedMemoryRegion rgn(addr, size);
452 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
453 assert(reserved_rgn != NULL, "No reserved region (" INTPTR_FORMAT ", " SIZE_FORMAT ")", p2i(addr), size)do { if (!(reserved_rgn != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 453, "assert(" "reserved_rgn != __null" ") failed", "No reserved region ("
"0x%016" "l" "x" ", " "%" "l" "u" ")", p2i(addr), size); ::breakpoint
(); } } while (0)
;
454 assert(reserved_rgn->contain_region(addr, size), "Not completely contained")do { if (!(reserved_rgn->contain_region(addr, size))) { (*
g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 454, "assert(" "reserved_rgn->contain_region(addr, size)"
") failed", "Not completely contained"); ::breakpoint(); } }
while (0)
;
455 const char* flag_name = reserved_rgn->flag_name(); // after remove, info is not complete
456 bool result = reserved_rgn->remove_uncommitted_region(addr, size);
457 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("Removed uncommitted region \'%s\' (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ") %s",
458 flag_name, p2i(addr), size, (result ? " Succeeded" : "Failed"));
459 return result;
460}
461
462bool VirtualMemoryTracker::remove_released_region(ReservedMemoryRegion* rgn) {
463 assert(rgn != NULL, "Sanity check")do { if (!(rgn != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 463, "assert(" "rgn != __null" ") failed", "Sanity check");
::breakpoint(); } } while (0)
;
464 assert(_reserved_regions != NULL, "Sanity check")do { if (!(_reserved_regions != __null)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 464, "assert(" "_reserved_regions != __null" ") failed", "Sanity check"
); ::breakpoint(); } } while (0)
;
465
466 // uncommit regions within the released region
467 ReservedMemoryRegion backup(*rgn);
468 bool result = rgn->remove_uncommitted_region(rgn->base(), rgn->size());
469 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("Remove uncommitted region \'%s\' (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ") %s",
470 backup.flag_name(), p2i(backup.base()), backup.size(), (result ? "Succeeded" : "Failed"));
471 if (!result) {
472 return false;
473 }
474
475 VirtualMemorySummary::record_released_memory(rgn->size(), rgn->flag());
476 result = _reserved_regions->remove(*rgn);
477 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("Removed region \'%s\' (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ") from _resvered_regions %s" ,
478 backup.flag_name(), p2i(backup.base()), backup.size(), (result ? "Succeeded" : "Failed"));
479 return result;
480}
481
482bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
483 assert(addr != NULL, "Invalid address")do { if (!(addr != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 483, "assert(" "addr != __null" ") failed", "Invalid address"
); ::breakpoint(); } } while (0)
;
484 assert(size > 0, "Invalid size")do { if (!(size > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 484, "assert(" "size > 0" ") failed", "Invalid size"); ::
breakpoint(); } } while (0)
;
485 assert(_reserved_regions != NULL, "Sanity check")do { if (!(_reserved_regions != __null)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 485, "assert(" "_reserved_regions != __null" ") failed", "Sanity check"
); ::breakpoint(); } } while (0)
;
486
487 ReservedMemoryRegion rgn(addr, size);
488 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
489
490 if (reserved_rgn == NULL__null) {
491 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("No reserved region found for (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ")!",
492 p2i(rgn.base()), rgn.size());
493 }
494 assert(reserved_rgn != NULL, "No reserved region")do { if (!(reserved_rgn != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 494, "assert(" "reserved_rgn != __null" ") failed", "No reserved region"
); ::breakpoint(); } } while (0)
;
495 if (reserved_rgn->same_region(addr, size)) {
496 return remove_released_region(reserved_rgn);
497 }
498
499 // uncommit regions within the released region
500 if (!reserved_rgn->remove_uncommitted_region(addr, size)) {
501 return false;
502 }
503
504 if (reserved_rgn->flag() == mtClassShared) {
505 if (reserved_rgn->contain_region(addr, size)) {
506 // This is an unmapped CDS region, which is part of the reserved shared
507 // memory region.
508 // See special handling in VirtualMemoryTracker::add_reserved_region also.
509 return true;
510 }
511
512 if (size > reserved_rgn->size()) {
513 // This is from release the whole region spanning from archive space to class space,
514 // so we release them altogether.
515 ReservedMemoryRegion class_rgn(addr + reserved_rgn->size(),
516 (size - reserved_rgn->size()));
517 ReservedMemoryRegion* cls_rgn = _reserved_regions->find(class_rgn);
518 assert(cls_rgn != NULL, "Class space region not recorded?")do { if (!(cls_rgn != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 518, "assert(" "cls_rgn != __null" ") failed", "Class space region not recorded?"
); ::breakpoint(); } } while (0)
;
519 assert(cls_rgn->flag() == mtClass, "Must be class type")do { if (!(cls_rgn->flag() == mtClass)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 519, "assert(" "cls_rgn->flag() == mtClass" ") failed", "Must be class type"
); ::breakpoint(); } } while (0)
;
520 remove_released_region(reserved_rgn);
521 remove_released_region(cls_rgn);
522 return true;
523 }
524 }
525
526 VirtualMemorySummary::record_released_memory(size, reserved_rgn->flag());
527
528 assert(reserved_rgn->contain_region(addr, size), "Not completely contained")do { if (!(reserved_rgn->contain_region(addr, size))) { (*
g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 528, "assert(" "reserved_rgn->contain_region(addr, size)"
") failed", "Not completely contained"); ::breakpoint(); } }
while (0)
;
529 if (reserved_rgn->base() == addr ||
530 reserved_rgn->end() == addr + size) {
531 reserved_rgn->exclude_region(addr, size);
532 return true;
533 } else {
534 address top = reserved_rgn->end();
535 address high_base = addr + size;
536 ReservedMemoryRegion high_rgn(high_base, top - high_base,
537 *reserved_rgn->call_stack(), reserved_rgn->flag());
538
539 // use original region for lower region
540 reserved_rgn->exclude_region(addr, top - addr);
541 LinkedListNode<ReservedMemoryRegion>* new_rgn = _reserved_regions->add(high_rgn);
542 if (new_rgn == NULL__null) {
543 return false;
544 } else {
545 reserved_rgn->move_committed_regions(addr, *new_rgn->data());
546 return true;
547 }
548 }
549}
550
551// Given an existing memory mapping registered with NMT, split the mapping in
552// two. The newly created two mappings will be registered under the call
553// stack and the memory flags of the original section.
554bool VirtualMemoryTracker::split_reserved_region(address addr, size_t size, size_t split) {
555
556 ReservedMemoryRegion rgn(addr, size);
557 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
558 assert(reserved_rgn->same_region(addr, size), "Must be identical region")do { if (!(reserved_rgn->same_region(addr, size))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 558, "assert(" "reserved_rgn->same_region(addr, size)" ") failed"
, "Must be identical region"); ::breakpoint(); } } while (0)
;
559 assert(reserved_rgn != NULL, "No reserved region")do { if (!(reserved_rgn != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 559, "assert(" "reserved_rgn != __null" ") failed", "No reserved region"
); ::breakpoint(); } } while (0)
;
560 assert(reserved_rgn->committed_size() == 0, "Splitting committed region?")do { if (!(reserved_rgn->committed_size() == 0)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 560, "assert(" "reserved_rgn->committed_size() == 0" ") failed"
, "Splitting committed region?"); ::breakpoint(); } } while (
0)
;
561
562 NativeCallStack original_stack = *reserved_rgn->call_stack();
563 MEMFLAGS original_flags = reserved_rgn->flag();
564
565 const char* name = reserved_rgn->flag_name();
566 remove_released_region(reserved_rgn);
567 log_debug(nmt)(!(LogImpl<(LogTag::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_nmt), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("Split region \'%s\' (" INTPTR_FORMAT"0x%016" "l" "x" ", " SIZE_FORMAT"%" "l" "u" ") with size " SIZE_FORMAT"%" "l" "u",
568 name, p2i(rgn.base()), rgn.size(), split);
569 // Now, create two new regions.
570 add_reserved_region(addr, split, original_stack, original_flags);
571 add_reserved_region(addr + split, size - split, original_stack, original_flags);
572
573 return true;
574}
575
576
577// Iterate the range, find committed region within its bound.
578class RegionIterator : public StackObj {
579private:
580 const address _start;
581 const size_t _size;
582
583 address _current_start;
584 size_t _current_size;
585public:
586 RegionIterator(address start, size_t size) :
587 _start(start), _size(size), _current_start(start), _current_size(size) {
588 }
589
590 // return true if committed region is found
591 bool next_committed(address& start, size_t& size);
592private:
593 address end() const { return _start + _size; }
594};
595
596bool RegionIterator::next_committed(address& committed_start, size_t& committed_size) {
597 if (end() <= _current_start) return false;
598
599 const size_t page_sz = os::vm_page_size();
Value stored to 'page_sz' during its initialization is never read
600 assert(_current_start + _current_size == end(), "Must be")do { if (!(_current_start + _current_size == end())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 600, "assert(" "_current_start + _current_size == end()" ") failed"
, "Must be"); ::breakpoint(); } } while (0)
;
601 if (os::committed_in_range(_current_start, _current_size, committed_start, committed_size)) {
602 assert(committed_start != NULL, "Must be")do { if (!(committed_start != __null)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 602, "assert(" "committed_start != __null" ") failed", "Must be"
); ::breakpoint(); } } while (0)
;
603 assert(committed_size > 0 && is_aligned(committed_size, os::vm_page_size()), "Must be")do { if (!(committed_size > 0 && is_aligned(committed_size
, os::vm_page_size()))) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 603, "assert(" "committed_size > 0 && is_aligned(committed_size, os::vm_page_size())"
") failed", "Must be"); ::breakpoint(); } } while (0)
;
604
605 size_t remaining_size = (_current_start + _current_size) - (committed_start + committed_size);
606 _current_start = committed_start + committed_size;
607 _current_size = remaining_size;
608 return true;
609 } else {
610 return false;
611 }
612}
613
614// Walk all known thread stacks, snapshot their committed ranges.
615class SnapshotThreadStackWalker : public VirtualMemoryWalker {
616public:
617 SnapshotThreadStackWalker() {}
618
619 bool do_allocation_site(const ReservedMemoryRegion* rgn) {
620 if (rgn->flag() == mtThreadStack) {
621 address stack_bottom = rgn->thread_stack_uncommitted_bottom();
622 address committed_start;
623 size_t committed_size;
624 size_t stack_size = rgn->base() + rgn->size() - stack_bottom;
625 // Align the size to work with full pages (Alpine and AIX stack top is not page aligned)
626 size_t aligned_stack_size = align_up(stack_size, os::vm_page_size());
627
628 ReservedMemoryRegion* region = const_cast<ReservedMemoryRegion*>(rgn);
629 NativeCallStack ncs; // empty stack
630
631 RegionIterator itr(stack_bottom, aligned_stack_size);
632 DEBUG_ONLY(bool found_stack = false;)bool found_stack = false;
633 while (itr.next_committed(committed_start, committed_size)) {
634 assert(committed_start != NULL, "Should not be null")do { if (!(committed_start != __null)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 634, "assert(" "committed_start != __null" ") failed", "Should not be null"
); ::breakpoint(); } } while (0)
;
635 assert(committed_size > 0, "Should not be 0")do { if (!(committed_size > 0)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 635, "assert(" "committed_size > 0" ") failed", "Should not be 0"
); ::breakpoint(); } } while (0)
;
636 // unaligned stack_size case: correct the region to fit the actual stack_size
637 if (stack_bottom + stack_size < committed_start + committed_size) {
638 committed_size = stack_bottom + stack_size - committed_start;
639 }
640 region->add_committed_region(committed_start, committed_size, ncs);
641 DEBUG_ONLY(found_stack = true;)found_stack = true;
642 }
643#ifdef ASSERT1
644 if (!found_stack) {
645 log_debug(thread)(!(LogImpl<(LogTag::_thread), (LogTag::__NO_TAG), (LogTag::
__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG
)>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_thread), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::
__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<
LogLevel::Debug>
("Thread exited without proper cleanup, may leak thread object");
646 }
647#endif
648 }
649 return true;
650 }
651};
652
653void VirtualMemoryTracker::snapshot_thread_stacks() {
654 SnapshotThreadStackWalker walker;
655 walk_virtual_memory(&walker);
656}
657
658bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) {
659 assert(_reserved_regions != NULL, "Sanity check")do { if (!(_reserved_regions != __null)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/virtualMemoryTracker.cpp"
, 659, "assert(" "_reserved_regions != __null" ") failed", "Sanity check"
); ::breakpoint(); } } while (0)
;
660 ThreadCritical tc;
661 // Check that the _reserved_regions haven't been deleted.
662 if (_reserved_regions != NULL__null) {
663 LinkedListNode<ReservedMemoryRegion>* head = _reserved_regions->head();
664 while (head != NULL__null) {
665 const ReservedMemoryRegion* rgn = head->peek();
666 if (!walker->do_allocation_site(rgn)) {
667 return false;
668 }
669 head = head->next();
670 }
671 }
672 return true;
673}