comparison src/share/vm/code/dependencies.cpp @ 14262:3aaa4b9966f6

7194669: CodeCache::mark_for_deoptimization should avoid verifying dependencies multiple times Summary: Avoid verifying dependencies multiple times by caching verified dependencies Reviewed-by: kvn, twisti, roland
author anoll
date Wed, 15 Jan 2014 06:16:55 +0100
parents ac9cb1d5a202
children 3e2b76368121 757ec609d8d5
comparison
equal deleted inserted replaced
14260:8cdf3f43f63e 14262:3aaa4b9966f6
678 678
679 assert(result == NULL || result->is_klass() || result->is_method(), "must be"); 679 assert(result == NULL || result->is_klass() || result->is_method(), "must be");
680 return result; 680 return result;
681 } 681 }
682 682
683 /**
684 * Returns a unique identifier for each dependency argument.
685 */
686 uintptr_t Dependencies::DepStream::get_identifier(int i) {
687 if (has_oop_argument()) {
688 return (uintptr_t)(oopDesc*)argument_oop(i);
689 } else {
690 return (uintptr_t)argument(i);
691 }
692 }
693
683 oop Dependencies::DepStream::argument_oop(int i) { 694 oop Dependencies::DepStream::argument_oop(int i) {
684 oop result = recorded_oop_at(argument_index(i)); 695 oop result = recorded_oop_at(argument_index(i));
685 assert(result == NULL || result->is_oop(), "must be"); 696 assert(result == NULL || result->is_oop(), "must be");
686 return result; 697 return result;
687 } 698 }
712 723
713 // And some dependencies don't have a context type at all, 724 // And some dependencies don't have a context type at all,
714 // e.g. evol_method. 725 // e.g. evol_method.
715 return NULL; 726 return NULL;
716 } 727 }
728
729 // ----------------- DependencySignature --------------------------------------
730 bool DependencySignature::equals(const DependencySignature& sig) const {
731 if (type() != sig.type()) {
732 return false;
733 }
734
735 if (args_count() != sig.args_count()) {
736 return false;
737 }
738
739 for (int i = 0; i < sig.args_count(); i++) {
740 if (arg(i) != sig.arg(i)) {
741 return false;
742 }
743 }
744 return true;
745 }
746
747
748 // ----------------- DependencySignatureBuffer --------------------------------------
749 DependencySignatureBuffer::DependencySignatureBuffer() {
750 _signatures = NEW_RESOURCE_ARRAY(GrowableArray<DependencySignature*>*, Dependencies::TYPE_LIMIT);
751 memset(_signatures, 0, sizeof(DependencySignature*) * Dependencies::TYPE_LIMIT);
752 }
753
754 /* Check if arguments are identical. Two dependency signatures are considered
755 * identical, if the type as well as all argument identifiers are identical.
756 * If the dependency has not already been checked, the dependency signature is
757 * added to the checked dependencies of the same type. The function returns
758 * false, which causes the dependency to be checked in the caller.
759 */
760 bool DependencySignatureBuffer::add_if_missing(const DependencySignature& sig) {
761 const int index = sig.type();
762 GrowableArray<DependencySignature*>* buffer = _signatures[index];
763 if (buffer == NULL) {
764 buffer = new GrowableArray<DependencySignature*>();
765 _signatures[index] = buffer;
766 }
767
768 // Check if we have already checked the dependency
769 for (int i = 0; i < buffer->length(); i++) {
770 DependencySignature* checked_signature = buffer->at(i);
771 if (checked_signature->equals(sig)) {
772 return true;
773 }
774 }
775 buffer->append((DependencySignature*)&sig);
776 return false;
777 }
778
717 779
718 /// Checking dependencies: 780 /// Checking dependencies:
719 781
720 // This hierarchy walker inspects subtypes of a given type, 782 // This hierarchy walker inspects subtypes of a given type,
721 // trying to find a "bad" class which breaks a dependency. 783 // trying to find a "bad" class which breaks a dependency.