< prev index next >

src/hotspot/share/prims/jvmtiRedefineClasses.cpp

Print this page




 771 
 772     for (int i = 0; i < members_len; i++) {
 773       if (the_syms[i] != scr_syms[i]) {
 774         log_trace(redefine, class, nestmates)
 775           ("redefined class %s attribute change error: NestMembers[%d]: %s changed to %s",
 776            the_class->external_name(), i, the_syms[i]->as_C_string(), scr_syms[i]->as_C_string());
 777         return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 778       }
 779     }
 780   } else if (the_members_exists ^ scr_members_exists) {
 781     const char* action_str = (the_members_exists) ? "removed" : "added";
 782     log_trace(redefine, class, nestmates)
 783       ("redefined class %s attribute change error: NestMembers attribute %s",
 784        the_class->external_name(), action_str);
 785     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 786   }
 787 
 788   return JVMTI_ERROR_NONE;
 789 }
 790 

























































 791 static bool can_add_or_delete(Method* m) {
 792       // Compatibility mode
 793   return (AllowRedefinitionToAddDeleteMethods &&
 794           (m->is_private() && (m->is_static() || m->is_final())));
 795 }
 796 
 797 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
 798              InstanceKlass* the_class,
 799              InstanceKlass* scratch_class) {
 800   int i;
 801 
 802   // Check superclasses, or rather their names, since superclasses themselves can be
 803   // requested to replace.
 804   // Check for NULL superclass first since this might be java.lang.Object
 805   if (the_class->super() != scratch_class->super() &&
 806       (the_class->super() == NULL || scratch_class->super() == NULL ||
 807        the_class->super()->name() !=
 808        scratch_class->super()->name())) {
 809     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
 810   }


 820   Array<InstanceKlass*>* k_new_interfaces = scratch_class->local_interfaces();
 821   int n_intfs = k_interfaces->length();
 822   if (n_intfs != k_new_interfaces->length()) {
 823     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
 824   }
 825   for (i = 0; i < n_intfs; i++) {
 826     if (k_interfaces->at(i)->name() !=
 827         k_new_interfaces->at(i)->name()) {
 828       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
 829     }
 830   }
 831 
 832   // Check whether class is in the error init state.
 833   if (the_class->is_in_error_state()) {
 834     // TBD #5057930: special error code is needed in 1.6
 835     return JVMTI_ERROR_INVALID_CLASS;
 836   }
 837 
 838   // Check whether the nest-related attributes have been changed.
 839   jvmtiError err = check_nest_attributes(the_class, scratch_class);






 840   if (err != JVMTI_ERROR_NONE) {
 841     return err;
 842   }
 843 
 844   // Check whether class modifiers are the same.
 845   jushort old_flags = (jushort) the_class->access_flags().get_flags();
 846   jushort new_flags = (jushort) scratch_class->access_flags().get_flags();
 847   if (old_flags != new_flags) {
 848     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
 849   }
 850 
 851   // Check if the number, names, types and order of fields declared in these classes
 852   // are the same.
 853   JavaFieldStream old_fs(the_class);
 854   JavaFieldStream new_fs(scratch_class);
 855   for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) {
 856     // access
 857     old_flags = old_fs.access_flags().as_short();
 858     new_flags = new_fs.access_flags().as_short();
 859     if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {




 771 
 772     for (int i = 0; i < members_len; i++) {
 773       if (the_syms[i] != scr_syms[i]) {
 774         log_trace(redefine, class, nestmates)
 775           ("redefined class %s attribute change error: NestMembers[%d]: %s changed to %s",
 776            the_class->external_name(), i, the_syms[i]->as_C_string(), scr_syms[i]->as_C_string());
 777         return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 778       }
 779     }
 780   } else if (the_members_exists ^ scr_members_exists) {
 781     const char* action_str = (the_members_exists) ? "removed" : "added";
 782     log_trace(redefine, class, nestmates)
 783       ("redefined class %s attribute change error: NestMembers attribute %s",
 784        the_class->external_name(), action_str);
 785     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 786   }
 787 
 788   return JVMTI_ERROR_NONE;
 789 }
 790 
 791 static jvmtiError check_permitted_subtypes_attribute(InstanceKlass* the_class,
 792                                                      InstanceKlass* scratch_class) {
 793   // Check whether the class NestMembers attribute has been changed.
 794   Array<u2>* the_permitted_subtypes = the_class->permitted_subtypes();
 795   Array<u2>* scr_permitted_subtypes = scratch_class->permitted_subtypes();
 796   bool the_subtypes_exists = the_permitted_subtypes != Universe::the_empty_short_array();
 797   bool scr_subtypes_exists = scr_permitted_subtypes != Universe::the_empty_short_array();
 798   int subtypes_len = the_permitted_subtypes->length();
 799   if (the_subtypes_exists && scr_subtypes_exists) {
 800     if (subtypes_len != scr_permitted_subtypes->length()) {
 801       log_trace(redefine, class, sealed)
 802         ("redefined class %s attribute change error: PermittedSubtypes len=%d changed to len=%d",
 803          the_class->external_name(), subtypes_len, scr_permitted_subtypes->length());
 804       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 805     }
 806 
 807     // The order of entries in the PermittedSubtypes array is not specified so
 808     // we have to explicitly check for the same contents. We do this by copying
 809     // the referenced symbols into their own arrays, sorting them and then
 810     // comparing each element pair.
 811 
 812     Symbol** the_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, subtypes_len);
 813     Symbol** scr_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, subtypes_len);
 814 
 815     if (the_syms == NULL || scr_syms == NULL) {
 816       return JVMTI_ERROR_OUT_OF_MEMORY;
 817     }
 818 
 819     for (int i = 0; i < subtypes_len; i++) {
 820       int the_cp_index = the_permitted_subtypes->at(i);
 821       int scr_cp_index = scr_permitted_subtypes->at(i);
 822       the_syms[i] = the_class->constants()->klass_name_at(the_cp_index);
 823       scr_syms[i] = scratch_class->constants()->klass_name_at(scr_cp_index);
 824     }
 825 
 826     qsort(the_syms, subtypes_len, sizeof(Symbol*), symcmp);
 827     qsort(scr_syms, subtypes_len, sizeof(Symbol*), symcmp);
 828 
 829     for (int i = 0; i < subtypes_len; i++) {
 830       if (the_syms[i] != scr_syms[i]) {
 831         log_trace(redefine, class, sealed)
 832           ("redefined class %s attribute change error: PermittedSubtypes[%d]: %s changed to %s",
 833            the_class->external_name(), i, the_syms[i]->as_C_string(), scr_syms[i]->as_C_string());
 834         return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 835       }
 836     }
 837   } else if (the_subtypes_exists ^ scr_subtypes_exists) {
 838     const char* action_str = (the_subtypes_exists) ? "removed" : "added";
 839     log_trace(redefine, class, sealed)
 840       ("redefined class %s attribute change error: PermittedSubtypes attribute %s",
 841        the_class->external_name(), action_str);
 842     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 843   }
 844 
 845   return JVMTI_ERROR_NONE;
 846 }
 847 
 848 static bool can_add_or_delete(Method* m) {
 849       // Compatibility mode
 850   return (AllowRedefinitionToAddDeleteMethods &&
 851           (m->is_private() && (m->is_static() || m->is_final())));
 852 }
 853 
 854 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
 855              InstanceKlass* the_class,
 856              InstanceKlass* scratch_class) {
 857   int i;
 858 
 859   // Check superclasses, or rather their names, since superclasses themselves can be
 860   // requested to replace.
 861   // Check for NULL superclass first since this might be java.lang.Object
 862   if (the_class->super() != scratch_class->super() &&
 863       (the_class->super() == NULL || scratch_class->super() == NULL ||
 864        the_class->super()->name() !=
 865        scratch_class->super()->name())) {
 866     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
 867   }


 877   Array<InstanceKlass*>* k_new_interfaces = scratch_class->local_interfaces();
 878   int n_intfs = k_interfaces->length();
 879   if (n_intfs != k_new_interfaces->length()) {
 880     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
 881   }
 882   for (i = 0; i < n_intfs; i++) {
 883     if (k_interfaces->at(i)->name() !=
 884         k_new_interfaces->at(i)->name()) {
 885       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
 886     }
 887   }
 888 
 889   // Check whether class is in the error init state.
 890   if (the_class->is_in_error_state()) {
 891     // TBD #5057930: special error code is needed in 1.6
 892     return JVMTI_ERROR_INVALID_CLASS;
 893   }
 894 
 895   // Check whether the nest-related attributes have been changed.
 896   jvmtiError err = check_nest_attributes(the_class, scratch_class);
 897   if (err != JVMTI_ERROR_NONE) {
 898     return err;
 899   }
 900 
 901   // Check whether the PermittedSubtypes attribute has been changed.
 902   err = check_permitted_subtypes_attribute(the_class, scratch_class);
 903   if (err != JVMTI_ERROR_NONE) {
 904     return err;
 905   }
 906 
 907   // Check whether class modifiers are the same.
 908   jushort old_flags = (jushort) the_class->access_flags().get_flags();
 909   jushort new_flags = (jushort) scratch_class->access_flags().get_flags();
 910   if (old_flags != new_flags) {
 911     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
 912   }
 913 
 914   // Check if the number, names, types and order of fields declared in these classes
 915   // are the same.
 916   JavaFieldStream old_fs(the_class);
 917   JavaFieldStream new_fs(scratch_class);
 918   for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) {
 919     // access
 920     old_flags = old_fs.access_flags().as_short();
 921     new_flags = new_fs.access_flags().as_short();
 922     if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {


< prev index next >