Mercurial > hg > truffle
annotate src/share/vm/services/memBaseline.hpp @ 14517:3812c088b945
Merge
author | lana |
---|---|
date | Thu, 06 Mar 2014 10:37:26 -0800 |
parents | fbca7eaeac2e |
children | 833b0f92429a |
rev | line source |
---|---|
6197 | 1 /* |
10148 | 2 * Copyright (c) 2012, 2013, 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_BASELINE_HPP | |
26 #define SHARE_VM_SERVICES_MEM_BASELINE_HPP | |
27 | |
28 #include "memory/allocation.hpp" | |
29 #include "runtime/mutex.hpp" | |
30 #include "services/memPtr.hpp" | |
31 #include "services/memSnapshot.hpp" | |
32 | |
33 // compare unsigned number | |
34 #define UNSIGNED_COMPARE(a, b) ((a > b) ? 1 : ((a == b) ? 0 : -1)) | |
35 | |
36 /* | |
37 * MallocCallsitePointer and VMCallsitePointer are used | |
38 * to baseline memory blocks with their callsite information. | |
39 * They are only available when detail tracking is turned | |
40 * on. | |
41 */ | |
42 | |
43 /* baselined malloc record aggregated by callsite */ | |
44 class MallocCallsitePointer : public MemPointer { | |
45 private: | |
46 size_t _count; // number of malloc invocation from this callsite | |
47 size_t _amount; // total amount of memory malloc-ed from this callsite | |
48 | |
49 public: | |
50 MallocCallsitePointer() { | |
51 _count = 0; | |
52 _amount = 0; | |
53 } | |
54 | |
55 MallocCallsitePointer(address pc) : MemPointer(pc) { | |
56 _count = 0; | |
57 _amount = 0; | |
58 } | |
59 | |
60 MallocCallsitePointer& operator=(const MallocCallsitePointer& p) { | |
61 MemPointer::operator=(p); | |
62 _count = p.count(); | |
63 _amount = p.amount(); | |
64 return *this; | |
65 } | |
66 | |
67 inline void inc(size_t size) { | |
68 _count ++; | |
69 _amount += size; | |
70 }; | |
71 | |
72 inline size_t count() const { | |
73 return _count; | |
74 } | |
75 | |
76 inline size_t amount() const { | |
77 return _amount; | |
78 } | |
79 }; | |
80 | |
81 // baselined virtual memory record aggregated by callsite | |
82 class VMCallsitePointer : public MemPointer { | |
83 private: | |
84 size_t _count; // number of invocation from this callsite | |
85 size_t _reserved_amount; // total reserved amount | |
86 size_t _committed_amount; // total committed amount | |
87 | |
88 public: | |
89 VMCallsitePointer() { | |
90 _count = 0; | |
91 _reserved_amount = 0; | |
92 _committed_amount = 0; | |
93 } | |
94 | |
95 VMCallsitePointer(address pc) : MemPointer(pc) { | |
96 _count = 0; | |
97 _reserved_amount = 0; | |
98 _committed_amount = 0; | |
99 } | |
100 | |
101 VMCallsitePointer& operator=(const VMCallsitePointer& p) { | |
102 MemPointer::operator=(p); | |
103 _count = p.count(); | |
104 _reserved_amount = p.reserved_amount(); | |
105 _committed_amount = p.committed_amount(); | |
106 return *this; | |
107 } | |
108 | |
109 inline void inc(size_t reserved, size_t committed) { | |
110 _count ++; | |
111 _reserved_amount += reserved; | |
112 _committed_amount += committed; | |
113 } | |
114 | |
115 inline size_t count() const { | |
116 return _count; | |
117 } | |
118 | |
119 inline size_t reserved_amount() const { | |
120 return _reserved_amount; | |
121 } | |
122 | |
123 inline size_t committed_amount() const { | |
124 return _committed_amount; | |
125 } | |
126 }; | |
127 | |
128 // maps a memory type flag to readable name | |
129 typedef struct _memType2Name { | |
130 MEMFLAGS _flag; | |
131 const char* _name; | |
132 } MemType2Name; | |
133 | |
134 | |
135 // This class aggregates malloc'd records by memory type | |
10127
b80cc96882f7
8012464: NMT: classes should not derive from _ValueObj, use VALUE_OBJ_CLASS_SPEC instead
zgu
parents:
7434
diff
changeset
|
136 class MallocMem VALUE_OBJ_CLASS_SPEC { |
6197 | 137 private: |
138 MEMFLAGS _type; | |
139 | |
140 size_t _count; | |
141 size_t _amount; | |
142 | |
143 public: | |
144 MallocMem() { | |
145 _type = mtNone; | |
146 _count = 0; | |
147 _amount = 0; | |
148 } | |
149 | |
150 MallocMem(MEMFLAGS flags) { | |
151 assert(HAS_VALID_MEMORY_TYPE(flags), "no type"); | |
152 _type = FLAGS_TO_MEMORY_TYPE(flags); | |
153 _count = 0; | |
154 _amount = 0; | |
155 } | |
156 | |
157 inline void set_type(MEMFLAGS flag) { | |
158 _type = flag; | |
159 } | |
160 | |
161 inline void clear() { | |
162 _count = 0; | |
163 _amount = 0; | |
164 _type = mtNone; | |
165 } | |
166 | |
167 MallocMem& operator=(const MallocMem& m) { | |
168 assert(_type == m.type(), "different type"); | |
169 _count = m.count(); | |
170 _amount = m.amount(); | |
171 return *this; | |
172 } | |
173 | |
174 inline void inc(size_t amt) { | |
175 _amount += amt; | |
176 _count ++; | |
177 } | |
178 | |
179 inline void reduce(size_t amt) { | |
180 assert(_amount >= amt, "Just check"); | |
181 _amount -= amt; | |
182 } | |
183 | |
184 inline void overwrite_counter(size_t count) { | |
185 _count = count; | |
186 } | |
187 | |
188 inline MEMFLAGS type() const { | |
189 return _type; | |
190 } | |
191 | |
192 inline bool is_type(MEMFLAGS flags) const { | |
193 return FLAGS_TO_MEMORY_TYPE(flags) == _type; | |
194 } | |
195 | |
196 inline size_t count() const { | |
197 return _count; | |
198 } | |
199 | |
200 inline size_t amount() const { | |
201 return _amount; | |
202 } | |
203 }; | |
204 | |
205 // This class records live arena's memory usage | |
206 class ArenaMem : public MallocMem { | |
207 public: | |
208 ArenaMem(MEMFLAGS typeflag): MallocMem(typeflag) { | |
209 } | |
210 ArenaMem() { } | |
211 }; | |
212 | |
213 // This class aggregates virtual memory by its memory type | |
10127
b80cc96882f7
8012464: NMT: classes should not derive from _ValueObj, use VALUE_OBJ_CLASS_SPEC instead
zgu
parents:
7434
diff
changeset
|
214 class VMMem VALUE_OBJ_CLASS_SPEC { |
6197 | 215 private: |
216 MEMFLAGS _type; | |
217 | |
218 size_t _count; | |
219 size_t _reserved_amount; | |
220 size_t _committed_amount; | |
221 | |
222 public: | |
223 VMMem() { | |
224 _type = mtNone; | |
225 _count = 0; | |
226 _reserved_amount = 0; | |
227 _committed_amount = 0; | |
228 } | |
229 | |
230 VMMem(MEMFLAGS flags) { | |
231 assert(HAS_VALID_MEMORY_TYPE(flags), "no type"); | |
232 _type = FLAGS_TO_MEMORY_TYPE(flags); | |
233 _count = 0; | |
234 _reserved_amount = 0; | |
235 _committed_amount = 0; | |
236 } | |
237 | |
238 inline void clear() { | |
239 _type = mtNone; | |
240 _count = 0; | |
241 _reserved_amount = 0; | |
242 _committed_amount = 0; | |
243 } | |
244 | |
245 inline void set_type(MEMFLAGS flags) { | |
246 _type = FLAGS_TO_MEMORY_TYPE(flags); | |
247 } | |
248 | |
249 VMMem& operator=(const VMMem& m) { | |
250 assert(_type == m.type(), "different type"); | |
251 | |
252 _count = m.count(); | |
253 _reserved_amount = m.reserved_amount(); | |
254 _committed_amount = m.committed_amount(); | |
255 return *this; | |
256 } | |
257 | |
258 | |
259 inline MEMFLAGS type() const { | |
260 return _type; | |
261 } | |
262 | |
263 inline bool is_type(MEMFLAGS flags) const { | |
264 return FLAGS_TO_MEMORY_TYPE(flags) == _type; | |
265 } | |
266 | |
267 inline void inc(size_t reserved_amt, size_t committed_amt) { | |
268 _reserved_amount += reserved_amt; | |
269 _committed_amount += committed_amt; | |
270 _count ++; | |
271 } | |
272 | |
273 inline size_t count() const { | |
274 return _count; | |
275 } | |
276 | |
277 inline size_t reserved_amount() const { | |
278 return _reserved_amount; | |
279 } | |
280 | |
281 inline size_t committed_amount() const { | |
282 return _committed_amount; | |
283 } | |
284 }; | |
285 | |
286 | |
287 | |
288 #define NUMBER_OF_MEMORY_TYPE (mt_number_of_types + 1) | |
289 | |
290 class BaselineReporter; | |
291 class BaselineComparisonReporter; | |
292 | |
293 /* | |
294 * This class baselines current memory snapshot. | |
295 * A memory baseline summarizes memory usage by memory type, | |
296 * aggregates memory usage by callsites when detail tracking | |
297 * is on. | |
298 */ | |
10127
b80cc96882f7
8012464: NMT: classes should not derive from _ValueObj, use VALUE_OBJ_CLASS_SPEC instead
zgu
parents:
7434
diff
changeset
|
299 class MemBaseline VALUE_OBJ_CLASS_SPEC { |
6197 | 300 friend class BaselineReporter; |
301 friend class BaselineComparisonReporter; | |
302 | |
303 private: | |
304 // overall summaries | |
305 size_t _total_malloced; | |
306 size_t _total_vm_reserved; | |
307 size_t _total_vm_committed; | |
308 size_t _number_of_classes; | |
309 size_t _number_of_threads; | |
310 | |
311 // if it has properly baselined | |
312 bool _baselined; | |
313 | |
314 // we categorize memory into three categories within the memory type | |
315 MallocMem _malloc_data[NUMBER_OF_MEMORY_TYPE]; | |
316 VMMem _vm_data[NUMBER_OF_MEMORY_TYPE]; | |
317 ArenaMem _arena_data[NUMBER_OF_MEMORY_TYPE]; | |
318 | |
319 // memory records that aggregate memory usage by callsites. | |
320 // only available when detail tracking is on. | |
321 MemPointerArray* _malloc_cs; | |
322 MemPointerArray* _vm_cs; | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
323 // virtual memory map |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6197
diff
changeset
|
324 MemPointerArray* _vm_map; |
6197 | 325 |
326 private: | |
327 static MemType2Name MemType2NameMap[NUMBER_OF_MEMORY_TYPE]; | |
328 | |
329 private: | |
330 // should not use copy constructor | |
331 MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); } | |
332 | |
10148 | 333 // check and block at a safepoint |
334 static inline void check_safepoint(JavaThread* thr); | |
335 | |
6197 | 336 public: |
337 // create a memory baseline | |
338 MemBaseline(); | |
339 | |
7434
32164d89fe9c
8004845: Catch incorrect usage of new and delete during compile time for value objects and stack objects
brutisso
parents:
6882
diff
changeset
|
340 ~MemBaseline(); |
6197 | 341 |
342 inline bool baselined() const { | |
343 return _baselined; | |
344 } | |
345 | |
346 MemBaseline& operator=(const MemBaseline& other); | |
347 | |
348 // reset the baseline for reuse | |
349 void clear(); | |
350 | |
351 // baseline the snapshot | |
352 bool baseline(MemSnapshot& snapshot, bool summary_only = true); | |
353 | |
354 bool baseline(const MemPointerArray* malloc_records, | |
355 const MemPointerArray* vm_records, | |
356 bool summary_only = true); | |
357 | |
358 // total malloc'd memory of specified memory type | |
359 inline size_t malloc_amount(MEMFLAGS flag) const { | |
360 return _malloc_data[flag2index(flag)].amount(); | |
361 } | |
362 // number of malloc'd memory blocks of specified memory type | |
363 inline size_t malloc_count(MEMFLAGS flag) const { | |
364 return _malloc_data[flag2index(flag)].count(); | |
365 } | |
366 // total memory used by arenas of specified memory type | |
367 inline size_t arena_amount(MEMFLAGS flag) const { | |
368 return _arena_data[flag2index(flag)].amount(); | |
369 } | |
370 // number of arenas of specified memory type | |
371 inline size_t arena_count(MEMFLAGS flag) const { | |
372 return _arena_data[flag2index(flag)].count(); | |
373 } | |
374 // total reserved memory of specified memory type | |
375 inline size_t reserved_amount(MEMFLAGS flag) const { | |
376 return _vm_data[flag2index(flag)].reserved_amount(); | |
377 } | |
378 // total committed memory of specified memory type | |
379 inline size_t committed_amount(MEMFLAGS flag) const { | |
380 return _vm_data[flag2index(flag)].committed_amount(); | |
381 } | |
382 // total memory (malloc'd + mmap'd + arena) of specified | |
383 // memory type | |
384 inline size_t total_amount(MEMFLAGS flag) const { | |
385 int index = flag2index(flag); | |
386 return _malloc_data[index].amount() + | |
387 _vm_data[index].reserved_amount() + | |
388 _arena_data[index].amount(); | |
389 } | |
390 | |
391 /* overall summaries */ | |
392 | |
393 // total malloc'd memory in snapshot | |
394 inline size_t total_malloc_amount() const { | |
395 return _total_malloced; | |
396 } | |
397 // total mmap'd memory in snapshot | |
398 inline size_t total_reserved_amount() const { | |
399 return _total_vm_reserved; | |
400 } | |
401 // total committed memory in snapshot | |
402 inline size_t total_committed_amount() const { | |
403 return _total_vm_committed; | |
404 } | |
405 // number of loaded classes | |
406 inline size_t number_of_classes() const { | |
407 return _number_of_classes; | |
408 } | |
409 // number of running threads | |
410 inline size_t number_of_threads() const { | |
411 return _number_of_threads; | |
412 } | |
413 // lookup human readable name of a memory type | |
414 static const char* type2name(MEMFLAGS type); | |
415 | |
416 private: | |
417 // convert memory flag to the index to mapping table | |
418 int flag2index(MEMFLAGS flag) const; | |
419 | |
420 // reset baseline values | |
421 void reset(); | |
422 | |
423 // summarize the records in global snapshot | |
424 bool baseline_malloc_summary(const MemPointerArray* malloc_records); | |
425 bool baseline_vm_summary(const MemPointerArray* vm_records); | |
426 bool baseline_malloc_details(const MemPointerArray* malloc_records); | |
427 bool baseline_vm_details(const MemPointerArray* vm_records); | |
428 | |
429 // print a line of malloc'd memory aggregated by callsite | |
430 void print_malloc_callsite(outputStream* st, address pc, size_t size, | |
431 size_t count, int diff_amt, int diff_count) const; | |
432 // print a line of mmap'd memory aggregated by callsite | |
433 void print_vm_callsite(outputStream* st, address pc, size_t rsz, | |
434 size_t csz, int diff_rsz, int diff_csz) const; | |
435 | |
436 // sorting functions for raw records | |
437 static int malloc_sort_by_pc(const void* p1, const void* p2); | |
438 static int malloc_sort_by_addr(const void* p1, const void* p2); | |
439 | |
440 private: | |
441 // sorting functions for baselined records | |
442 static int bl_malloc_sort_by_size(const void* p1, const void* p2); | |
443 static int bl_vm_sort_by_size(const void* p1, const void* p2); | |
444 static int bl_malloc_sort_by_pc(const void* p1, const void* p2); | |
445 static int bl_vm_sort_by_pc(const void* p1, const void* p2); | |
446 }; | |
447 | |
448 | |
449 #endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP |