Mercurial > hg > truffle
comparison src/share/vm/code/codeCache.cpp @ 12324:510fbd28919c
8020151: PSR:PERF Large performance regressions when code cache is filled
Summary: Code cache sweeping based on method hotness; removed speculatively disconnect
Reviewed-by: kvn, iveresov
author | anoll |
---|---|
date | Fri, 27 Sep 2013 10:50:55 +0200 |
parents | f2110083203d |
children | cefad50507d8 3aaa4b9966f6 78bbf4d43a14 |
comparison
equal
deleted
inserted
replaced
12323:c9ccd7b85f20 | 12324:510fbd28919c |
---|---|
122 int CodeCache::_number_of_adapters = 0; | 122 int CodeCache::_number_of_adapters = 0; |
123 int CodeCache::_number_of_nmethods = 0; | 123 int CodeCache::_number_of_nmethods = 0; |
124 int CodeCache::_number_of_nmethods_with_dependencies = 0; | 124 int CodeCache::_number_of_nmethods_with_dependencies = 0; |
125 bool CodeCache::_needs_cache_clean = false; | 125 bool CodeCache::_needs_cache_clean = false; |
126 nmethod* CodeCache::_scavenge_root_nmethods = NULL; | 126 nmethod* CodeCache::_scavenge_root_nmethods = NULL; |
127 nmethod* CodeCache::_saved_nmethods = NULL; | |
128 | 127 |
129 int CodeCache::_codemem_full_count = 0; | 128 int CodeCache::_codemem_full_count = 0; |
130 | 129 |
131 CodeBlob* CodeCache::first() { | 130 CodeBlob* CodeCache::first() { |
132 assert_locked_or_safepoint(CodeCache_lock); | 131 assert_locked_or_safepoint(CodeCache_lock); |
462 if (call_f) f_or_null->do_code_blob(cb); | 461 if (call_f) f_or_null->do_code_blob(cb); |
463 } | 462 } |
464 } | 463 } |
465 #endif //PRODUCT | 464 #endif //PRODUCT |
466 | 465 |
467 /** | |
468 * Remove and return nmethod from the saved code list in order to reanimate it. | |
469 */ | |
470 nmethod* CodeCache::reanimate_saved_code(Method* m) { | |
471 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
472 nmethod* saved = _saved_nmethods; | |
473 nmethod* prev = NULL; | |
474 while (saved != NULL) { | |
475 if (saved->is_in_use() && saved->method() == m) { | |
476 if (prev != NULL) { | |
477 prev->set_saved_nmethod_link(saved->saved_nmethod_link()); | |
478 } else { | |
479 _saved_nmethods = saved->saved_nmethod_link(); | |
480 } | |
481 assert(saved->is_speculatively_disconnected(), "shouldn't call for other nmethods"); | |
482 saved->set_speculatively_disconnected(false); | |
483 saved->set_saved_nmethod_link(NULL); | |
484 if (PrintMethodFlushing) { | |
485 saved->print_on(tty, " ### nmethod is reconnected"); | |
486 } | |
487 if (LogCompilation && (xtty != NULL)) { | |
488 ttyLocker ttyl; | |
489 xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id()); | |
490 xtty->method(m); | |
491 xtty->stamp(); | |
492 xtty->end_elem(); | |
493 } | |
494 return saved; | |
495 } | |
496 prev = saved; | |
497 saved = saved->saved_nmethod_link(); | |
498 } | |
499 return NULL; | |
500 } | |
501 | |
502 /** | |
503 * Remove nmethod from the saved code list in order to discard it permanently | |
504 */ | |
505 void CodeCache::remove_saved_code(nmethod* nm) { | |
506 // For conc swpr this will be called with CodeCache_lock taken by caller | |
507 assert_locked_or_safepoint(CodeCache_lock); | |
508 assert(nm->is_speculatively_disconnected(), "shouldn't call for other nmethods"); | |
509 nmethod* saved = _saved_nmethods; | |
510 nmethod* prev = NULL; | |
511 while (saved != NULL) { | |
512 if (saved == nm) { | |
513 if (prev != NULL) { | |
514 prev->set_saved_nmethod_link(saved->saved_nmethod_link()); | |
515 } else { | |
516 _saved_nmethods = saved->saved_nmethod_link(); | |
517 } | |
518 if (LogCompilation && (xtty != NULL)) { | |
519 ttyLocker ttyl; | |
520 xtty->begin_elem("nmethod_removed compile_id='%3d'", nm->compile_id()); | |
521 xtty->stamp(); | |
522 xtty->end_elem(); | |
523 } | |
524 return; | |
525 } | |
526 prev = saved; | |
527 saved = saved->saved_nmethod_link(); | |
528 } | |
529 ShouldNotReachHere(); | |
530 } | |
531 | |
532 void CodeCache::speculatively_disconnect(nmethod* nm) { | |
533 assert_locked_or_safepoint(CodeCache_lock); | |
534 assert(nm->is_in_use() && !nm->is_speculatively_disconnected(), "should only disconnect live nmethods"); | |
535 nm->set_saved_nmethod_link(_saved_nmethods); | |
536 _saved_nmethods = nm; | |
537 if (PrintMethodFlushing) { | |
538 nm->print_on(tty, " ### nmethod is speculatively disconnected"); | |
539 } | |
540 if (LogCompilation && (xtty != NULL)) { | |
541 ttyLocker ttyl; | |
542 xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id()); | |
543 xtty->method(nm->method()); | |
544 xtty->stamp(); | |
545 xtty->end_elem(); | |
546 } | |
547 nm->method()->clear_code(); | |
548 nm->set_speculatively_disconnected(true); | |
549 } | |
550 | |
551 | 466 |
552 void CodeCache::gc_prologue() { | 467 void CodeCache::gc_prologue() { |
553 assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called"); | 468 assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called"); |
554 } | 469 } |
555 | |
556 | 470 |
557 void CodeCache::gc_epilogue() { | 471 void CodeCache::gc_epilogue() { |
558 assert_locked_or_safepoint(CodeCache_lock); | 472 assert_locked_or_safepoint(CodeCache_lock); |
559 FOR_ALL_ALIVE_BLOBS(cb) { | 473 FOR_ALL_ALIVE_BLOBS(cb) { |
560 if (cb->is_nmethod()) { | 474 if (cb->is_nmethod()) { |