97 // the other thread obtains and records the same region that is just 'released' by current
98 // thread but before it can record the operation.
99 class Tracker : public StackObj {
100 public:
101 enum TrackerType {
102 uncommit,
103 release
104 };
105
106 public:
107 Tracker(enum TrackerType type) : _type(type) { }
108 void record(address addr, size_t size);
109 private:
110 enum TrackerType _type;
111 // Virtual memory tracking data structures are protected by ThreadCritical lock.
112 ThreadCritical _tc;
113 };
114
115 class MemTracker : AllStatic {
116 friend class VirtualMemoryTrackerTest;
117
118 public:
119 static inline NMT_TrackingLevel tracking_level() {
120 if (_tracking_level == NMT_unknown) {
121 // No fencing is needed here, since JVM is in single-threaded
122 // mode.
123 _tracking_level = init_tracking_level();
124 _cmdline_tracking_level = _tracking_level;
125 }
126 return _tracking_level;
127 }
128
129 // A late initialization, for the stuff(s) can not be
130 // done in init_tracking_level(), which can NOT malloc
131 // any memory.
132 static void init();
133
134 // Shutdown native memory tracking
135 static void shutdown();
136
137 // Verify native memory tracking command line option.
224
225 static inline void record_virtual_memory_commit(void* addr, size_t size,
226 const NativeCallStack& stack) {
227 if (tracking_level() < NMT_summary) return;
228 if (addr != NULL) {
229 ThreadCritical tc;
230 if (tracking_level() < NMT_summary) return;
231 VirtualMemoryTracker::add_committed_region((address)addr, size, stack);
232 }
233 }
234
235 static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) {
236 if (tracking_level() < NMT_summary) return;
237 if (addr != NULL) {
238 ThreadCritical tc;
239 if (tracking_level() < NMT_summary) return;
240 VirtualMemoryTracker::set_reserved_region_type((address)addr, flag);
241 }
242 }
243
244 static inline void record_thread_stack(void* addr, size_t size) {
245 if (tracking_level() < NMT_summary) return;
246 if (addr != NULL) {
247 // uses thread stack malloc slot for book keeping number of threads
248 MallocMemorySummary::record_malloc(0, mtThreadStack);
249 record_virtual_memory_reserve(addr, size, CALLER_PC, mtThreadStack);
250 }
251 }
252
253 static inline void release_thread_stack(void* addr, size_t size) {
254 if (tracking_level() < NMT_summary) return;
255 if (addr != NULL) {
256 // uses thread stack malloc slot for book keeping number of threads
257 MallocMemorySummary::record_free(0, mtThreadStack);
258 ThreadCritical tc;
259 if (tracking_level() < NMT_summary) return;
260 VirtualMemoryTracker::remove_released_region((address)addr, size);
261 }
262 }
263
264 // Query lock is used to synchronize the access to tracking data.
265 // So far, it is only used by JCmd query, but it may be used by
266 // other tools.
267 static inline Mutex* query_lock() { return _query_lock; }
268
269 // Make a final report or report for hs_err file.
270 static void error_report(outputStream* output) {
271 if (tracking_level() >= NMT_summary) {
272 report(true, output); // just print summary for error case.
273 }
274 }
275
276 static void final_report(outputStream* output) {
277 NMT_TrackingLevel level = tracking_level();
278 if (level >= NMT_summary) {
279 report(level == NMT_summary, output);
280 }
281 }
282
|
97 // the other thread obtains and records the same region that is just 'released' by current
98 // thread but before it can record the operation.
99 class Tracker : public StackObj {
100 public:
101 enum TrackerType {
102 uncommit,
103 release
104 };
105
106 public:
107 Tracker(enum TrackerType type) : _type(type) { }
108 void record(address addr, size_t size);
109 private:
110 enum TrackerType _type;
111 // Virtual memory tracking data structures are protected by ThreadCritical lock.
112 ThreadCritical _tc;
113 };
114
115 class MemTracker : AllStatic {
116 friend class VirtualMemoryTrackerTest;
117 public:
118 static inline NMT_TrackingLevel tracking_level() {
119 if (_tracking_level == NMT_unknown) {
120 // No fencing is needed here, since JVM is in single-threaded
121 // mode.
122 _tracking_level = init_tracking_level();
123 _cmdline_tracking_level = _tracking_level;
124 }
125 return _tracking_level;
126 }
127
128 // A late initialization, for the stuff(s) can not be
129 // done in init_tracking_level(), which can NOT malloc
130 // any memory.
131 static void init();
132
133 // Shutdown native memory tracking
134 static void shutdown();
135
136 // Verify native memory tracking command line option.
223
224 static inline void record_virtual_memory_commit(void* addr, size_t size,
225 const NativeCallStack& stack) {
226 if (tracking_level() < NMT_summary) return;
227 if (addr != NULL) {
228 ThreadCritical tc;
229 if (tracking_level() < NMT_summary) return;
230 VirtualMemoryTracker::add_committed_region((address)addr, size, stack);
231 }
232 }
233
234 static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) {
235 if (tracking_level() < NMT_summary) return;
236 if (addr != NULL) {
237 ThreadCritical tc;
238 if (tracking_level() < NMT_summary) return;
239 VirtualMemoryTracker::set_reserved_region_type((address)addr, flag);
240 }
241 }
242
243 static void record_thread_stack(void* addr, size_t size);
244
245 static void release_thread_stack(void* addr, size_t size);
246
247 // Query lock is used to synchronize the access to tracking data.
248 // So far, it is only used by JCmd query, but it may be used by
249 // other tools.
250 static inline Mutex* query_lock() { return _query_lock; }
251
252 // Make a final report or report for hs_err file.
253 static void error_report(outputStream* output) {
254 if (tracking_level() >= NMT_summary) {
255 report(true, output); // just print summary for error case.
256 }
257 }
258
259 static void final_report(outputStream* output) {
260 NMT_TrackingLevel level = tracking_level();
261 if (level >= NMT_summary) {
262 report(level == NMT_summary, output);
263 }
264 }
265
|