25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "code/compiledIC.hpp" |
26 #include "code/compiledIC.hpp" |
27 #include "code/compiledMethod.inline.hpp" |
27 #include "code/compiledMethod.inline.hpp" |
28 #include "code/scopeDesc.hpp" |
28 #include "code/scopeDesc.hpp" |
29 #include "code/codeCache.hpp" |
29 #include "code/codeCache.hpp" |
|
30 #include "code/icBuffer.hpp" |
30 #include "gc/shared/barrierSet.hpp" |
31 #include "gc/shared/barrierSet.hpp" |
31 #include "gc/shared/gcBehaviours.hpp" |
32 #include "gc/shared/gcBehaviours.hpp" |
32 #include "interpreter/bytecode.inline.hpp" |
33 #include "interpreter/bytecode.inline.hpp" |
33 #include "logging/log.hpp" |
34 #include "logging/log.hpp" |
34 #include "logging/logTag.hpp" |
35 #include "logging/logTag.hpp" |
428 assert(klass->is_loader_alive(), "must be alive"); |
429 assert(klass->is_loader_alive(), "must be alive"); |
429 } |
430 } |
430 #endif // ASSERT |
431 #endif // ASSERT |
431 |
432 |
432 |
433 |
433 void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic) { |
434 bool CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic) { |
|
435 if (ic->is_clean()) { |
|
436 return true; |
|
437 } |
434 if (ic->is_icholder_call()) { |
438 if (ic->is_icholder_call()) { |
435 // The only exception is compiledICHolder metdata which may |
439 // The only exception is compiledICHolder metdata which may |
436 // yet be marked below. (We check this further below). |
440 // yet be marked below. (We check this further below). |
437 CompiledICHolder* cichk_metdata = ic->cached_icholder(); |
441 CompiledICHolder* cichk_metdata = ic->cached_icholder(); |
438 |
442 |
439 if (cichk_metdata->is_loader_alive()) { |
443 if (cichk_metdata->is_loader_alive()) { |
440 return; |
444 return true; |
441 } |
445 } |
442 } else { |
446 } else { |
443 Metadata* ic_metdata = ic->cached_metadata(); |
447 Metadata* ic_metdata = ic->cached_metadata(); |
444 if (ic_metdata != NULL) { |
448 if (ic_metdata != NULL) { |
445 if (ic_metdata->is_klass()) { |
449 if (ic_metdata->is_klass()) { |
446 if (((Klass*)ic_metdata)->is_loader_alive()) { |
450 if (((Klass*)ic_metdata)->is_loader_alive()) { |
447 return; |
451 return true; |
448 } |
452 } |
449 } else if (ic_metdata->is_method()) { |
453 } else if (ic_metdata->is_method()) { |
450 Method* method = (Method*)ic_metdata; |
454 Method* method = (Method*)ic_metdata; |
451 assert(!method->is_old(), "old method should have been cleaned"); |
455 assert(!method->is_old(), "old method should have been cleaned"); |
452 if (method->method_holder()->is_loader_alive()) { |
456 if (method->method_holder()->is_loader_alive()) { |
453 return; |
457 return true; |
454 } |
458 } |
455 } else { |
459 } else { |
456 ShouldNotReachHere(); |
460 ShouldNotReachHere(); |
457 } |
461 } |
458 } |
462 } |
459 } |
463 } |
460 |
464 |
461 ic->set_to_clean(); |
465 return ic->set_to_clean(); |
462 } |
466 } |
463 |
467 |
464 // static_stub_Relocations may have dangling references to |
468 // static_stub_Relocations may have dangling references to |
465 // nmethods so trim them out here. Otherwise it looks like |
469 // nmethods so trim them out here. Otherwise it looks like |
466 // compiled code is maintaining a link to dead metadata. |
470 // compiled code is maintaining a link to dead metadata. |
494 #endif |
498 #endif |
495 } |
499 } |
496 |
500 |
497 // Clean references to unloaded nmethods at addr from this one, which is not unloaded. |
501 // Clean references to unloaded nmethods at addr from this one, which is not unloaded. |
498 template <class CompiledICorStaticCall> |
502 template <class CompiledICorStaticCall> |
499 static void clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from, |
503 static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from, |
500 bool clean_all) { |
504 bool clean_all) { |
501 // Ok, to lookup references to zombies here |
505 // Ok, to lookup references to zombies here |
502 CodeBlob *cb = CodeCache::find_blob_unsafe(addr); |
506 CodeBlob *cb = CodeCache::find_blob_unsafe(addr); |
503 CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; |
507 CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; |
504 if (nm != NULL) { |
508 if (nm != NULL) { |
505 // Clean inline caches pointing to both zombie and not_entrant methods |
509 // Clean inline caches pointing to both zombie and not_entrant methods |
506 if (clean_all || !nm->is_in_use() || nm->is_unloading() || (nm->method()->code() != nm)) { |
510 if (clean_all || !nm->is_in_use() || nm->is_unloading() || (nm->method()->code() != nm)) { |
507 ic->set_to_clean(from->is_alive()); |
511 if (!ic->set_to_clean(from->is_alive())) { |
|
512 return false; |
|
513 } |
508 assert(ic->is_clean(), "nmethod " PTR_FORMAT "not clean %s", p2i(from), from->method()->name_and_sig_as_C_string()); |
514 assert(ic->is_clean(), "nmethod " PTR_FORMAT "not clean %s", p2i(from), from->method()->name_and_sig_as_C_string()); |
509 } |
515 } |
510 } |
516 } |
511 } |
517 return true; |
512 |
518 } |
513 static void clean_if_nmethod_is_unloaded(CompiledIC *ic, CompiledMethod* from, |
519 |
|
520 static bool clean_if_nmethod_is_unloaded(CompiledIC *ic, CompiledMethod* from, |
514 bool clean_all) { |
521 bool clean_all) { |
515 clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), from, clean_all); |
522 return clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), from, clean_all); |
516 } |
523 } |
517 |
524 |
518 static void clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, CompiledMethod* from, |
525 static bool clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, CompiledMethod* from, |
519 bool clean_all) { |
526 bool clean_all) { |
520 clean_if_nmethod_is_unloaded(csc, csc->destination(), from, clean_all); |
527 return clean_if_nmethod_is_unloaded(csc, csc->destination(), from, clean_all); |
521 } |
528 } |
522 |
529 |
523 // Cleans caches in nmethods that point to either classes that are unloaded |
530 // Cleans caches in nmethods that point to either classes that are unloaded |
524 // or nmethods that are unloaded. |
531 // or nmethods that are unloaded. |
525 // |
532 // |
526 // Can be called either in parallel by G1 currently or after all |
533 // Can be called either in parallel by G1 currently or after all |
527 // nmethods are unloaded. Return postponed=true in the parallel case for |
534 // nmethods are unloaded. Return postponed=true in the parallel case for |
528 // inline caches found that point to nmethods that are not yet visited during |
535 // inline caches found that point to nmethods that are not yet visited during |
529 // the do_unloading walk. |
536 // the do_unloading walk. |
530 void CompiledMethod::unload_nmethod_caches(bool unloading_occurred) { |
537 bool CompiledMethod::unload_nmethod_caches(bool unloading_occurred) { |
531 ResourceMark rm; |
538 ResourceMark rm; |
532 |
539 |
533 // Exception cache only needs to be called if unloading occurred |
540 // Exception cache only needs to be called if unloading occurred |
534 if (unloading_occurred) { |
541 if (unloading_occurred) { |
535 clean_exception_cache(); |
542 clean_exception_cache(); |
536 } |
543 } |
537 |
544 |
538 cleanup_inline_caches_impl(unloading_occurred, false); |
545 if (!cleanup_inline_caches_impl(unloading_occurred, false)) { |
|
546 return false; |
|
547 } |
539 |
548 |
540 // All static stubs need to be cleaned. |
549 // All static stubs need to be cleaned. |
541 clean_ic_stubs(); |
550 clean_ic_stubs(); |
542 |
551 |
543 // Check that the metadata embedded in the nmethod is alive |
552 // Check that the metadata embedded in the nmethod is alive |
544 DEBUG_ONLY(metadata_do(check_class)); |
553 DEBUG_ONLY(metadata_do(check_class)); |
|
554 return true; |
|
555 } |
|
556 |
|
557 void CompiledMethod::cleanup_inline_caches(bool clean_all) { |
|
558 for (;;) { |
|
559 { CompiledICLocker ic_locker(this); |
|
560 if (cleanup_inline_caches_impl(false, clean_all)) { |
|
561 return; |
|
562 } |
|
563 } |
|
564 InlineCacheBuffer::refill_ic_stubs(); |
|
565 } |
545 } |
566 } |
546 |
567 |
547 // Called to clean up after class unloading for live nmethods and from the sweeper |
568 // Called to clean up after class unloading for live nmethods and from the sweeper |
548 // for all methods. |
569 // for all methods. |
549 void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) { |
570 bool CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) { |
550 assert(CompiledICLocker::is_safe(this), "mt unsafe call"); |
571 assert(CompiledICLocker::is_safe(this), "mt unsafe call"); |
551 ResourceMark rm; |
572 ResourceMark rm; |
552 |
573 |
553 // Find all calls in an nmethod and clear the ones that point to non-entrant, |
574 // Find all calls in an nmethod and clear the ones that point to non-entrant, |
554 // zombie and unloaded nmethods. |
575 // zombie and unloaded nmethods. |
559 |
580 |
560 case relocInfo::virtual_call_type: |
581 case relocInfo::virtual_call_type: |
561 if (unloading_occurred) { |
582 if (unloading_occurred) { |
562 // If class unloading occurred we first clear ICs where the cached metadata |
583 // If class unloading occurred we first clear ICs where the cached metadata |
563 // is referring to an unloaded klass or method. |
584 // is referring to an unloaded klass or method. |
564 clean_ic_if_metadata_is_dead(CompiledIC_at(&iter)); |
585 if (!clean_ic_if_metadata_is_dead(CompiledIC_at(&iter))) { |
565 } |
586 return false; |
566 |
587 } |
567 clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all); |
588 } |
|
589 |
|
590 if (!clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all)) { |
|
591 return false; |
|
592 } |
568 break; |
593 break; |
569 |
594 |
570 case relocInfo::opt_virtual_call_type: |
595 case relocInfo::opt_virtual_call_type: |
571 clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all); |
596 if (!clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all)) { |
|
597 return false; |
|
598 } |
572 break; |
599 break; |
573 |
600 |
574 case relocInfo::static_call_type: |
601 case relocInfo::static_call_type: |
575 clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, clean_all); |
602 if (!clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, clean_all)) { |
|
603 return false; |
|
604 } |
576 break; |
605 break; |
577 |
|
578 case relocInfo::oop_type: |
|
579 break; |
|
580 |
|
581 case relocInfo::metadata_type: |
|
582 break; // nothing to do. |
|
583 |
606 |
584 default: |
607 default: |
585 break; |
608 break; |
586 } |
609 } |
587 } |
610 } |
|
611 |
|
612 return true; |
588 } |
613 } |
589 |
614 |
590 // Iterating over all nmethods, e.g. with the help of CodeCache::nmethods_do(fun) was found |
615 // Iterating over all nmethods, e.g. with the help of CodeCache::nmethods_do(fun) was found |
591 // to not be inherently safe. There is a chance that fields are seen which are not properly |
616 // to not be inherently safe. There is a chance that fields are seen which are not properly |
592 // initialized. This happens despite the fact that nmethods_do() asserts the CodeCache_lock |
617 // initialized. This happens despite the fact that nmethods_do() asserts the CodeCache_lock |