66 static inline void start() { } |
78 static inline void start() { } |
67 |
79 |
68 static inline void record_malloc(address addr, size_t size, MEMFLAGS flags, |
80 static inline void record_malloc(address addr, size_t size, MEMFLAGS flags, |
69 address pc = 0, Thread* thread = NULL) { } |
81 address pc = 0, Thread* thread = NULL) { } |
70 static inline void record_free(address addr, MEMFLAGS flags, Thread* thread = NULL) { } |
82 static inline void record_free(address addr, MEMFLAGS flags, Thread* thread = NULL) { } |
71 static inline void record_realloc(address old_addr, address new_addr, size_t size, |
|
72 MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { } |
|
73 static inline void record_arena_size(address addr, size_t size) { } |
83 static inline void record_arena_size(address addr, size_t size) { } |
74 static inline void record_virtual_memory_reserve(address addr, size_t size, |
84 static inline void record_virtual_memory_reserve(address addr, size_t size, |
75 address pc = 0, Thread* thread = NULL) { } |
85 MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { } |
|
86 static inline void record_virtual_memory_reserve_and_commit(address addr, size_t size, |
|
87 MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { } |
76 static inline void record_virtual_memory_commit(address addr, size_t size, |
88 static inline void record_virtual_memory_commit(address addr, size_t size, |
77 address pc = 0, Thread* thread = NULL) { } |
89 address pc = 0, Thread* thread = NULL) { } |
78 static inline void record_virtual_memory_uncommit(address addr, size_t size, |
|
79 Thread* thread = NULL) { } |
|
80 static inline void record_virtual_memory_release(address addr, size_t size, |
|
81 Thread* thread = NULL) { } |
|
82 static inline void record_virtual_memory_type(address base, MEMFLAGS flags, |
90 static inline void record_virtual_memory_type(address base, MEMFLAGS flags, |
83 Thread* thread = NULL) { } |
91 Thread* thread = NULL) { } |
|
92 static inline Tracker get_realloc_tracker() { return _tkr; } |
|
93 static inline Tracker get_virtual_memory_uncommit_tracker() { return _tkr; } |
|
94 static inline Tracker get_virtual_memory_release_tracker() { return _tkr; } |
84 static inline bool baseline() { return false; } |
95 static inline bool baseline() { return false; } |
85 static inline bool has_baseline() { return false; } |
96 static inline bool has_baseline() { return false; } |
86 |
97 |
87 static inline void set_autoShutdown(bool value) { } |
98 static inline void set_autoShutdown(bool value) { } |
88 static void shutdown(ShutdownReason reason) { } |
99 static void shutdown(ShutdownReason reason) { } |
161 NMT_started, // NMT fully started |
172 NMT_started, // NMT fully started |
162 NMT_shutdown_pending, // shutdown pending |
173 NMT_shutdown_pending, // shutdown pending |
163 NMT_final_shutdown, // in final phase of shutdown |
174 NMT_final_shutdown, // in final phase of shutdown |
164 NMT_shutdown // shutdown |
175 NMT_shutdown // shutdown |
165 }; |
176 }; |
|
177 |
|
178 public: |
|
179 class Tracker : public StackObj { |
|
180 friend class MemTracker; |
|
181 public: |
|
182 enum MemoryOperation { |
|
183 NoOp, // no op |
|
184 Malloc, // malloc |
|
185 Realloc, // realloc |
|
186 Free, // free |
|
187 Reserve, // virtual memory reserve |
|
188 Commit, // virtual memory commit |
|
189 ReserveAndCommit, // virtual memory reserve and commit |
|
190 StackAlloc = ReserveAndCommit, // allocate thread stack |
|
191 Type, // assign virtual memory type |
|
192 Uncommit, // virtual memory uncommit |
|
193 Release, // virtual memory release |
|
194 ArenaSize, // set arena size |
|
195 StackRelease // release thread stack |
|
196 }; |
|
197 |
|
198 |
|
199 protected: |
|
200 Tracker(MemoryOperation op, Thread* thr = NULL); |
|
201 |
|
202 public: |
|
203 void discard(); |
|
204 |
|
205 void record(address addr, size_t size = 0, MEMFLAGS flags = mtNone, address pc = NULL); |
|
206 void record(address old_addr, address new_addr, size_t size, |
|
207 MEMFLAGS flags, address pc = NULL); |
|
208 |
|
209 private: |
|
210 bool _need_thread_critical_lock; |
|
211 JavaThread* _java_thread; |
|
212 MemoryOperation _op; // memory operation |
|
213 jint _seq; // reserved sequence number |
|
214 }; |
|
215 |
166 |
216 |
167 public: |
217 public: |
168 // native memory tracking level |
218 // native memory tracking level |
169 enum NMTLevel { |
219 enum NMTLevel { |
170 NMT_off, // native memory tracking is off |
220 NMT_off, // native memory tracking is off |
274 static void start(); |
324 static void start(); |
275 |
325 |
276 // record a 'malloc' call |
326 // record a 'malloc' call |
277 static inline void record_malloc(address addr, size_t size, MEMFLAGS flags, |
327 static inline void record_malloc(address addr, size_t size, MEMFLAGS flags, |
278 address pc = 0, Thread* thread = NULL) { |
328 address pc = 0, Thread* thread = NULL) { |
279 if (is_on() && NMT_CAN_TRACK(flags)) { |
329 Tracker tkr(Tracker::Malloc, thread); |
280 assert(size > 0, "Sanity check"); |
330 tkr.record(addr, size, flags, pc); |
281 create_memory_record(addr, (flags|MemPointerRecord::malloc_tag()), size, pc, thread); |
|
282 } |
|
283 } |
331 } |
284 // record a 'free' call |
332 // record a 'free' call |
285 static inline void record_free(address addr, MEMFLAGS flags, Thread* thread = NULL) { |
333 static inline void record_free(address addr, MEMFLAGS flags, Thread* thread = NULL) { |
286 if (is_on() && NMT_CAN_TRACK(flags)) { |
334 Tracker tkr(Tracker::Free, thread); |
287 create_memory_record(addr, MemPointerRecord::free_tag(), 0, 0, thread); |
335 tkr.record(addr, 0, flags, DEBUG_CALLER_PC); |
288 } |
336 } |
289 } |
337 |
290 // record a 'realloc' call |
|
291 static inline void record_realloc(address old_addr, address new_addr, size_t size, |
|
292 MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { |
|
293 if (is_on() && NMT_CAN_TRACK(flags)) { |
|
294 assert(size > 0, "Sanity check"); |
|
295 record_free(old_addr, flags, thread); |
|
296 record_malloc(new_addr, size, flags, pc, thread); |
|
297 } |
|
298 } |
|
299 |
|
300 // record arena memory size |
|
301 static inline void record_arena_size(address addr, size_t size) { |
338 static inline void record_arena_size(address addr, size_t size) { |
302 // we add a positive offset to arena address, so we can have arena memory record |
339 Tracker tkr(Tracker::ArenaSize); |
303 // sorted after arena record |
340 tkr.record(addr, size); |
304 if (is_on() && !UseMallocOnly) { |
|
305 assert(addr != NULL, "Sanity check"); |
|
306 create_memory_record((addr + sizeof(void*)), MemPointerRecord::arena_size_tag(), size, |
|
307 DEBUG_CALLER_PC, NULL); |
|
308 } |
|
309 } |
341 } |
310 |
342 |
311 // record a virtual memory 'reserve' call |
343 // record a virtual memory 'reserve' call |
312 static inline void record_virtual_memory_reserve(address addr, size_t size, |
344 static inline void record_virtual_memory_reserve(address addr, size_t size, |
313 address pc = 0, Thread* thread = NULL) { |
345 MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { |
314 if (is_on()) { |
346 assert(size > 0, "Sanity check"); |
315 assert(size > 0, "Sanity check"); |
347 Tracker tkr(Tracker::Reserve, thread); |
316 create_memory_record(addr, MemPointerRecord::virtual_memory_reserve_tag(), |
348 tkr.record(addr, size, flags, pc); |
317 size, pc, thread); |
|
318 } |
|
319 } |
349 } |
320 |
350 |
321 static inline void record_thread_stack(address addr, size_t size, Thread* thr, |
351 static inline void record_thread_stack(address addr, size_t size, Thread* thr, |
322 address pc = 0) { |
352 address pc = 0) { |
323 if (is_on()) { |
353 Tracker tkr(Tracker::StackAlloc, thr); |
324 assert(size > 0 && thr != NULL, "Sanity check"); |
354 tkr.record(addr, size, mtThreadStack, pc); |
325 create_memory_record(addr, MemPointerRecord::virtual_memory_reserve_tag() | mtThreadStack, |
|
326 size, pc, thr); |
|
327 create_memory_record(addr, MemPointerRecord::virtual_memory_commit_tag() | mtThreadStack, |
|
328 size, pc, thr); |
|
329 } |
|
330 } |
355 } |
331 |
356 |
332 static inline void release_thread_stack(address addr, size_t size, Thread* thr) { |
357 static inline void release_thread_stack(address addr, size_t size, Thread* thr) { |
333 if (is_on()) { |
358 Tracker tkr(Tracker::StackRelease, thr); |
334 assert(size > 0 && thr != NULL, "Sanity check"); |
359 tkr.record(addr, size, mtThreadStack, DEBUG_CALLER_PC); |
335 assert(!thr->is_Java_thread(), "too early"); |
|
336 create_memory_record(addr, MemPointerRecord::virtual_memory_uncommit_tag() | mtThreadStack, |
|
337 size, DEBUG_CALLER_PC, thr); |
|
338 create_memory_record(addr, MemPointerRecord::virtual_memory_release_tag() | mtThreadStack, |
|
339 size, DEBUG_CALLER_PC, thr); |
|
340 } |
|
341 } |
360 } |
342 |
361 |
343 // record a virtual memory 'commit' call |
362 // record a virtual memory 'commit' call |
344 static inline void record_virtual_memory_commit(address addr, size_t size, |
363 static inline void record_virtual_memory_commit(address addr, size_t size, |
345 address pc, Thread* thread = NULL) { |
364 address pc, Thread* thread = NULL) { |
346 if (is_on()) { |
365 Tracker tkr(Tracker::Commit, thread); |
347 assert(size > 0, "Sanity check"); |
366 tkr.record(addr, size, mtNone, pc); |
348 create_memory_record(addr, MemPointerRecord::virtual_memory_commit_tag(), |
367 } |
349 size, pc, thread); |
368 |
350 } |
369 static inline void record_virtual_memory_reserve_and_commit(address addr, size_t size, |
351 } |
370 MEMFLAGS flags, address pc, Thread* thread = NULL) { |
352 |
371 Tracker tkr(Tracker::ReserveAndCommit, thread); |
353 // record a virtual memory 'uncommit' call |
372 tkr.record(addr, size, flags, pc); |
354 static inline void record_virtual_memory_uncommit(address addr, size_t size, |
373 } |
355 Thread* thread = NULL) { |
374 |
356 if (is_on()) { |
|
357 assert(size > 0, "Sanity check"); |
|
358 create_memory_record(addr, MemPointerRecord::virtual_memory_uncommit_tag(), |
|
359 size, DEBUG_CALLER_PC, thread); |
|
360 } |
|
361 } |
|
362 |
|
363 // record a virtual memory 'release' call |
|
364 static inline void record_virtual_memory_release(address addr, size_t size, |
|
365 Thread* thread = NULL) { |
|
366 if (is_on()) { |
|
367 assert(size > 0, "Sanity check"); |
|
368 create_memory_record(addr, MemPointerRecord::virtual_memory_release_tag(), |
|
369 size, DEBUG_CALLER_PC, thread); |
|
370 } |
|
371 } |
|
372 |
375 |
373 // record memory type on virtual memory base address |
376 // record memory type on virtual memory base address |
374 static inline void record_virtual_memory_type(address base, MEMFLAGS flags, |
377 static inline void record_virtual_memory_type(address base, MEMFLAGS flags, |
375 Thread* thread = NULL) { |
378 Thread* thread = NULL) { |
376 if (is_on()) { |
379 Tracker tkr(Tracker::Type); |
377 assert(base > 0, "wrong base address"); |
380 tkr.record(base, 0, flags); |
378 assert((flags & (~mt_masks)) == 0, "memory type only"); |
381 } |
379 create_memory_record(base, (flags | MemPointerRecord::virtual_memory_type_tag()), |
382 |
380 0, DEBUG_CALLER_PC, thread); |
383 // Get memory trackers for memory operations that can result race conditions. |
381 } |
384 // The memory tracker has to be obtained before realloc, virtual memory uncommit |
|
385 // and virtual memory release, and call tracker.record() method if operation |
|
386 // succeeded, or tracker.discard() to abort the tracking. |
|
387 static inline Tracker get_realloc_tracker() { |
|
388 return Tracker(Tracker::Realloc); |
|
389 } |
|
390 |
|
391 static inline Tracker get_virtual_memory_uncommit_tracker() { |
|
392 return Tracker(Tracker::Uncommit); |
|
393 } |
|
394 |
|
395 static inline Tracker get_virtual_memory_release_tracker() { |
|
396 return Tracker(Tracker::Release); |
382 } |
397 } |
383 |
398 |
384 |
399 |
385 // create memory baseline of current memory snapshot |
400 // create memory baseline of current memory snapshot |
386 static bool baseline(); |
401 static bool baseline(); |