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. |