Mercurial > hg > truffle
annotate src/share/vm/services/memTracker.hpp @ 20364:c6211b707068
8055007: NMT2: emptyStack missing in minimal build
Summary: Refactored emptyStack to a static member of NativeCallStack, which is accessible in minimal build.
Reviewed-by: coleenp, dholmes
author | zgu |
---|---|
date | Tue, 19 Aug 2014 08:34:25 -0400 |
parents | 833b0f92429a |
children | 417e3b8d04c5 |
rev | line source |
---|---|
6197 | 1 /* |
20360 | 2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. |
6197 | 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 | |
25 #ifndef SHARE_VM_SERVICES_MEM_TRACKER_HPP | |
26 #define SHARE_VM_SERVICES_MEM_TRACKER_HPP | |
27 | |
20360 | 28 #include "services/nmtCommon.hpp" |
20364 | 29 #include "utilities/nativeCallStack.hpp" |
20360 | 30 |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
31 |
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
32 #if !INCLUDE_NMT |
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
33 |
20364 | 34 #define CURRENT_PC NativeCallStack::EMPTY_STACK |
35 #define CALLER_PC NativeCallStack::EMPTY_STACK | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
36 |
20360 | 37 class Tracker : public StackObj { |
38 public: | |
39 Tracker() { } | |
40 void record(address addr, size_t size) { } | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
41 }; |
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
42 |
20360 | 43 class MemTracker : AllStatic { |
44 public: | |
45 static inline NMT_TrackingLevel tracking_level() { return NMT_off; } | |
46 static inline void shutdown() { } | |
47 static inline void init() { } | |
48 static bool check_launcher_nmt_support(const char* value) { return true; } | |
49 static bool verify_nmt_option() { return true; } | |
50 | |
51 static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag, | |
52 const NativeCallStack& stack, NMT_TrackingLevel level) { return mem_base; } | |
53 static inline size_t malloc_header_size(NMT_TrackingLevel level) { return 0; } | |
54 static inline size_t malloc_header_size(void* memblock) { return 0; } | |
55 static inline void* malloc_base(void* memblock) { return memblock; } | |
56 static inline void* record_free(void* memblock) { return memblock; } | |
57 | |
58 static inline void record_new_arena(MEMFLAGS flag) { } | |
59 static inline void record_arena_free(MEMFLAGS flag) { } | |
60 static inline void record_arena_size_change(int diff, MEMFLAGS flag) { } | |
61 static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack, | |
62 MEMFLAGS flag = mtNone) { } | |
63 static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size, | |
64 const NativeCallStack& stack, MEMFLAGS flag = mtNone) { } | |
65 static inline void record_virtual_memory_commit(void* addr, size_t size, const NativeCallStack& stack) { } | |
66 static inline Tracker get_virtual_memory_uncommit_tracker() { return Tracker(); } | |
67 static inline Tracker get_virtual_memory_release_tracker() { } | |
68 static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { } | |
69 static inline void record_thread_stack(void* addr, size_t size) { } | |
70 static inline void release_thread_stack(void* addr, size_t size) { } | |
71 | |
72 static void final_report(outputStream*) { } | |
73 }; | |
74 | |
75 #else | |
76 | |
77 #include "runtime/atomic.hpp" | |
78 #include "runtime/threadCritical.hpp" | |
79 #include "services/mallocTracker.hpp" | |
80 #include "services/virtualMemoryTracker.hpp" | |
81 | |
82 extern volatile bool NMT_stack_walkable; | |
83 | |
84 #define CURRENT_PC ((MemTracker::tracking_level() == NMT_detail && NMT_stack_walkable) ? \ | |
20364 | 85 NativeCallStack(0, true) : NativeCallStack::EMPTY_STACK) |
20360 | 86 #define CALLER_PC ((MemTracker::tracking_level() == NMT_detail && NMT_stack_walkable) ? \ |
20364 | 87 NativeCallStack(1, true) : NativeCallStack::EMPTY_STACK) |
20360 | 88 |
89 class MemBaseline; | |
90 class Mutex; | |
91 | |
92 // Tracker is used for guarding 'release' semantics of virtual memory operation, to avoid | |
93 // the other thread obtains and records the same region that is just 'released' by current | |
94 // thread but before it can record the operation. | |
95 class Tracker : public StackObj { | |
96 public: | |
97 enum TrackerType { | |
98 uncommit, | |
99 release | |
100 }; | |
101 | |
102 public: | |
103 Tracker(enum TrackerType type) : _type(type) { } | |
104 void record(address addr, size_t size); | |
105 private: | |
106 enum TrackerType _type; | |
107 // Virtual memory tracking data structures are protected by ThreadCritical lock. | |
108 ThreadCritical _tc; | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
109 }; |
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
110 |
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
111 class MemTracker : AllStatic { |
6197 | 112 public: |
20360 | 113 static inline NMT_TrackingLevel tracking_level() { |
114 if (_tracking_level == NMT_unknown) { | |
115 // No fencing is needed here, since JVM is in single-threaded | |
116 // mode. | |
117 _tracking_level = init_tracking_level(); | |
118 _cmdline_tracking_level = _tracking_level; | |
119 } | |
6770
9a86ddfc6c8f
7188594: Print statistic collected by NMT with VM flag
zgu
parents:
6768
diff
changeset
|
120 return _tracking_level; |
9a86ddfc6c8f
7188594: Print statistic collected by NMT with VM flag
zgu
parents:
6768
diff
changeset
|
121 } |
9a86ddfc6c8f
7188594: Print statistic collected by NMT with VM flag
zgu
parents:
6768
diff
changeset
|
122 |
20360 | 123 // A late initialization, for the stuff(s) can not be |
124 // done in init_tracking_level(), which can NOT malloc | |
125 // any memory. | |
126 static void init(); | |
127 | |
128 // Shutdown native memory tracking | |
129 static void shutdown(); | |
130 | |
131 // Verify native memory tracking command line option. | |
132 // This check allows JVM to detect if compatible launcher | |
133 // is used. | |
134 // If an incompatible launcher is used, NMT may not be | |
135 // able to start, even it is enabled by command line option. | |
136 // A warning message should be given if it is encountered. | |
137 static bool check_launcher_nmt_support(const char* value); | |
138 | |
139 // This method checks native memory tracking environment | |
140 // variable value passed by launcher. | |
141 // Launcher only obligates to pass native memory tracking | |
142 // option value, but not obligates to validate the value, | |
143 // and launcher has option to discard native memory tracking | |
144 // option from the command line once it sets up the environment | |
145 // variable, so NMT has to catch the bad value here. | |
146 static bool verify_nmt_option(); | |
147 | |
148 // Transition the tracking level to specified level | |
149 static bool transition_to(NMT_TrackingLevel level); | |
150 | |
151 static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag, | |
152 const NativeCallStack& stack, NMT_TrackingLevel level) { | |
153 return MallocTracker::record_malloc(mem_base, size, flag, stack, level); | |
154 } | |
155 | |
156 static inline size_t malloc_header_size(NMT_TrackingLevel level) { | |
157 return MallocTracker::malloc_header_size(level); | |
6197 | 158 } |
159 | |
20360 | 160 static size_t malloc_header_size(void* memblock) { |
161 if (tracking_level() != NMT_off) { | |
162 return MallocTracker::get_header_size(memblock); | |
163 } | |
164 return 0; | |
165 } | |
166 | |
167 // To malloc base address, which is the starting address | |
168 // of malloc tracking header if tracking is enabled. | |
169 // Otherwise, it returns the same address. | |
170 static void* malloc_base(void* memblock); | |
171 | |
172 // Record malloc free and return malloc base address | |
173 static inline void* record_free(void* memblock) { | |
174 return MallocTracker::record_free(memblock); | |
6197 | 175 } |
176 | |
20360 | 177 |
178 // Record creation of an arena | |
179 static inline void record_new_arena(MEMFLAGS flag) { | |
180 if (tracking_level() < NMT_summary) return; | |
181 MallocTracker::record_new_arena(flag); | |
182 } | |
183 | |
184 // Record destruction of an arena | |
185 static inline void record_arena_free(MEMFLAGS flag) { | |
186 if (tracking_level() < NMT_summary) return; | |
187 MallocTracker::record_arena_free(flag); | |
188 } | |
6197 | 189 |
20360 | 190 // Record arena size change. Arena size is the size of all arena |
191 // chuncks that backing up the arena. | |
192 static inline void record_arena_size_change(int diff, MEMFLAGS flag) { | |
193 if (tracking_level() < NMT_summary) return; | |
194 MallocTracker::record_arena_size_change(diff, flag); | |
195 } | |
196 | |
197 static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack, | |
198 MEMFLAGS flag = mtNone) { | |
199 if (tracking_level() < NMT_summary) return; | |
200 if (addr != NULL) { | |
201 ThreadCritical tc; | |
202 // Recheck to avoid potential racing during NMT shutdown | |
203 if (tracking_level() < NMT_summary) return; | |
204 VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, flag); | |
8810
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7971
diff
changeset
|
205 } |
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7971
diff
changeset
|
206 } |
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7971
diff
changeset
|
207 |
20360 | 208 static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size, |
209 const NativeCallStack& stack, MEMFLAGS flag = mtNone) { | |
210 if (tracking_level() < NMT_summary) return; | |
211 if (addr != NULL) { | |
212 ThreadCritical tc; | |
213 if (tracking_level() < NMT_summary) return; | |
214 VirtualMemoryTracker::add_reserved_region((address)addr, size, | |
215 stack, flag, true); | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11090
diff
changeset
|
216 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11090
diff
changeset
|
217 } |
6197 | 218 |
20360 | 219 static inline void record_virtual_memory_commit(void* addr, size_t size, |
220 const NativeCallStack& stack) { | |
221 if (tracking_level() < NMT_summary) return; | |
222 if (addr != NULL) { | |
223 ThreadCritical tc; | |
224 if (tracking_level() < NMT_summary) return; | |
225 VirtualMemoryTracker::add_committed_region((address)addr, size, stack); | |
226 } | |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
227 } |
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
228 |
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
229 static inline Tracker get_virtual_memory_uncommit_tracker() { |
20360 | 230 assert(tracking_level() >= NMT_summary, "Check by caller"); |
231 return Tracker(Tracker::uncommit); | |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
232 } |
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
233 |
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
234 static inline Tracker get_virtual_memory_release_tracker() { |
20360 | 235 assert(tracking_level() >= NMT_summary, "Check by caller"); |
236 return Tracker(Tracker::release); | |
6197 | 237 } |
238 | |
20360 | 239 static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { |
240 if (tracking_level() < NMT_summary) return; | |
241 if (addr != NULL) { | |
242 ThreadCritical tc; | |
243 if (tracking_level() < NMT_summary) return; | |
244 VirtualMemoryTracker::set_reserved_region_type((address)addr, flag); | |
6197 | 245 } |
246 } | |
247 | |
20360 | 248 static inline void record_thread_stack(void* addr, size_t size) { |
249 if (tracking_level() < NMT_summary) return; | |
250 if (addr != NULL) { | |
251 // uses thread stack malloc slot for book keeping number of threads | |
252 MallocMemorySummary::record_malloc(0, mtThreadStack); | |
253 record_virtual_memory_reserve_and_commit(addr, size, CALLER_PC, mtThreadStack); | |
254 } | |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
255 } |
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
256 |
20360 | 257 static inline void release_thread_stack(void* addr, size_t size) { |
258 if (tracking_level() < NMT_summary) return; | |
259 if (addr != NULL) { | |
260 // uses thread stack malloc slot for book keeping number of threads | |
261 MallocMemorySummary::record_free(0, mtThreadStack); | |
262 ThreadCritical tc; | |
263 if (tracking_level() < NMT_summary) return; | |
264 VirtualMemoryTracker::remove_released_region((address)addr, size); | |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
265 } |
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
266 } |
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
267 |
20360 | 268 // Query lock is used to synchronize the access to tracking data. |
269 // So far, it is only used by JCmd query, but it may be used by | |
270 // other tools. | |
271 static inline Mutex* query_lock() { return _query_lock; } | |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
272 |
20360 | 273 // Make a final report and shutdown. |
274 // This function generates summary report without creating snapshots, | |
275 // to avoid additional memory allocation. It uses native memory summary | |
276 // counters, and makes adjustment to them, once the adjustment is made, | |
277 // the counters are no longer accurate. As the result, this function | |
278 // should only be used for final reporting before shutting down. | |
279 static void final_report(outputStream*); | |
280 | |
281 // Stored baseline | |
282 static inline MemBaseline& get_baseline() { | |
283 return _baseline; | |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
284 } |
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10096
diff
changeset
|
285 |
20360 | 286 static NMT_TrackingLevel cmdline_tracking_level() { |
287 return _cmdline_tracking_level; | |
7971
4102b59539ce
8005012: Add WB APIs to better support NMT testing
ctornqvi
parents:
7464
diff
changeset
|
288 } |
4102b59539ce
8005012: Add WB APIs to better support NMT testing
ctornqvi
parents:
7464
diff
changeset
|
289 |
20360 | 290 static void tuning_statistics(outputStream* out); |
7971
4102b59539ce
8005012: Add WB APIs to better support NMT testing
ctornqvi
parents:
7464
diff
changeset
|
291 |
6197 | 292 private: |
20360 | 293 static NMT_TrackingLevel init_tracking_level(); |
6197 | 294 |
20360 | 295 private: |
296 // Tracking level | |
297 static volatile NMT_TrackingLevel _tracking_level; | |
298 // If NMT option value passed by launcher through environment | |
299 // variable is valid | |
300 static bool _is_nmt_env_valid; | |
301 // command line tracking level | |
302 static NMT_TrackingLevel _cmdline_tracking_level; | |
303 // Stored baseline | |
304 static MemBaseline _baseline; | |
305 // Query lock | |
306 static Mutex* _query_lock; | |
6197 | 307 }; |
308 | |
20360 | 309 #endif // INCLUDE_NMT |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6770
diff
changeset
|
310 |
6197 | 311 #endif // SHARE_VM_SERVICES_MEM_TRACKER_HPP |
20360 | 312 |