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 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( 695 InstanceKlass* the_class, 696 InstanceKlass* scratch_class) { 697 int i; 698 699 // Check superclasses, or rather their names, since superclasses themselves can be 700 // requested to replace. 701 // Check for NULL superclass first since this might be java.lang.Object 702 if (the_class->super() != scratch_class->super() && 703 (the_class->super() == NULL || scratch_class->super() == NULL || 704 the_class->super()->name() != 705 scratch_class->super()->name())) { 706 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED; 707 } 708 709 // Check if the number, names and order of directly implemented interfaces are the same. 710 // I think in principle we should just check if the sets of names of directly implemented 711 // interfaces are the same, i.e. the order of declaration (which, however, if changed in the 712 // .java file, also changes in .class file) should not matter. However, comparing sets is 715 // rely on it somewhere. 716 Array<Klass*>* k_interfaces = the_class->local_interfaces(); 717 Array<Klass*>* k_new_interfaces = scratch_class->local_interfaces(); 718 int n_intfs = k_interfaces->length(); 719 if (n_intfs != k_new_interfaces->length()) { 720 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED; 721 } 722 for (i = 0; i < n_intfs; i++) { 723 if (k_interfaces->at(i)->name() != 724 k_new_interfaces->at(i)->name()) { 725 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED; 726 } 727 } 728 729 // Check whether class is in the error init state. 730 if (the_class->is_in_error_state()) { 731 // TBD #5057930: special error code is needed in 1.6 732 return JVMTI_ERROR_INVALID_CLASS; 733 } 734 735 // Check whether the class NestHost attribute has been changed. 736 { 737 Thread* thread = Thread::current(); 738 ResourceMark rm(thread); 739 JvmtiThreadState *state = JvmtiThreadState::state_for((JavaThread*)thread); 740 RedefineVerifyMark rvm(the_class, scratch_class, state); 741 u2 the_nest_host_idx = the_class->nest_host_index(); 742 u2 scr_nest_host_idx = scratch_class->nest_host_index(); 743 744 if (the_nest_host_idx != 0 && scr_nest_host_idx != 0) { 745 Symbol* the_sym = the_class->constants()->klass_name_at(the_nest_host_idx); 746 Symbol* scr_sym = scratch_class->constants()->klass_name_at(scr_nest_host_idx); 747 if (the_sym != scr_sym) { 748 log_trace(redefine, class, nestmates) 749 ("redefined class %s attribute change error: NestHost class: %s replaced with: %s", 750 the_class->external_name(), the_sym->as_C_string(), scr_sym->as_C_string()); 751 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; 752 } 753 } else if ((the_nest_host_idx == 0) ^ (scr_nest_host_idx == 0)) { 754 const char* action_str = (the_nest_host_idx != 0) ? "removed" : "added"; 755 log_trace(redefine, class, nestmates) 756 ("redefined class %s attribute change error: NestHost attribute %s", 757 the_class->external_name(), action_str); 758 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; 759 } 760 761 // Check whether the class NestMembers attribute has been changed. 762 Array<u2>* the_nest_members = the_class->nest_members(); 763 Array<u2>* scr_nest_members = scratch_class->nest_members(); 764 bool the_members_exists = the_nest_members != Universe::the_empty_short_array(); 765 bool scr_members_exists = scr_nest_members != Universe::the_empty_short_array(); 766 767 int members_len = the_nest_members->length(); 768 if (the_members_exists && scr_members_exists) { 769 if (members_len != scr_nest_members->length()) { 770 log_trace(redefine, class, nestmates) 771 ("redefined class %s attribute change error: NestMember len=%d changed to len=%d", 772 the_class->external_name(), members_len, scr_nest_members->length()); 773 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; 774 } 775 776 // The order of entries in the NestMembers array is not specified so we 777 // have to explicitly check for the same contents. We do this by copying 778 // the referenced symbols into their own arrays, sorting them and then 779 // comparing each element pair. 780 781 Symbol** the_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, members_len); 782 Symbol** scr_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, members_len); 783 784 if (the_syms == NULL || scr_syms == NULL) { 785 return JVMTI_ERROR_OUT_OF_MEMORY; 786 } 787 788 for (int i = 0; i < members_len; i++) { 789 int the_cp_index = the_nest_members->at(i); 790 int scr_cp_index = scr_nest_members->at(i); 791 the_syms[i] = the_class->constants()->klass_name_at(the_cp_index); 792 scr_syms[i] = scratch_class->constants()->klass_name_at(scr_cp_index); 793 } 794 795 qsort(the_syms, members_len, sizeof(Symbol*), symcmp); 796 qsort(scr_syms, members_len, sizeof(Symbol*), symcmp); 797 798 for (int i = 0; i < members_len; i++) { 799 if (the_syms[i] != scr_syms[i]) { 800 log_trace(redefine, class, nestmates) 801 ("redefined class %s attribute change error: NestMembers[%d]: %s changed to %s", 802 the_class->external_name(), i, the_syms[i]->as_C_string(), scr_syms[i]->as_C_string()); 803 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; 804 } 805 } 806 /* 807 for (int i = 0; i < members_len; i++) { 808 int the_cp_index = the_nest_members->at(i); 809 int scr_cp_index = scr_nest_members->at(i); 810 Symbol* the_sym = the_class->constants()->klass_name_at(the_cp_index); 811 Symbol* scr_sym = scratch_class->constants()->klass_name_at(scr_cp_index); 812 if (the_sym != scr_sym) { 813 log_trace(redefine, class, nestmates) 814 ("redefined class %s attribute change error: NestMembers[%d]: %s changed to %s", 815 the_class->external_name(), i, the_sym->as_C_string(), scr_sym->as_C_string()); 816 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; 817 } 818 } 819 */ 820 } else if (the_members_exists ^ scr_members_exists) { 821 const char* action_str = (the_members_exists) ? "removed" : "added"; 822 log_trace(redefine, class, nestmates) 823 ("redefined class %s attribute change error: NestMembers attribute %s", 824 the_class->external_name(), action_str); 825 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; 826 } 827 } 828 829 // Check whether class modifiers are the same. 830 jushort old_flags = (jushort) the_class->access_flags().get_flags(); 831 jushort new_flags = (jushort) scratch_class->access_flags().get_flags(); 832 if (old_flags != new_flags) { 833 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED; 834 } 835 836 // Check if the number, names, types and order of fields declared in these classes 837 // are the same. 838 JavaFieldStream old_fs(the_class); 839 JavaFieldStream new_fs(scratch_class); 840 for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) { 841 // access 842 old_flags = old_fs.access_flags().as_short(); 843 new_flags = new_fs.access_flags().as_short(); 844 if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) { 845 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; 846 } 847 // offset 848 if (old_fs.offset() != new_fs.offset()) { 1682 1683 // Replace the new constant pool with a shrunken copy of the 1684 // merged constant pool so now the rewritten bytecodes have 1685 // valid references; the previous new constant pool will get 1686 // GCed. 1687 set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, 1688 CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); 1689 // The new constant pool replaces scratch_cp so have cleaner clean it up. 1690 // It can't be cleaned up while there are handles to it. 1691 cp_cleaner.add_scratch_cp(scratch_cp()); 1692 } 1693 1694 return JVMTI_ERROR_NONE; 1695 } // end merge_cp_and_rewrite() 1696 1697 1698 // Rewrite constant pool references in klass scratch_class. 1699 bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class, 1700 TRAPS) { 1701 1702 // rewrite constant pool references in the nest attributes: 1703 if (!rewrite_cp_refs_in_nest_attributes(scratch_class)) { 1704 // propagate failure back to caller 1705 return false; 1706 } 1707 1708 // rewrite constant pool references in the methods: 1709 if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) { 1710 // propagate failure back to caller 1711 return false; 1712 } 1713 1714 // rewrite constant pool references in the class_annotations: 1715 if (!rewrite_cp_refs_in_class_annotations(scratch_class, THREAD)) { 1716 // propagate failure back to caller 1717 return false; 1718 } 1719 1720 // rewrite constant pool references in the fields_annotations: 1721 if (!rewrite_cp_refs_in_fields_annotations(scratch_class, THREAD)) { 1722 // propagate failure back to caller 1723 return false; 1724 } 1725 1726 // rewrite constant pool references in the methods_annotations: 1727 if (!rewrite_cp_refs_in_methods_annotations(scratch_class, THREAD)) { 1769 // rewrite source file name index: 1770 u2 source_file_name_idx = scratch_class->source_file_name_index(); 1771 if (source_file_name_idx != 0) { 1772 u2 new_source_file_name_idx = find_new_index(source_file_name_idx); 1773 if (new_source_file_name_idx != 0) { 1774 scratch_class->set_source_file_name_index(new_source_file_name_idx); 1775 } 1776 } 1777 1778 // rewrite class generic signature index: 1779 u2 generic_signature_index = scratch_class->generic_signature_index(); 1780 if (generic_signature_index != 0) { 1781 u2 new_generic_signature_index = find_new_index(generic_signature_index); 1782 if (new_generic_signature_index != 0) { 1783 scratch_class->set_generic_signature_index(new_generic_signature_index); 1784 } 1785 } 1786 1787 return true; 1788 } // end rewrite_cp_refs() 1789 1790 // Rewrite constant pool references in the NestHost and NestMembers attributes. 1791 bool VM_RedefineClasses::rewrite_cp_refs_in_nest_attributes( 1792 InstanceKlass* scratch_class) { 1793 1794 u2 cp_index = scratch_class->nest_host_index(); 1795 if (cp_index != 0) { 1796 scratch_class->set_nest_host_index(find_new_index(cp_index)); 1797 } 1798 Array<u2>* nest_members = scratch_class->nest_members(); 1799 for (int i = 0; i < nest_members->length(); i++) { 1800 u2 cp_index = nest_members->at(i); 1801 nest_members->at_put(i, find_new_index(cp_index)); 1802 } 1803 return true; 1804 } 1805 1806 // Rewrite constant pool references in the methods. 1807 bool VM_RedefineClasses::rewrite_cp_refs_in_methods( 1808 InstanceKlass* scratch_class, TRAPS) { 1809 1810 Array<Method*>* methods = scratch_class->methods(); 1811 1812 if (methods == NULL || methods->length() == 0) { 1813 // no methods so nothing to do 1814 return true; 1815 } 1816 1817 // rewrite constant pool references in the methods: 1818 for (int i = methods->length() - 1; i >= 0; i--) { 1819 methodHandle method(THREAD, methods->at(i)); 1820 methodHandle new_method; 1821 rewrite_cp_refs_in_method(method, &new_method, THREAD); 1822 if (!new_method.is_null()) { 1823 // the method has been replaced so save the new method version 1824 // even in the case of an exception. original method is on the |