666 // Shrink the merge_cp operands
667 merge_cp->shrink_operands(_operands_cur_length, CHECK);
668
669 if (log_is_enabled(Trace, redefine, class, constantpool)) {
670 // don't want to loop unless we are tracing
671 int count = 0;
672 for (int i = 1; i < _operands_index_map_p->length(); i++) {
673 int value = _operands_index_map_p->at(i);
674 if (value != -1) {
675 log_trace(redefine, class, constantpool)("operands_index_map[%d]: old=%d new=%d", count, i, value);
676 count++;
677 }
678 }
679 }
680 // Clean-up
681 _operands_index_map_p = NULL;
682 _operands_cur_length = 0;
683 _operands_index_map_count = 0;
684 } // end finalize_operands_merge()
685
686
687 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
688 InstanceKlass* the_class,
689 InstanceKlass* scratch_class) {
690 int i;
691
692 // Check superclasses, or rather their names, since superclasses themselves can be
693 // requested to replace.
694 // Check for NULL superclass first since this might be java.lang.Object
695 if (the_class->super() != scratch_class->super() &&
696 (the_class->super() == NULL || scratch_class->super() == NULL ||
697 the_class->super()->name() !=
698 scratch_class->super()->name())) {
699 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
700 }
701
702 // Check if the number, names and order of directly implemented interfaces are the same.
703 // I think in principle we should just check if the sets of names of directly implemented
704 // interfaces are the same, i.e. the order of declaration (which, however, if changed in the
705 // .java file, also changes in .class file) should not matter. However, comparing sets is
708 // rely on it somewhere.
709 Array<Klass*>* k_interfaces = the_class->local_interfaces();
710 Array<Klass*>* k_new_interfaces = scratch_class->local_interfaces();
711 int n_intfs = k_interfaces->length();
712 if (n_intfs != k_new_interfaces->length()) {
713 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
714 }
715 for (i = 0; i < n_intfs; i++) {
716 if (k_interfaces->at(i)->name() !=
717 k_new_interfaces->at(i)->name()) {
718 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
719 }
720 }
721
722 // Check whether class is in the error init state.
723 if (the_class->is_in_error_state()) {
724 // TBD #5057930: special error code is needed in 1.6
725 return JVMTI_ERROR_INVALID_CLASS;
726 }
727
728 // Check whether class modifiers are the same.
729 jushort old_flags = (jushort) the_class->access_flags().get_flags();
730 jushort new_flags = (jushort) scratch_class->access_flags().get_flags();
731 if (old_flags != new_flags) {
732 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
733 }
734
735 // Check if the number, names, types and order of fields declared in these classes
736 // are the same.
737 JavaFieldStream old_fs(the_class);
738 JavaFieldStream new_fs(scratch_class);
739 for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) {
740 // access
741 old_flags = old_fs.access_flags().as_short();
742 new_flags = new_fs.access_flags().as_short();
743 if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {
744 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
745 }
746 // offset
747 if (old_fs.offset() != new_fs.offset()) {
1581
1582 // Replace the new constant pool with a shrunken copy of the
1583 // merged constant pool so now the rewritten bytecodes have
1584 // valid references; the previous new constant pool will get
1585 // GCed.
1586 set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length,
1587 CHECK_(JVMTI_ERROR_OUT_OF_MEMORY));
1588 // The new constant pool replaces scratch_cp so have cleaner clean it up.
1589 // It can't be cleaned up while there are handles to it.
1590 cp_cleaner.add_scratch_cp(scratch_cp());
1591 }
1592
1593 return JVMTI_ERROR_NONE;
1594 } // end merge_cp_and_rewrite()
1595
1596
1597 // Rewrite constant pool references in klass scratch_class.
1598 bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class,
1599 TRAPS) {
1600
1601 // rewrite constant pool references in the methods:
1602 if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) {
1603 // propagate failure back to caller
1604 return false;
1605 }
1606
1607 // rewrite constant pool references in the class_annotations:
1608 if (!rewrite_cp_refs_in_class_annotations(scratch_class, THREAD)) {
1609 // propagate failure back to caller
1610 return false;
1611 }
1612
1613 // rewrite constant pool references in the fields_annotations:
1614 if (!rewrite_cp_refs_in_fields_annotations(scratch_class, THREAD)) {
1615 // propagate failure back to caller
1616 return false;
1617 }
1618
1619 // rewrite constant pool references in the methods_annotations:
1620 if (!rewrite_cp_refs_in_methods_annotations(scratch_class, THREAD)) {
1662 // rewrite source file name index:
1663 u2 source_file_name_idx = scratch_class->source_file_name_index();
1664 if (source_file_name_idx != 0) {
1665 u2 new_source_file_name_idx = find_new_index(source_file_name_idx);
1666 if (new_source_file_name_idx != 0) {
1667 scratch_class->set_source_file_name_index(new_source_file_name_idx);
1668 }
1669 }
1670
1671 // rewrite class generic signature index:
1672 u2 generic_signature_index = scratch_class->generic_signature_index();
1673 if (generic_signature_index != 0) {
1674 u2 new_generic_signature_index = find_new_index(generic_signature_index);
1675 if (new_generic_signature_index != 0) {
1676 scratch_class->set_generic_signature_index(new_generic_signature_index);
1677 }
1678 }
1679
1680 return true;
1681 } // end rewrite_cp_refs()
1682
1683 // Rewrite constant pool references in the methods.
1684 bool VM_RedefineClasses::rewrite_cp_refs_in_methods(
1685 InstanceKlass* scratch_class, TRAPS) {
1686
1687 Array<Method*>* methods = scratch_class->methods();
1688
1689 if (methods == NULL || methods->length() == 0) {
1690 // no methods so nothing to do
1691 return true;
1692 }
1693
1694 // rewrite constant pool references in the methods:
1695 for (int i = methods->length() - 1; i >= 0; i--) {
1696 methodHandle method(THREAD, methods->at(i));
1697 methodHandle new_method;
1698 rewrite_cp_refs_in_method(method, &new_method, THREAD);
1699 if (!new_method.is_null()) {
1700 // the method has been replaced so save the new method version
1701 // even in the case of an exception. original method is on the
|
666 // Shrink the merge_cp operands
667 merge_cp->shrink_operands(_operands_cur_length, CHECK);
668
669 if (log_is_enabled(Trace, redefine, class, constantpool)) {
670 // don't want to loop unless we are tracing
671 int count = 0;
672 for (int i = 1; i < _operands_index_map_p->length(); i++) {
673 int value = _operands_index_map_p->at(i);
674 if (value != -1) {
675 log_trace(redefine, class, constantpool)("operands_index_map[%d]: old=%d new=%d", count, i, value);
676 count++;
677 }
678 }
679 }
680 // Clean-up
681 _operands_index_map_p = NULL;
682 _operands_cur_length = 0;
683 _operands_index_map_count = 0;
684 } // end finalize_operands_merge()
685
686 // Symbol* comparator for qsort
687 // The caller must have an active ResourceMark.
688 static int symcmp(const void* a, const void* b) {
689 char* astr = (*(Symbol**)a)->as_C_string();
690 char* bstr = (*(Symbol**)b)->as_C_string();
691 return strcmp(astr, bstr);
692 }
693
694 static jvmtiError check_nest_attributes(InstanceKlass* the_class,
695 InstanceKlass* scratch_class) {
696 // Check whether the class NestHost attribute has been changed.
697 Thread* thread = Thread::current();
698 ResourceMark rm(thread);
699 JvmtiThreadState *state = JvmtiThreadState::state_for((JavaThread*)thread);
700 u2 the_nest_host_idx = the_class->nest_host_index();
701 u2 scr_nest_host_idx = scratch_class->nest_host_index();
702
703 if (the_nest_host_idx != 0 && scr_nest_host_idx != 0) {
704 Symbol* the_sym = the_class->constants()->klass_name_at(the_nest_host_idx);
705 Symbol* scr_sym = scratch_class->constants()->klass_name_at(scr_nest_host_idx);
706 if (the_sym != scr_sym) {
707 log_trace(redefine, class, nestmates)
708 ("redefined class %s attribute change error: NestHost class: %s replaced with: %s",
709 the_class->external_name(), the_sym->as_C_string(), scr_sym->as_C_string());
710 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
711 }
712 } else if ((the_nest_host_idx == 0) ^ (scr_nest_host_idx == 0)) {
713 const char* action_str = (the_nest_host_idx != 0) ? "removed" : "added";
714 log_trace(redefine, class, nestmates)
715 ("redefined class %s attribute change error: NestHost attribute %s",
716 the_class->external_name(), action_str);
717 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
718 }
719
720 // Check whether the class NestMembers attribute has been changed.
721 Array<u2>* the_nest_members = the_class->nest_members();
722 Array<u2>* scr_nest_members = scratch_class->nest_members();
723 bool the_members_exists = the_nest_members != Universe::the_empty_short_array();
724 bool scr_members_exists = scr_nest_members != Universe::the_empty_short_array();
725
726 int members_len = the_nest_members->length();
727 if (the_members_exists && scr_members_exists) {
728 if (members_len != scr_nest_members->length()) {
729 log_trace(redefine, class, nestmates)
730 ("redefined class %s attribute change error: NestMember len=%d changed to len=%d",
731 the_class->external_name(), members_len, scr_nest_members->length());
732 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
733 }
734
735 // The order of entries in the NestMembers array is not specified so we
736 // have to explicitly check for the same contents. We do this by copying
737 // the referenced symbols into their own arrays, sorting them and then
738 // comparing each element pair.
739
740 Symbol** the_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, members_len);
741 Symbol** scr_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, members_len);
742
743 if (the_syms == NULL || scr_syms == NULL) {
744 return JVMTI_ERROR_OUT_OF_MEMORY;
745 }
746
747 for (int i = 0; i < members_len; i++) {
748 int the_cp_index = the_nest_members->at(i);
749 int scr_cp_index = scr_nest_members->at(i);
750 the_syms[i] = the_class->constants()->klass_name_at(the_cp_index);
751 scr_syms[i] = scratch_class->constants()->klass_name_at(scr_cp_index);
752 }
753
754 qsort(the_syms, members_len, sizeof(Symbol*), symcmp);
755 qsort(scr_syms, members_len, sizeof(Symbol*), symcmp);
756
757 for (int i = 0; i < members_len; i++) {
758 if (the_syms[i] != scr_syms[i]) {
759 log_trace(redefine, class, nestmates)
760 ("redefined class %s attribute change error: NestMembers[%d]: %s changed to %s",
761 the_class->external_name(), i, the_syms[i]->as_C_string(), scr_syms[i]->as_C_string());
762 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
763 }
764 }
765 } else if (the_members_exists ^ scr_members_exists) {
766 const char* action_str = (the_members_exists) ? "removed" : "added";
767 log_trace(redefine, class, nestmates)
768 ("redefined class %s attribute change error: NestMembers attribute %s",
769 the_class->external_name(), action_str);
770 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
771 }
772
773 return JVMTI_ERROR_NONE;
774 }
775
776 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
777 InstanceKlass* the_class,
778 InstanceKlass* scratch_class) {
779 int i;
780
781 // Check superclasses, or rather their names, since superclasses themselves can be
782 // requested to replace.
783 // Check for NULL superclass first since this might be java.lang.Object
784 if (the_class->super() != scratch_class->super() &&
785 (the_class->super() == NULL || scratch_class->super() == NULL ||
786 the_class->super()->name() !=
787 scratch_class->super()->name())) {
788 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
789 }
790
791 // Check if the number, names and order of directly implemented interfaces are the same.
792 // I think in principle we should just check if the sets of names of directly implemented
793 // interfaces are the same, i.e. the order of declaration (which, however, if changed in the
794 // .java file, also changes in .class file) should not matter. However, comparing sets is
797 // rely on it somewhere.
798 Array<Klass*>* k_interfaces = the_class->local_interfaces();
799 Array<Klass*>* k_new_interfaces = scratch_class->local_interfaces();
800 int n_intfs = k_interfaces->length();
801 if (n_intfs != k_new_interfaces->length()) {
802 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
803 }
804 for (i = 0; i < n_intfs; i++) {
805 if (k_interfaces->at(i)->name() !=
806 k_new_interfaces->at(i)->name()) {
807 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
808 }
809 }
810
811 // Check whether class is in the error init state.
812 if (the_class->is_in_error_state()) {
813 // TBD #5057930: special error code is needed in 1.6
814 return JVMTI_ERROR_INVALID_CLASS;
815 }
816
817 // Check whether the nest-related attributes have been changed.
818 jvmtiError err = check_nest_attributes(the_class, scratch_class);
819 if (err != JVMTI_ERROR_NONE) {
820 return err;
821 }
822
823 // Check whether class modifiers are the same.
824 jushort old_flags = (jushort) the_class->access_flags().get_flags();
825 jushort new_flags = (jushort) scratch_class->access_flags().get_flags();
826 if (old_flags != new_flags) {
827 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
828 }
829
830 // Check if the number, names, types and order of fields declared in these classes
831 // are the same.
832 JavaFieldStream old_fs(the_class);
833 JavaFieldStream new_fs(scratch_class);
834 for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) {
835 // access
836 old_flags = old_fs.access_flags().as_short();
837 new_flags = new_fs.access_flags().as_short();
838 if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {
839 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
840 }
841 // offset
842 if (old_fs.offset() != new_fs.offset()) {
1676
1677 // Replace the new constant pool with a shrunken copy of the
1678 // merged constant pool so now the rewritten bytecodes have
1679 // valid references; the previous new constant pool will get
1680 // GCed.
1681 set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length,
1682 CHECK_(JVMTI_ERROR_OUT_OF_MEMORY));
1683 // The new constant pool replaces scratch_cp so have cleaner clean it up.
1684 // It can't be cleaned up while there are handles to it.
1685 cp_cleaner.add_scratch_cp(scratch_cp());
1686 }
1687
1688 return JVMTI_ERROR_NONE;
1689 } // end merge_cp_and_rewrite()
1690
1691
1692 // Rewrite constant pool references in klass scratch_class.
1693 bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class,
1694 TRAPS) {
1695
1696 // rewrite constant pool references in the nest attributes:
1697 if (!rewrite_cp_refs_in_nest_attributes(scratch_class)) {
1698 // propagate failure back to caller
1699 return false;
1700 }
1701
1702 // rewrite constant pool references in the methods:
1703 if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) {
1704 // propagate failure back to caller
1705 return false;
1706 }
1707
1708 // rewrite constant pool references in the class_annotations:
1709 if (!rewrite_cp_refs_in_class_annotations(scratch_class, THREAD)) {
1710 // propagate failure back to caller
1711 return false;
1712 }
1713
1714 // rewrite constant pool references in the fields_annotations:
1715 if (!rewrite_cp_refs_in_fields_annotations(scratch_class, THREAD)) {
1716 // propagate failure back to caller
1717 return false;
1718 }
1719
1720 // rewrite constant pool references in the methods_annotations:
1721 if (!rewrite_cp_refs_in_methods_annotations(scratch_class, THREAD)) {
1763 // rewrite source file name index:
1764 u2 source_file_name_idx = scratch_class->source_file_name_index();
1765 if (source_file_name_idx != 0) {
1766 u2 new_source_file_name_idx = find_new_index(source_file_name_idx);
1767 if (new_source_file_name_idx != 0) {
1768 scratch_class->set_source_file_name_index(new_source_file_name_idx);
1769 }
1770 }
1771
1772 // rewrite class generic signature index:
1773 u2 generic_signature_index = scratch_class->generic_signature_index();
1774 if (generic_signature_index != 0) {
1775 u2 new_generic_signature_index = find_new_index(generic_signature_index);
1776 if (new_generic_signature_index != 0) {
1777 scratch_class->set_generic_signature_index(new_generic_signature_index);
1778 }
1779 }
1780
1781 return true;
1782 } // end rewrite_cp_refs()
1783
1784 // Rewrite constant pool references in the NestHost and NestMembers attributes.
1785 bool VM_RedefineClasses::rewrite_cp_refs_in_nest_attributes(
1786 InstanceKlass* scratch_class) {
1787
1788 u2 cp_index = scratch_class->nest_host_index();
1789 if (cp_index != 0) {
1790 scratch_class->set_nest_host_index(find_new_index(cp_index));
1791 }
1792 Array<u2>* nest_members = scratch_class->nest_members();
1793 for (int i = 0; i < nest_members->length(); i++) {
1794 u2 cp_index = nest_members->at(i);
1795 nest_members->at_put(i, find_new_index(cp_index));
1796 }
1797 return true;
1798 }
1799
1800 // Rewrite constant pool references in the methods.
1801 bool VM_RedefineClasses::rewrite_cp_refs_in_methods(
1802 InstanceKlass* scratch_class, TRAPS) {
1803
1804 Array<Method*>* methods = scratch_class->methods();
1805
1806 if (methods == NULL || methods->length() == 0) {
1807 // no methods so nothing to do
1808 return true;
1809 }
1810
1811 // rewrite constant pool references in the methods:
1812 for (int i = methods->length() - 1; i >= 0; i--) {
1813 methodHandle method(THREAD, methods->at(i));
1814 methodHandle new_method;
1815 rewrite_cp_refs_in_method(method, &new_method, THREAD);
1816 if (!new_method.is_null()) {
1817 // the method has been replaced so save the new method version
1818 // even in the case of an exception. original method is on the
|