51
51
#include " utilities/quickSort.hpp"
52
52
#include " utilities/resourceHash.hpp"
53
53
54
- ArenaStatCounter::ArenaStatCounter () :
55
- _current(0 ), _start(0 ), _peak(0 ),
56
- _na(0 ), _ra(0 ),
57
- _limit(0 ), _hit_limit(false ), _limit_in_process(false ),
58
- _na_at_peak(0 ), _ra_at_peak(0 ), _live_nodes_at_peak(0 )
59
- {}
60
-
61
- size_t ArenaStatCounter::peak_since_start () const {
62
- return _peak > _start ? _peak - _start : 0 ;
54
+ ArenaStatCounter::ArenaStatCounter () {
55
+ reset ();
56
+ }
57
+
58
+ void ArenaStatCounter::reset () {
59
+ _current = 0 ;
60
+ _peak = 0 ;
61
+ _current_by_tag.clear ();
62
+ _peak_by_tag.clear ();
63
+ _limit = 0 ;
64
+ _hit_limit = false ;
65
+ _limit_in_process = false ;
66
+ _live_nodes_at_peak = 0 ;
67
+ _active = false ;
63
68
}
64
69
65
70
void ArenaStatCounter::start (size_t limit) {
66
- _peak = _start = _current;
71
+ reset ();
72
+ _active = true ;
67
73
_limit = limit;
68
- _hit_limit = false ;
69
74
}
70
75
71
- void ArenaStatCounter::end (){
76
+ void ArenaStatCounter::end () {
72
77
_limit = 0 ;
73
78
_hit_limit = false ;
79
+ _active = false ;
74
80
}
75
81
76
82
void ArenaStatCounter::update_c2_node_count () {
83
+ assert (_active, " compilaton has not yet started" );
77
84
#ifdef COMPILER2
78
85
CompilerThread* const th = Thread::current ()->as_Compiler_thread ();
79
86
const CompileTask* const task = th->task ();
@@ -90,43 +97,43 @@ void ArenaStatCounter::update_c2_node_count() {
90
97
91
98
// Account an arena allocation or de-allocation.
92
99
bool ArenaStatCounter::account (ssize_t delta, int tag) {
100
+ assert (_active, " compilaton has not yet started" );
93
101
bool rc = false ;
94
102
#ifdef ASSERT
95
103
// Note: if this fires, we free more arena memory under the scope of the
96
104
// CompilationMemoryHistoryMark than we allocate. This cannot be since we
97
105
// assume arena allocations in CompilerThread to be stack bound and symmetric.
98
106
assert (delta >= 0 || ((ssize_t )_current + delta) >= 0 ,
99
- " Negative overflow (d=%zd %zu %zu %zu )" , delta, _current, _start , _peak);
107
+ " Negative overflow (d=%zd %zu %zu)" , delta, _current, _peak);
100
108
#endif
101
109
// Update totals
102
110
_current += delta;
103
- // Update detail counter
104
- switch ((Arena::Tag)tag) {
105
- case Arena::Tag::tag_ra: _ra += delta; break ;
106
- case Arena::Tag::tag_node: _na += delta; break ;
107
- default : // ignore
108
- break ;
109
- };
111
+ _current_by_tag.add (tag, delta);
110
112
// Did we reach a peak?
111
113
if (_current > _peak) {
112
114
_peak = _current;
113
- assert (delta > 0 , " Sanity (%zu %zu %zu)" , _current, _start, _peak);
114
- _na_at_peak = _na;
115
- _ra_at_peak = _ra;
115
+ assert (delta > 0 , " Sanity (%zu %zu)" , _current, _peak);
116
116
update_c2_node_count ();
117
+ _peak_by_tag = _current_by_tag;
117
118
rc = true ;
118
119
// Did we hit the memory limit?
119
- if (!_hit_limit && _limit > 0 && peak_since_start () > _limit) {
120
+ if (!_hit_limit && _limit > 0 && _peak > _limit) {
120
121
_hit_limit = true ;
121
122
}
122
123
}
123
124
return rc;
124
125
}
125
126
126
127
void ArenaStatCounter::print_on (outputStream* st) const {
127
- st->print (" %zu [na %zu ra %zu]" , peak_since_start (), _na_at_peak, _ra_at_peak);
128
+ st->print (" %zu [" , _peak);
129
+ for (int tag = 0 ; tag < _peak_by_tag.element_count (); tag++) {
130
+ if (_peak_by_tag.counter (tag) > 0 ) {
131
+ st->print (" %s %zu " , _peak_by_tag.tag_name (tag), _peak_by_tag.counter (tag));
132
+ }
133
+ }
134
+ st->print (" ]" );
128
135
#ifdef ASSERT
129
- st->print (" (%zu->%zu->%zu) " , _start , _peak, _current);
136
+ st->print (" (%zu->%zu) " , _peak, _current);
130
137
#endif
131
138
}
132
139
@@ -186,10 +193,8 @@ class MemStatEntry : public CHeapObj<mtInternal> {
186
193
187
194
// peak usage, bytes, over all arenas
188
195
size_t _total;
189
- // usage in node arena when total peaked
190
- size_t _na_at_peak;
191
- // usage in resource area when total peaked
192
- size_t _ra_at_peak;
196
+ // usage per arena tag when total peaked
197
+ ArenaCountersByTag _peak_by_tag;
193
198
// number of nodes (c2 only) when total peaked
194
199
unsigned _live_nodes_at_peak;
195
200
const char * _result;
@@ -199,8 +204,9 @@ class MemStatEntry : public CHeapObj<mtInternal> {
199
204
MemStatEntry (FullMethodName method)
200
205
: _method(method), _comptype(compiler_c1),
201
206
_time (0 ), _num_recomp(0 ), _thread(nullptr ), _limit(0 ),
202
- _total(0 ), _na_at_peak( 0 ), _ra_at_peak( 0 ), _live_nodes_at_peak(0 ),
207
+ _total(0 ), _live_nodes_at_peak(0 ),
203
208
_result(nullptr ) {
209
+ _peak_by_tag.clear ();
204
210
}
205
211
206
212
void set_comptype (CompilerType comptype) { _comptype = comptype; }
@@ -210,30 +216,42 @@ class MemStatEntry : public CHeapObj<mtInternal> {
210
216
void inc_recompilation () { _num_recomp++; }
211
217
212
218
void set_total (size_t n) { _total = n; }
213
- void set_na_at_peak (size_t n) { _na_at_peak = n; }
214
- void set_ra_at_peak (size_t n) { _ra_at_peak = n; }
219
+ void set_peak_by_tag (ArenaCountersByTag peak_by_tag) { _peak_by_tag = peak_by_tag; }
215
220
void set_live_nodes_at_peak (unsigned n) { _live_nodes_at_peak = n; }
216
221
217
222
void set_result (const char * s) { _result = s; }
218
223
219
224
size_t total () const { return _total; }
220
225
221
226
static void print_legend (outputStream* st) {
227
+ #define LEGEND_KEY_FMT " %11s"
222
228
st->print_cr (" Legend:" );
223
- st->print_cr (" total : memory allocated via arenas while compiling" );
224
- st->print_cr (" NA : ...how much in node arenas (if c2)" );
225
- st->print_cr (" RA : ...how much in resource areas" );
226
- st->print_cr (" result : Result: 'ok' finished successfully, 'oom' hit memory limit, 'err' compilation failed" );
227
- st->print_cr (" #nodes : ...how many nodes (c2 only)" );
228
- st->print_cr (" limit : memory limit, if set" );
229
- st->print_cr (" time : time of last compilation (sec)" );
230
- st->print_cr (" type : compiler type" );
231
- st->print_cr (" #rc : how often recompiled" );
232
- st->print_cr (" thread : compiler thread" );
229
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , " total" , " memory allocated via arenas while compiling" );
230
+ for (int tag = 0 ; tag < Arena::tag_count (); tag++) {
231
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , Arena::tag_name[tag], Arena::tag_desc[tag]);
232
+ }
233
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , " result" , " Result: 'ok' finished successfully, 'oom' hit memory limit, 'err' compilation failed" );
234
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , " #nodes" , " ...how many nodes (c2 only)" );
235
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , " limit" , " memory limit, if set" );
236
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , " time" , " time taken for last compilation (sec)" );
237
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , " type" , " compiler type" );
238
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , " #rc" , " how often recompiled" );
239
+ st->print_cr (" " LEGEND_KEY_FMT " : %s" , " thread" , " compiler thread" );
240
+ #undef LEGEND_KEY_FMT
233
241
}
234
242
235
243
static void print_header (outputStream* st) {
236
- st->print_cr (" total NA RA result #nodes limit time type #rc thread method" );
244
+ #define SIZE_FMT " %-10s"
245
+ st->print (SIZE_FMT, " total" );
246
+ for (int tag = 0 ; tag < Arena::tag_count (); tag++) {
247
+ st->print (SIZE_FMT, Arena::tag_name[tag]);
248
+ }
249
+ #define HDR_FMT1 " %-8s%-8s%-8s%-8s"
250
+ #define HDR_FMT2 " %-6s%-4s%-19s%s"
251
+
252
+ st->print (HDR_FMT1, " result" , " #nodes" , " limit" , " time" );
253
+ st->print (HDR_FMT2, " type" , " #rc" , " thread" , " method" );
254
+ st->print_cr (" " );
237
255
}
238
256
239
257
void print_on (outputStream* st, bool human_readable) const {
@@ -247,21 +265,14 @@ class MemStatEntry : public CHeapObj<mtInternal> {
247
265
}
248
266
col += 10 ; st->fill_to (col);
249
267
250
- // NA
251
- if (human_readable) {
252
- st->print (PROPERFMT " " , PROPERFMTARGS (_na_at_peak));
253
- } else {
254
- st->print (" %zu " , _na_at_peak);
255
- }
256
- col += 10 ; st->fill_to (col);
257
-
258
- // RA
259
- if (human_readable) {
260
- st->print (PROPERFMT " " , PROPERFMTARGS (_ra_at_peak));
261
- } else {
262
- st->print (" %zu " , _ra_at_peak);
268
+ for (int tag = 0 ; tag < Arena::tag_count (); tag++) {
269
+ if (human_readable) {
270
+ st->print (PROPERFMT " " , PROPERFMTARGS (_peak_by_tag.counter (tag)));
271
+ } else {
272
+ st->print (" %zu " , _peak_by_tag.counter (tag));
273
+ }
274
+ col += 10 ; st->fill_to (col);
263
275
}
264
- col += 10 ; st->fill_to (col);
265
276
266
277
// result?
267
278
st->print (" %s " , _result ? _result : " " );
@@ -296,7 +307,7 @@ class MemStatEntry : public CHeapObj<mtInternal> {
296
307
col += 4 ; st->fill_to (col);
297
308
298
309
// Thread
299
- st->print (PTR_FORMAT " " , p2i (_thread));
310
+ st->print (PTR_FORMAT " " , p2i (_thread));
300
311
301
312
// MethodName
302
313
char buf[1024 ];
@@ -341,7 +352,7 @@ class MemStatTable :
341
352
public:
342
353
343
354
void add (const FullMethodName& fmn, CompilerType comptype,
344
- size_t total, size_t na_at_peak, size_t ra_at_peak ,
355
+ size_t total, ArenaCountersByTag peak_by_tag ,
345
356
unsigned live_nodes_at_peak, size_t limit, const char * result) {
346
357
assert_lock_strong (NMTCompilationCostHistory_lock);
347
358
MemStatTableKey key (fmn, comptype);
@@ -360,8 +371,7 @@ class MemStatTable :
360
371
e->set_comptype (comptype);
361
372
e->inc_recompilation ();
362
373
e->set_total (total);
363
- e->set_na_at_peak (na_at_peak);
364
- e->set_ra_at_peak (ra_at_peak);
374
+ e->set_peak_by_tag (peak_by_tag);
365
375
e->set_live_nodes_at_peak (live_nodes_at_peak);
366
376
e->set_limit (limit);
367
377
e->set_result (result);
@@ -427,7 +437,7 @@ void CompilationMemoryStatistic::on_end_compilation() {
427
437
const bool print = directive->should_print_memstat ();
428
438
429
439
// Store memory used in task, for later processing by JFR
430
- task->set_arena_bytes (arena_stat->peak_since_start ());
440
+ task->set_arena_bytes (arena_stat->peak ());
431
441
432
442
// Store result
433
443
// For this to work, we must call on_end_compilation() at a point where
@@ -447,9 +457,8 @@ void CompilationMemoryStatistic::on_end_compilation() {
447
457
assert (_the_table != nullptr , " not initialized" );
448
458
449
459
_the_table->add (fmn, ct,
450
- arena_stat->peak_since_start (), // total
451
- arena_stat->na_at_peak (),
452
- arena_stat->ra_at_peak (),
460
+ arena_stat->peak (), // total
461
+ arena_stat->peak_by_tag (),
453
462
arena_stat->live_nodes_at_peak (),
454
463
arena_stat->limit (),
455
464
result);
@@ -511,7 +520,7 @@ void CompilationMemoryStatistic::on_arena_change(ssize_t diff, const Arena* aren
511
520
512
521
bool hit_limit_before = arena_stat->hit_limit ();
513
522
514
- if (arena_stat->account (diff, (int )arena->get_tag ())) { // new peak?
523
+ if (arena_stat->is_active () && arena_stat-> account (diff, (int )arena->get_tag ())) { // new peak?
515
524
516
525
// Limit handling
517
526
if (arena_stat->hit_limit ()) {
@@ -545,7 +554,7 @@ void CompilationMemoryStatistic::on_arena_change(ssize_t diff, const Arena* aren
545
554
}
546
555
ss.print (" Hit MemLimit %s(limit: %zu now: %zu)" ,
547
556
(hit_limit_before ? " again " : " " ),
548
- arena_stat->limit (), arena_stat->peak_since_start ());
557
+ arena_stat->limit (), arena_stat->peak ());
549
558
}
550
559
551
560
// log if needed
0 commit comments