Mercurial > hg > graal-compiler
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. |