comparison src/share/vm/code/codeCache.cpp @ 1202:5f24d0319e54

4360113: Evict nmethods when code cache gets full Summary: Speculatively unload the oldest nmethods when code cache gets full. Reviewed-by: never, kvn Contributed-by: eric.caspole@amd.com
author kvn
date Fri, 29 Jan 2010 09:27:22 -0800
parents 148e5441d916
children ed4f78aa9282
comparison
equal deleted inserted replaced
1201:24128c2ffa87 1202:5f24d0319e54
94 CodeHeap * CodeCache::_heap = new CodeHeap(); 94 CodeHeap * CodeCache::_heap = new CodeHeap();
95 int CodeCache::_number_of_blobs = 0; 95 int CodeCache::_number_of_blobs = 0;
96 int CodeCache::_number_of_nmethods_with_dependencies = 0; 96 int CodeCache::_number_of_nmethods_with_dependencies = 0;
97 bool CodeCache::_needs_cache_clean = false; 97 bool CodeCache::_needs_cache_clean = false;
98 nmethod* CodeCache::_scavenge_root_nmethods = NULL; 98 nmethod* CodeCache::_scavenge_root_nmethods = NULL;
99 nmethod* CodeCache::_saved_nmethods = NULL;
99 100
100 101
101 CodeBlob* CodeCache::first() { 102 CodeBlob* CodeCache::first() {
102 assert_locked_or_safepoint(CodeCache_lock); 103 assert_locked_or_safepoint(CodeCache_lock);
103 return (CodeBlob*)_heap->first(); 104 return (CodeBlob*)_heap->first();
392 } 393 }
393 if (call_f) f_or_null->do_code_blob(cb); 394 if (call_f) f_or_null->do_code_blob(cb);
394 } 395 }
395 } 396 }
396 #endif //PRODUCT 397 #endif //PRODUCT
398
399
400 nmethod* CodeCache::find_and_remove_saved_code(methodOop m) {
401 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
402 nmethod* saved = _saved_nmethods;
403 nmethod* prev = NULL;
404 while (saved != NULL) {
405 if (saved->is_in_use() && saved->method() == m) {
406 if (prev != NULL) {
407 prev->set_saved_nmethod_link(saved->saved_nmethod_link());
408 } else {
409 _saved_nmethods = saved->saved_nmethod_link();
410 }
411 assert(saved->is_speculatively_disconnected(), "shouldn't call for other nmethods");
412 saved->set_speculatively_disconnected(false);
413 saved->set_saved_nmethod_link(NULL);
414 if (PrintMethodFlushing) {
415 saved->print_on(tty, " ### nmethod is reconnected");
416 }
417 if (LogCompilation && (xtty != NULL)) {
418 ttyLocker ttyl;
419 xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id());
420 xtty->method(methodOop(m));
421 xtty->stamp();
422 xtty->end_elem();
423 }
424 return saved;
425 }
426 prev = saved;
427 saved = saved->saved_nmethod_link();
428 }
429 return NULL;
430 }
431
432 void CodeCache::remove_saved_code(nmethod* nm) {
433 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
434 assert(nm->is_speculatively_disconnected(), "shouldn't call for other nmethods");
435 nmethod* saved = _saved_nmethods;
436 nmethod* prev = NULL;
437 while (saved != NULL) {
438 if (saved == nm) {
439 if (prev != NULL) {
440 prev->set_saved_nmethod_link(saved->saved_nmethod_link());
441 } else {
442 _saved_nmethods = saved->saved_nmethod_link();
443 }
444 if (LogCompilation && (xtty != NULL)) {
445 ttyLocker ttyl;
446 xtty->begin_elem("nmethod_removed compile_id='%3d'", nm->compile_id());
447 xtty->stamp();
448 xtty->end_elem();
449 }
450 return;
451 }
452 prev = saved;
453 saved = saved->saved_nmethod_link();
454 }
455 ShouldNotReachHere();
456 }
457
458 void CodeCache::speculatively_disconnect(nmethod* nm) {
459 assert_locked_or_safepoint(CodeCache_lock);
460 assert(nm->is_in_use() && !nm->is_speculatively_disconnected(), "should only disconnect live nmethods");
461 nm->set_saved_nmethod_link(_saved_nmethods);
462 _saved_nmethods = nm;
463 if (PrintMethodFlushing) {
464 nm->print_on(tty, " ### nmethod is speculatively disconnected");
465 }
466 if (LogCompilation && (xtty != NULL)) {
467 ttyLocker ttyl;
468 xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id());
469 xtty->method(methodOop(nm->method()));
470 xtty->stamp();
471 xtty->end_elem();
472 }
473 nm->method()->clear_code();
474 nm->set_speculatively_disconnected(true);
475 }
476
397 477
398 void CodeCache::gc_prologue() { 478 void CodeCache::gc_prologue() {
399 assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called"); 479 assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
400 } 480 }
401 481