594 nm->clear_inline_caches(); |
594 nm->clear_inline_caches(); |
595 } |
595 } |
596 } |
596 } |
597 |
597 |
598 #ifndef PRODUCT |
598 #ifndef PRODUCT |
599 // used to keep track of how much time is spent in mark_for_deoptimization |
599 // Keeps track of time spent for checking dependencies |
600 static elapsedTimer dependentCheckTime; |
600 static elapsedTimer dependentCheckTime; |
601 static int dependentCheckCount = 0; |
601 #endif |
602 #endif // PRODUCT |
|
603 |
602 |
604 |
603 |
605 int CodeCache::mark_for_deoptimization(DepChange& changes) { |
604 int CodeCache::mark_for_deoptimization(DepChange& changes) { |
606 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
605 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
607 |
|
608 #ifndef PRODUCT |
|
609 dependentCheckTime.start(); |
|
610 dependentCheckCount++; |
|
611 #endif // PRODUCT |
|
612 |
|
613 int number_of_marked_CodeBlobs = 0; |
606 int number_of_marked_CodeBlobs = 0; |
614 |
607 |
615 // search the hierarchy looking for nmethods which are affected by the loading of this class |
608 // search the hierarchy looking for nmethods which are affected by the loading of this class |
616 |
609 |
617 // then search the interfaces this class implements looking for nmethods |
610 // then search the interfaces this class implements looking for nmethods |
618 // which might be dependent of the fact that an interface only had one |
611 // which might be dependent of the fact that an interface only had one |
619 // implementor. |
612 // implementor. |
620 |
613 // nmethod::check_all_dependencies works only correctly, if no safepoint |
621 { No_Safepoint_Verifier nsv; |
614 // can happen |
622 for (DepChange::ContextStream str(changes, nsv); str.next(); ) { |
615 No_Safepoint_Verifier nsv; |
623 Klass* d = str.klass(); |
616 for (DepChange::ContextStream str(changes, nsv); str.next(); ) { |
624 number_of_marked_CodeBlobs += InstanceKlass::cast(d)->mark_dependent_nmethods(changes); |
617 Klass* d = str.klass(); |
625 } |
618 number_of_marked_CodeBlobs += InstanceKlass::cast(d)->mark_dependent_nmethods(changes); |
626 } |
619 } |
627 |
620 |
|
621 #ifndef PRODUCT |
628 if (VerifyDependencies) { |
622 if (VerifyDependencies) { |
629 // Turn off dependency tracing while actually testing deps. |
623 // Object pointers are used as unique identifiers for dependency arguments. This |
630 NOT_PRODUCT( FlagSetting fs(TraceDependencies, false) ); |
624 // is only possible if no safepoint, i.e., GC occurs during the verification code. |
631 FOR_ALL_ALIVE_NMETHODS(nm) { |
625 dependentCheckTime.start(); |
632 if (!nm->is_marked_for_deoptimization() && |
626 nmethod::check_all_dependencies(changes); |
633 nm->check_all_dependencies()) { |
627 dependentCheckTime.stop(); |
634 ResourceMark rm; |
628 } |
635 tty->print_cr("Should have been marked for deoptimization:"); |
629 #endif |
636 changes.print(); |
|
637 nm->print(); |
|
638 nm->print_dependencies(); |
|
639 } |
|
640 } |
|
641 } |
|
642 |
|
643 #ifndef PRODUCT |
|
644 dependentCheckTime.stop(); |
|
645 #endif // PRODUCT |
|
646 |
630 |
647 return number_of_marked_CodeBlobs; |
631 return number_of_marked_CodeBlobs; |
648 } |
632 } |
649 |
633 |
650 |
634 |