comparison src/share/vm/code/nmethod.cpp @ 12675:7fedc59e2cdc

Split code cache stats for the different compilers
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 05 Nov 2013 12:19:10 +0100
parents 98031e66de15
children 0e998f0daddf
comparison
equal deleted inserted replaced
12674:ecd519b39f10 12675:7fedc59e2cdc
127 // PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation. 127 // PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation.
128 // (In the latter two cases, they like other stats are printed to the log only.) 128 // (In the latter two cases, they like other stats are printed to the log only.)
129 129
130 // These variables are put into one block to reduce relocations 130 // These variables are put into one block to reduce relocations
131 // and make it simpler to print from the debugger. 131 // and make it simpler to print from the debugger.
132 static 132 struct java_nmethod_stats_struct {
133 struct nmethod_stats_struct {
134 int nmethod_count; 133 int nmethod_count;
135 int total_size; 134 int total_size;
136 int relocation_size; 135 int relocation_size;
137 int consts_size; 136 int consts_size;
138 int insts_size; 137 int insts_size;
156 scopes_pcs_size += nm->scopes_pcs_size(); 155 scopes_pcs_size += nm->scopes_pcs_size();
157 dependencies_size += nm->dependencies_size(); 156 dependencies_size += nm->dependencies_size();
158 handler_table_size += nm->handler_table_size(); 157 handler_table_size += nm->handler_table_size();
159 nul_chk_table_size += nm->nul_chk_table_size(); 158 nul_chk_table_size += nm->nul_chk_table_size();
160 } 159 }
161 void print_nmethod_stats() { 160 void print_nmethod_stats(const char* name) {
162 if (nmethod_count == 0) return; 161 if (nmethod_count == 0) return;
163 tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count); 162 tty->print_cr("Statistics for %d bytecoded nmethods for %s:", nmethod_count, name);
164 if (total_size != 0) tty->print_cr(" total in heap = %d", total_size); 163 if (total_size != 0) tty->print_cr(" total in heap = %d", total_size);
165 if (relocation_size != 0) tty->print_cr(" relocation = %d", relocation_size); 164 if (relocation_size != 0) tty->print_cr(" relocation = %d", relocation_size);
166 if (consts_size != 0) tty->print_cr(" constants = %d", consts_size); 165 if (consts_size != 0) tty->print_cr(" constants = %d", consts_size);
167 if (insts_size != 0) tty->print_cr(" main code = %d", insts_size); 166 if (insts_size != 0) tty->print_cr(" main code = %d", insts_size);
168 if (stub_size != 0) tty->print_cr(" stub code = %d", stub_size); 167 if (stub_size != 0) tty->print_cr(" stub code = %d", stub_size);
171 if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %d", scopes_pcs_size); 170 if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %d", scopes_pcs_size);
172 if (dependencies_size != 0) tty->print_cr(" dependencies = %d", dependencies_size); 171 if (dependencies_size != 0) tty->print_cr(" dependencies = %d", dependencies_size);
173 if (handler_table_size != 0) tty->print_cr(" handler table = %d", handler_table_size); 172 if (handler_table_size != 0) tty->print_cr(" handler table = %d", handler_table_size);
174 if (nul_chk_table_size != 0) tty->print_cr(" nul chk table = %d", nul_chk_table_size); 173 if (nul_chk_table_size != 0) tty->print_cr(" nul chk table = %d", nul_chk_table_size);
175 } 174 }
176 175 };
176
177 struct native_nmethod_stats_struct {
177 int native_nmethod_count; 178 int native_nmethod_count;
178 int native_total_size; 179 int native_total_size;
179 int native_relocation_size; 180 int native_relocation_size;
180 int native_insts_size; 181 int native_insts_size;
181 int native_oops_size; 182 int native_oops_size;
192 if (native_total_size != 0) tty->print_cr(" N. total size = %d", native_total_size); 193 if (native_total_size != 0) tty->print_cr(" N. total size = %d", native_total_size);
193 if (native_relocation_size != 0) tty->print_cr(" N. relocation = %d", native_relocation_size); 194 if (native_relocation_size != 0) tty->print_cr(" N. relocation = %d", native_relocation_size);
194 if (native_insts_size != 0) tty->print_cr(" N. main code = %d", native_insts_size); 195 if (native_insts_size != 0) tty->print_cr(" N. main code = %d", native_insts_size);
195 if (native_oops_size != 0) tty->print_cr(" N. oops = %d", native_oops_size); 196 if (native_oops_size != 0) tty->print_cr(" N. oops = %d", native_oops_size);
196 } 197 }
197 198 };
199
200 struct pc_nmethod_stats_struct {
198 int pc_desc_resets; // number of resets (= number of caches) 201 int pc_desc_resets; // number of resets (= number of caches)
199 int pc_desc_queries; // queries to nmethod::find_pc_desc 202 int pc_desc_queries; // queries to nmethod::find_pc_desc
200 int pc_desc_approx; // number of those which have approximate true 203 int pc_desc_approx; // number of those which have approximate true
201 int pc_desc_repeats; // number of _pc_descs[0] hits 204 int pc_desc_repeats; // number of _pc_descs[0] hits
202 int pc_desc_hits; // number of LRU cache hits 205 int pc_desc_hits; // number of LRU cache hits
213 pc_desc_resets, 216 pc_desc_resets,
214 pc_desc_queries, pc_desc_approx, 217 pc_desc_queries, pc_desc_approx,
215 pc_desc_repeats, pc_desc_hits, 218 pc_desc_repeats, pc_desc_hits,
216 pc_desc_tests, pc_desc_searches, pc_desc_adds); 219 pc_desc_tests, pc_desc_searches, pc_desc_adds);
217 } 220 }
218 } nmethod_stats; 221 };
222
223 #ifdef COMPILER1
224 static java_nmethod_stats_struct c1_java_nmethod_stats;
225 #endif
226 #ifdef COMPILER2
227 static java_nmethod_stats_struct c2_java_nmethod_stats;
228 #endif
229 #ifdef GRAAL
230 static java_nmethod_stats_struct graal_java_nmethod_stats;
231 #endif
232
233 static native_nmethod_stats_struct native_nmethod_stats;
234 static pc_nmethod_stats_struct pc_nmethod_stats;
235
236 static void note_java_nmethod(nmethod* nm) {
237 #ifdef COMPILER1
238 if (nm->is_compiled_by_c1()) {
239 c1_java_nmethod_stats.note_nmethod(nm);
240 }
241 #endif
242 #ifdef COMPILER2
243 if (nm->is_compiled_by_c2()) {
244 c2_java_nmethod_stats.note_nmethod(nm);
245 }
246 #endif
247 #ifdef GRAAL
248 if (nm->is_compiled_by_graal()) {
249 graal_java_nmethod_stats.note_nmethod(nm);
250 }
251 #endif
252 }
219 253
220 254
221 //--------------------------------------------------------------------------------- 255 //---------------------------------------------------------------------------------
222 256
223 257
294 //----------------------------------------------------------------------------- 328 //-----------------------------------------------------------------------------
295 329
296 330
297 // Helper used by both find_pc_desc methods. 331 // Helper used by both find_pc_desc methods.
298 static inline bool match_desc(PcDesc* pc, int pc_offset, bool approximate) { 332 static inline bool match_desc(PcDesc* pc, int pc_offset, bool approximate) {
299 NOT_PRODUCT(++nmethod_stats.pc_desc_tests); 333 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_tests);
300 if (!approximate) 334 if (!approximate)
301 return pc->pc_offset() == pc_offset; 335 return pc->pc_offset() == pc_offset;
302 else 336 else
303 return (pc-1)->pc_offset() < pc_offset && pc_offset <= pc->pc_offset(); 337 return (pc-1)->pc_offset() < pc_offset && pc_offset <= pc->pc_offset();
304 } 338 }
306 void PcDescCache::reset_to(PcDesc* initial_pc_desc) { 340 void PcDescCache::reset_to(PcDesc* initial_pc_desc) {
307 if (initial_pc_desc == NULL) { 341 if (initial_pc_desc == NULL) {
308 _pc_descs[0] = NULL; // native method; no PcDescs at all 342 _pc_descs[0] = NULL; // native method; no PcDescs at all
309 return; 343 return;
310 } 344 }
311 NOT_PRODUCT(++nmethod_stats.pc_desc_resets); 345 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_resets);
312 // reset the cache by filling it with benign (non-null) values 346 // reset the cache by filling it with benign (non-null) values
313 assert(initial_pc_desc->pc_offset() < 0, "must be sentinel"); 347 assert(initial_pc_desc->pc_offset() < 0, "must be sentinel");
314 for (int i = 0; i < cache_size; i++) 348 for (int i = 0; i < cache_size; i++)
315 _pc_descs[i] = initial_pc_desc; 349 _pc_descs[i] = initial_pc_desc;
316 } 350 }
317 351
318 PcDesc* PcDescCache::find_pc_desc(int pc_offset, bool approximate) { 352 PcDesc* PcDescCache::find_pc_desc(int pc_offset, bool approximate) {
319 NOT_PRODUCT(++nmethod_stats.pc_desc_queries); 353 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_queries);
320 NOT_PRODUCT(if (approximate) ++nmethod_stats.pc_desc_approx); 354 NOT_PRODUCT(if (approximate) ++pc_nmethod_stats.pc_desc_approx);
321 355
322 // Note: one might think that caching the most recently 356 // Note: one might think that caching the most recently
323 // read value separately would be a win, but one would be 357 // read value separately would be a win, but one would be
324 // wrong. When many threads are updating it, the cache 358 // wrong. When many threads are updating it, the cache
325 // line it's in would bounce between caches, negating 359 // line it's in would bounce between caches, negating
331 365
332 // Step one: Check the most recently added value. 366 // Step one: Check the most recently added value.
333 res = _pc_descs[0]; 367 res = _pc_descs[0];
334 if (res == NULL) return NULL; // native method; no PcDescs at all 368 if (res == NULL) return NULL; // native method; no PcDescs at all
335 if (match_desc(res, pc_offset, approximate)) { 369 if (match_desc(res, pc_offset, approximate)) {
336 NOT_PRODUCT(++nmethod_stats.pc_desc_repeats); 370 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_repeats);
337 return res; 371 return res;
338 } 372 }
339 373
340 // Step two: Check the rest of the LRU cache. 374 // Step two: Check the rest of the LRU cache.
341 for (int i = 1; i < cache_size; ++i) { 375 for (int i = 1; i < cache_size; ++i) {
342 res = _pc_descs[i]; 376 res = _pc_descs[i];
343 if (res->pc_offset() < 0) break; // optimization: skip empty cache 377 if (res->pc_offset() < 0) break; // optimization: skip empty cache
344 if (match_desc(res, pc_offset, approximate)) { 378 if (match_desc(res, pc_offset, approximate)) {
345 NOT_PRODUCT(++nmethod_stats.pc_desc_hits); 379 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_hits);
346 return res; 380 return res;
347 } 381 }
348 } 382 }
349 383
350 // Report failure. 384 // Report failure.
351 return NULL; 385 return NULL;
352 } 386 }
353 387
354 void PcDescCache::add_pc_desc(PcDesc* pc_desc) { 388 void PcDescCache::add_pc_desc(PcDesc* pc_desc) {
355 NOT_PRODUCT(++nmethod_stats.pc_desc_adds); 389 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_adds);
356 // Update the LRU cache by shifting pc_desc forward. 390 // Update the LRU cache by shifting pc_desc forward.
357 for (int i = 0; i < cache_size; i++) { 391 for (int i = 0; i < cache_size; i++) {
358 PcDesc* next = _pc_descs[i]; 392 PcDesc* next = _pc_descs[i];
359 _pc_descs[i] = pc_desc; 393 _pc_descs[i] = pc_desc;
360 pc_desc = next; 394 pc_desc = next;
517 nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size, 551 nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size,
518 compile_id, &offsets, 552 compile_id, &offsets,
519 code_buffer, frame_size, 553 code_buffer, frame_size,
520 basic_lock_owner_sp_offset, 554 basic_lock_owner_sp_offset,
521 basic_lock_sp_offset, oop_maps); 555 basic_lock_sp_offset, oop_maps);
522 if (nm != NULL) nmethod_stats.note_native_nmethod(nm); 556 if (nm != NULL) native_nmethod_stats.note_native_nmethod(nm);
523 if (PrintAssembly && nm != NULL) { 557 if (PrintAssembly && nm != NULL) {
524 Disassembler::decode(nm); 558 Disassembler::decode(nm);
525 } 559 }
526 } 560 }
527 // verify nmethod 561 // verify nmethod
553 offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); 587 offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
554 588
555 nm = new (nmethod_size) nmethod(method(), nmethod_size, 589 nm = new (nmethod_size) nmethod(method(), nmethod_size,
556 &offsets, code_buffer, frame_size); 590 &offsets, code_buffer, frame_size);
557 591
558 if (nm != NULL) nmethod_stats.note_nmethod(nm); 592 if (nm != NULL) note_java_nmethod(nm);
559 if (PrintAssembly && nm != NULL) { 593 if (PrintAssembly && nm != NULL) {
560 Disassembler::decode(nm); 594 Disassembler::decode(nm);
561 } 595 }
562 } 596 }
563 // verify nmethod 597 // verify nmethod
638 672
639 // record this nmethod as dependent on this klass 673 // record this nmethod as dependent on this klass
640 InstanceKlass::cast(klass)->add_dependent_nmethod(nm); 674 InstanceKlass::cast(klass)->add_dependent_nmethod(nm);
641 } 675 }
642 } 676 }
643 if (nm != NULL) nmethod_stats.note_nmethod(nm); 677 if (nm != NULL) note_java_nmethod(nm);
644 if (PrintAssembly && nm != NULL) { 678 if (PrintAssembly && nm != NULL) {
645 Disassembler::decode(nm); 679 Disassembler::decode(nm);
646 } 680 }
647 } 681 }
648 682
2166 PcDesc* lower = nm->scopes_pcs_begin(); 2200 PcDesc* lower = nm->scopes_pcs_begin();
2167 PcDesc* upper = nm->scopes_pcs_end(); 2201 PcDesc* upper = nm->scopes_pcs_end();
2168 lower += 1; // exclude initial sentinel 2202 lower += 1; // exclude initial sentinel
2169 PcDesc* res = NULL; 2203 PcDesc* res = NULL;
2170 for (PcDesc* p = lower; p < upper; p++) { 2204 for (PcDesc* p = lower; p < upper; p++) {
2171 NOT_PRODUCT(--nmethod_stats.pc_desc_tests); // don't count this call to match_desc 2205 NOT_PRODUCT(--pc_nmethod_stats.pc_desc_tests); // don't count this call to match_desc
2172 if (match_desc(p, pc_offset, approximate)) { 2206 if (match_desc(p, pc_offset, approximate)) {
2173 if (res == NULL) 2207 if (res == NULL)
2174 res = p; 2208 res = p;
2175 else 2209 else
2176 res = (PcDesc*) badAddress; 2210 res = (PcDesc*) badAddress;
2213 assert(upper->pc_offset() >= pc_offset, "sanity") 2247 assert(upper->pc_offset() >= pc_offset, "sanity")
2214 assert_LU_OK; 2248 assert_LU_OK;
2215 2249
2216 // Use the last successful return as a split point. 2250 // Use the last successful return as a split point.
2217 PcDesc* mid = _pc_desc_cache.last_pc_desc(); 2251 PcDesc* mid = _pc_desc_cache.last_pc_desc();
2218 NOT_PRODUCT(++nmethod_stats.pc_desc_searches); 2252 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
2219 if (mid->pc_offset() < pc_offset) { 2253 if (mid->pc_offset() < pc_offset) {
2220 lower = mid; 2254 lower = mid;
2221 } else { 2255 } else {
2222 upper = mid; 2256 upper = mid;
2223 } 2257 }
2226 const int LOG2_RADIX = 4 /*smaller steps in debug mode:*/ debug_only(-1); 2260 const int LOG2_RADIX = 4 /*smaller steps in debug mode:*/ debug_only(-1);
2227 const int RADIX = (1 << LOG2_RADIX); 2261 const int RADIX = (1 << LOG2_RADIX);
2228 for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) { 2262 for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) {
2229 while ((mid = lower + step) < upper) { 2263 while ((mid = lower + step) < upper) {
2230 assert_LU_OK; 2264 assert_LU_OK;
2231 NOT_PRODUCT(++nmethod_stats.pc_desc_searches); 2265 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
2232 if (mid->pc_offset() < pc_offset) { 2266 if (mid->pc_offset() < pc_offset) {
2233 lower = mid; 2267 lower = mid;
2234 } else { 2268 } else {
2235 upper = mid; 2269 upper = mid;
2236 break; 2270 break;
2241 2275
2242 // Sneak up on the value with a linear search of length ~16. 2276 // Sneak up on the value with a linear search of length ~16.
2243 while (true) { 2277 while (true) {
2244 assert_LU_OK; 2278 assert_LU_OK;
2245 mid = lower + 1; 2279 mid = lower + 1;
2246 NOT_PRODUCT(++nmethod_stats.pc_desc_searches); 2280 NOT_PRODUCT(++pc_nmethod_stats.pc_desc_searches);
2247 if (mid->pc_offset() < pc_offset) { 2281 if (mid->pc_offset() < pc_offset) {
2248 lower = mid; 2282 lower = mid;
2249 } else { 2283 } else {
2250 upper = mid; 2284 upper = mid;
2251 break; 2285 break;
3041 #endif // PRODUCT 3075 #endif // PRODUCT
3042 3076
3043 void nmethod::print_statistics() { 3077 void nmethod::print_statistics() {
3044 ttyLocker ttyl; 3078 ttyLocker ttyl;
3045 if (xtty != NULL) xtty->head("statistics type='nmethod'"); 3079 if (xtty != NULL) xtty->head("statistics type='nmethod'");
3046 nmethod_stats.print_native_nmethod_stats(); 3080 native_nmethod_stats.print_native_nmethod_stats();
3047 nmethod_stats.print_nmethod_stats(); 3081 #ifdef COMPILER1
3082 c1_java_nmethod_stats.print_nmethod_stats("C1");
3083 #endif
3084 #ifdef COMPILER2
3085 c2_java_nmethod_stats.print_nmethod_stats("C2");
3086 #endif
3087 #ifdef GRAAL
3088 graal_java_nmethod_stats.print_nmethod_stats("Graal");
3089 #endif
3048 DebugInformationRecorder::print_statistics(); 3090 DebugInformationRecorder::print_statistics();
3049 nmethod_stats.print_pc_stats(); 3091 pc_nmethod_stats.print_pc_stats();
3050 Dependencies::print_statistics(); 3092 Dependencies::print_statistics();
3051 if (xtty != NULL) xtty->tail("statistics"); 3093 if (xtty != NULL) xtty->tail("statistics");
3052 } 3094 }