74 static inline void record_virtual_memory_reserve(address addr, size_t size,
75 address pc = 0, Thread* thread = NULL) { }
76 static inline void record_virtual_memory_commit(address addr, size_t size,
77 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,
83 Thread* thread = NULL) { }
84 static inline bool baseline() { return false; }
85 static inline bool has_baseline() { return false; }
86
87 static void shutdown(ShutdownReason reason) { }
88 static inline bool shutdown_in_progress() { }
89 static bool print_memory_usage(BaselineOutputer& out, size_t unit,
90 bool summary_only = true) { }
91 static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
92 bool summary_only = true) { }
93
94 static inline void sync() { }
95 static inline void thread_exiting(JavaThread* thread) { }
96
97 };
98
99
100 #else // !INCLUDE_NMT
101
102 #include "memory/allocation.hpp"
103 #include "runtime/globals.hpp"
104 #include "runtime/mutex.hpp"
105 #include "runtime/os.hpp"
106 #include "runtime/thread.hpp"
107 #include "services/memPtr.hpp"
108 #include "services/memRecorder.hpp"
109 #include "services/memSnapshot.hpp"
110 #include "services/memTrackWorker.hpp"
111
112 extern bool NMT_track_callsite;
113
114 #ifdef ASSERT
115 #define DEBUG_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
116 #else
117 #define DEBUG_CALLER_PC 0
118 #endif
119
120 // The thread closure walks threads to collect per-thread
121 // memory recorders at NMT sync point
122 class SyncThreadRecorderClosure : public ThreadClosure {
123 private:
124 int _thread_count;
125
126 public:
127 SyncThreadRecorderClosure() {
128 _thread_count =0;
129 }
130
131 void do_thread(Thread* thread);
132 int get_thread_count() const {
133 return _thread_count;
363 create_memory_record(base, (flags | MemPointerRecord::virtual_memory_type_tag()),
364 0, DEBUG_CALLER_PC, thread);
365 }
366 }
367
368
369 // create memory baseline of current memory snapshot
370 static bool baseline();
371 // is there a memory baseline
372 static bool has_baseline() {
373 return _baseline.baselined();
374 }
375
376 // print memory usage from current snapshot
377 static bool print_memory_usage(BaselineOutputer& out, size_t unit,
378 bool summary_only = true);
379 // compare memory usage between current snapshot and baseline
380 static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
381 bool summary_only = true);
382
383 // sync is called within global safepoint to synchronize nmt data
384 static void sync();
385
386 // called when a thread is about to exit
387 static void thread_exiting(JavaThread* thread);
388
389 // retrieve global snapshot
390 static MemSnapshot* get_snapshot() {
391 if (shutdown_in_progress()) {
392 return NULL;
393 }
394 return _snapshot;
395 }
396
397 // print tracker stats
398 NOT_PRODUCT(static void print_tracker_stats(outputStream* st);)
399 NOT_PRODUCT(static void walk_stack(int toSkip, char* buf, int len);)
400
401 private:
402 // start native memory tracking worker thread
415
416 // per-thread recorder pool
417 static void release_thread_recorder(MemRecorder* rec);
418 static void delete_all_pooled_recorders();
419
420 // pending recorder queue. Recorders are queued to pending queue
421 // when they are overflowed or collected at nmt sync point.
422 static void enqueue_pending_recorder(MemRecorder* rec);
423 static MemRecorder* get_pending_recorders();
424 static void delete_all_pending_recorders();
425
426 private:
427 // retrieve a pooled memory record or create new one if there is not
428 // one available
429 static MemRecorder* get_new_or_pooled_instance();
430 static void create_memory_record(address addr, MEMFLAGS type,
431 size_t size, address pc, Thread* thread);
432 static void create_record_in_recorder(address addr, MEMFLAGS type,
433 size_t size, address pc, JavaThread* thread);
434
435 private:
436 // global memory snapshot
437 static MemSnapshot* _snapshot;
438
439 // a memory baseline of snapshot
440 static MemBaseline _baseline;
441
442 // query lock
443 static Mutex* _query_lock;
444
445 // a thread can start to allocate memory before it is attached
446 // to VM 'Thread', those memory activities are recorded here.
447 // ThreadCritical is required to guard this global recorder.
448 static MemRecorder* _global_recorder;
449
450 // main thread id
451 debug_only(static intx _main_thread_tid;)
452
453 // pending recorders to be merged
454 static volatile MemRecorder* _merge_pending_queue;
466 static int _thread_count;
467 // pooled recorder count
468 static volatile jint _pooled_recorder_count;
469
470
471 // worker thread to merge pending recorders into snapshot
472 static MemTrackWorker* _worker_thread;
473
474 // how many safepoints we skipped without entering sync point
475 static int _sync_point_skip_count;
476
477 // if the tracker is properly intialized
478 static bool _is_tracker_ready;
479 // tracking level (off, summary and detail)
480 static enum NMTLevel _tracking_level;
481
482 // current nmt state
483 static volatile enum NMTStates _state;
484 // the reason for shutting down nmt
485 static enum ShutdownReason _reason;
486 };
487
488 #endif // !INCLUDE_NMT
489
490 #endif // SHARE_VM_SERVICES_MEM_TRACKER_HPP
|
74 static inline void record_virtual_memory_reserve(address addr, size_t size,
75 address pc = 0, Thread* thread = NULL) { }
76 static inline void record_virtual_memory_commit(address addr, size_t size,
77 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,
83 Thread* thread = NULL) { }
84 static inline bool baseline() { return false; }
85 static inline bool has_baseline() { return false; }
86
87 static void shutdown(ShutdownReason reason) { }
88 static inline bool shutdown_in_progress() { }
89 static bool print_memory_usage(BaselineOutputer& out, size_t unit,
90 bool summary_only = true) { }
91 static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
92 bool summary_only = true) { }
93
94 static bool wbtest_wait_for_data_merge() { }
95
96 static inline void sync() { }
97 static inline void thread_exiting(JavaThread* thread) { }
98 };
99
100
101 #else // !INCLUDE_NMT
102
103 #include "memory/allocation.hpp"
104 #include "runtime/globals.hpp"
105 #include "runtime/mutex.hpp"
106 #include "runtime/os.hpp"
107 #include "runtime/thread.hpp"
108 #include "services/memPtr.hpp"
109 #include "services/memRecorder.hpp"
110 #include "services/memSnapshot.hpp"
111 #include "services/memTrackWorker.hpp"
112
113 extern bool NMT_track_callsite;
114
115 #ifndef MAX_UNSIGNED_LONG
116 #define MAX_UNSIGNED_LONG (unsigned long)(-1)
117 #endif
118
119 #ifdef ASSERT
120 #define DEBUG_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
121 #else
122 #define DEBUG_CALLER_PC 0
123 #endif
124
125 // The thread closure walks threads to collect per-thread
126 // memory recorders at NMT sync point
127 class SyncThreadRecorderClosure : public ThreadClosure {
128 private:
129 int _thread_count;
130
131 public:
132 SyncThreadRecorderClosure() {
133 _thread_count =0;
134 }
135
136 void do_thread(Thread* thread);
137 int get_thread_count() const {
138 return _thread_count;
368 create_memory_record(base, (flags | MemPointerRecord::virtual_memory_type_tag()),
369 0, DEBUG_CALLER_PC, thread);
370 }
371 }
372
373
374 // create memory baseline of current memory snapshot
375 static bool baseline();
376 // is there a memory baseline
377 static bool has_baseline() {
378 return _baseline.baselined();
379 }
380
381 // print memory usage from current snapshot
382 static bool print_memory_usage(BaselineOutputer& out, size_t unit,
383 bool summary_only = true);
384 // compare memory usage between current snapshot and baseline
385 static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
386 bool summary_only = true);
387
388 // the version for whitebox testing support, it ensures that all memory
389 // activities before this method call, are reflected in the snapshot
390 // database.
391 static bool wbtest_wait_for_data_merge();
392
393 // sync is called within global safepoint to synchronize nmt data
394 static void sync();
395
396 // called when a thread is about to exit
397 static void thread_exiting(JavaThread* thread);
398
399 // retrieve global snapshot
400 static MemSnapshot* get_snapshot() {
401 if (shutdown_in_progress()) {
402 return NULL;
403 }
404 return _snapshot;
405 }
406
407 // print tracker stats
408 NOT_PRODUCT(static void print_tracker_stats(outputStream* st);)
409 NOT_PRODUCT(static void walk_stack(int toSkip, char* buf, int len);)
410
411 private:
412 // start native memory tracking worker thread
425
426 // per-thread recorder pool
427 static void release_thread_recorder(MemRecorder* rec);
428 static void delete_all_pooled_recorders();
429
430 // pending recorder queue. Recorders are queued to pending queue
431 // when they are overflowed or collected at nmt sync point.
432 static void enqueue_pending_recorder(MemRecorder* rec);
433 static MemRecorder* get_pending_recorders();
434 static void delete_all_pending_recorders();
435
436 private:
437 // retrieve a pooled memory record or create new one if there is not
438 // one available
439 static MemRecorder* get_new_or_pooled_instance();
440 static void create_memory_record(address addr, MEMFLAGS type,
441 size_t size, address pc, Thread* thread);
442 static void create_record_in_recorder(address addr, MEMFLAGS type,
443 size_t size, address pc, JavaThread* thread);
444
445 static void set_current_processing_generation(unsigned long generation) {
446 _worker_thread_idle = false;
447 _processing_generation = generation;
448 }
449
450 static void report_worker_idle() {
451 _worker_thread_idle = true;
452 }
453
454 private:
455 // global memory snapshot
456 static MemSnapshot* _snapshot;
457
458 // a memory baseline of snapshot
459 static MemBaseline _baseline;
460
461 // query lock
462 static Mutex* _query_lock;
463
464 // a thread can start to allocate memory before it is attached
465 // to VM 'Thread', those memory activities are recorded here.
466 // ThreadCritical is required to guard this global recorder.
467 static MemRecorder* _global_recorder;
468
469 // main thread id
470 debug_only(static intx _main_thread_tid;)
471
472 // pending recorders to be merged
473 static volatile MemRecorder* _merge_pending_queue;
485 static int _thread_count;
486 // pooled recorder count
487 static volatile jint _pooled_recorder_count;
488
489
490 // worker thread to merge pending recorders into snapshot
491 static MemTrackWorker* _worker_thread;
492
493 // how many safepoints we skipped without entering sync point
494 static int _sync_point_skip_count;
495
496 // if the tracker is properly intialized
497 static bool _is_tracker_ready;
498 // tracking level (off, summary and detail)
499 static enum NMTLevel _tracking_level;
500
501 // current nmt state
502 static volatile enum NMTStates _state;
503 // the reason for shutting down nmt
504 static enum ShutdownReason _reason;
505 // the generation that NMT is processing
506 static volatile unsigned long _processing_generation;
507 // although NMT is still procesing current generation, but
508 // there is not more recorder to process, set idle state
509 static volatile bool _worker_thread_idle;
510 };
511
512 #endif // !INCLUDE_NMT
513
514 #endif // SHARE_VM_SERVICES_MEM_TRACKER_HPP
|