< prev index next >

src/hotspot/share/prims/jvmtiRedefineClasses.cpp

Print this page

 592       if (scratch_i != *merge_cp_length_p) {
 593         // The new entry in *merge_cp_p is at a different index than
 594         // the new entry in scratch_cp so we need to map the index values.
 595         map_index(scratch_cp, scratch_i, *merge_cp_length_p);
 596       }
 597       (*merge_cp_length_p)++;
 598     } break;
 599 
 600     // At this stage, Class or UnresolvedClass could be in scratch_cp, but not
 601     // ClassIndex
 602     case JVM_CONSTANT_ClassIndex: // fall through
 603 
 604     // Invalid is used as the tag for the second constant pool entry
 605     // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should
 606     // not be seen by itself.
 607     case JVM_CONSTANT_Invalid: // fall through
 608 
 609     // At this stage, String could be here, but not StringIndex
 610     case JVM_CONSTANT_StringIndex: // fall through
 611 
 612     // At this stage JVM_CONSTANT_UnresolvedClassInError should not be
 613     // here
 614     case JVM_CONSTANT_UnresolvedClassInError: // fall through
 615 
 616     default:
 617     {
 618       // leave a breadcrumb
 619       jbyte bad_value = scratch_cp->tag_at(scratch_i).value();
 620       ShouldNotReachHere();
 621     } break;
 622   } // end switch tag value
 623 } // end append_entry()
 624 
 625 
 626 u2 VM_RedefineClasses::find_or_append_indirect_entry(const constantPoolHandle& scratch_cp,
 627       int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p) {
 628 
 629   int new_ref_i = ref_i;
 630   bool match = (ref_i < *merge_cp_length_p) &&
 631                scratch_cp->compare_entry_to(ref_i, *merge_cp_p, ref_i);
 632 
 633   if (!match) {

 905        the_class->external_name(), action_str);
 906     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 907   }
 908 
 909   return JVMTI_ERROR_NONE;
 910 }
 911 
 912 
 913 static jvmtiError check_permitted_subclasses_attribute(InstanceKlass* the_class,
 914                                                        InstanceKlass* scratch_class) {
 915   Thread* thread = Thread::current();
 916   ResourceMark rm(thread);
 917 
 918   // Check whether the class PermittedSubclasses attribute has been changed.
 919   return check_attribute_arrays("PermittedSubclasses",
 920                                 the_class, scratch_class,
 921                                 the_class->permitted_subclasses(),
 922                                 scratch_class->permitted_subclasses());
 923 }
 924 












 925 static bool can_add_or_delete(Method* m) {
 926       // Compatibility mode
 927   return (AllowRedefinitionToAddDeleteMethods &&
 928           (m->is_private() && (m->is_static() || m->is_final())));
 929 }
 930 
 931 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
 932              InstanceKlass* the_class,
 933              InstanceKlass* scratch_class) {
 934   int i;
 935 
 936   // Check superclasses, or rather their names, since superclasses themselves can be
 937   // requested to replace.
 938   // Check for null superclass first since this might be java.lang.Object
 939   if (the_class->super() != scratch_class->super() &&
 940       (the_class->super() == nullptr || scratch_class->super() == nullptr ||
 941        the_class->super()->name() !=
 942        scratch_class->super()->name())) {
 943     log_info(redefine, class, normalize)
 944       ("redefined class %s superclass change error: superclass changed from %s to %s.",

 984   }
 985 
 986   // Check whether the nest-related attributes have been changed.
 987   jvmtiError err = check_nest_attributes(the_class, scratch_class);
 988   if (err != JVMTI_ERROR_NONE) {
 989     return err;
 990   }
 991 
 992   // Check whether the Record attribute has been changed.
 993   err = check_record_attribute(the_class, scratch_class);
 994   if (err != JVMTI_ERROR_NONE) {
 995     return err;
 996   }
 997 
 998   // Check whether the PermittedSubclasses attribute has been changed.
 999   err = check_permitted_subclasses_attribute(the_class, scratch_class);
1000   if (err != JVMTI_ERROR_NONE) {
1001     return err;
1002   }
1003 






1004   // Check whether class modifiers are the same.
1005   jushort old_flags = (jushort) the_class->access_flags().get_flags();
1006   jushort new_flags = (jushort) scratch_class->access_flags().get_flags();
1007   if (old_flags != new_flags) {
1008     log_info(redefine, class, normalize)
1009         ("redefined class %s modifiers change error: modifiers changed from %d to %d.",
1010          the_class->external_name(), old_flags, new_flags);
1011     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
1012   }
1013 
1014   // Check if the number, names, types and order of fields declared in these classes
1015   // are the same.
1016   JavaFieldStream old_fs(the_class);
1017   JavaFieldStream new_fs(scratch_class);
1018   for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) {
1019     // name and signature
1020     Symbol* name_sym1 = the_class->constants()->symbol_at(old_fs.name_index());
1021     Symbol* sig_sym1 = the_class->constants()->symbol_at(old_fs.signature_index());
1022     Symbol* name_sym2 = scratch_class->constants()->symbol_at(new_fs.name_index());
1023     Symbol* sig_sym2 = scratch_class->constants()->symbol_at(new_fs.signature_index());

1911 bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class) {
1912 
1913   // rewrite constant pool references in the nest attributes:
1914   if (!rewrite_cp_refs_in_nest_attributes(scratch_class)) {
1915     // propagate failure back to caller
1916     return false;
1917   }
1918 
1919   // rewrite constant pool references in the Record attribute:
1920   if (!rewrite_cp_refs_in_record_attribute(scratch_class)) {
1921     // propagate failure back to caller
1922     return false;
1923   }
1924 
1925   // rewrite constant pool references in the PermittedSubclasses attribute:
1926   if (!rewrite_cp_refs_in_permitted_subclasses_attribute(scratch_class)) {
1927     // propagate failure back to caller
1928     return false;
1929   }
1930 






1931   // rewrite constant pool references in the methods:
1932   if (!rewrite_cp_refs_in_methods(scratch_class)) {
1933     // propagate failure back to caller
1934     return false;
1935   }
1936 
1937   // rewrite constant pool references in the class_annotations:
1938   if (!rewrite_cp_refs_in_class_annotations(scratch_class)) {
1939     // propagate failure back to caller
1940     return false;
1941   }
1942 
1943   // rewrite constant pool references in the fields_annotations:
1944   if (!rewrite_cp_refs_in_fields_annotations(scratch_class)) {
1945     // propagate failure back to caller
1946     return false;
1947   }
1948 
1949   // rewrite constant pool references in the methods_annotations:
1950   if (!rewrite_cp_refs_in_methods_annotations(scratch_class)) {

2059         }
2060       }
2061     }
2062   }
2063   return true;
2064 }
2065 
2066 // Rewrite constant pool references in the PermittedSubclasses attribute.
2067 bool VM_RedefineClasses::rewrite_cp_refs_in_permitted_subclasses_attribute(
2068        InstanceKlass* scratch_class) {
2069 
2070   Array<u2>* permitted_subclasses = scratch_class->permitted_subclasses();
2071   assert(permitted_subclasses != nullptr, "unexpected null permitted_subclasses");
2072   for (int i = 0; i < permitted_subclasses->length(); i++) {
2073     u2 cp_index = permitted_subclasses->at(i);
2074     permitted_subclasses->at_put(i, find_new_index(cp_index));
2075   }
2076   return true;
2077 }
2078 













2079 // Rewrite constant pool references in the methods.
2080 bool VM_RedefineClasses::rewrite_cp_refs_in_methods(InstanceKlass* scratch_class) {
2081 
2082   Array<Method*>* methods = scratch_class->methods();
2083 
2084   if (methods == nullptr || methods->length() == 0) {
2085     // no methods so nothing to do
2086     return true;
2087   }
2088 
2089   JavaThread* THREAD = JavaThread::current(); // For exception macros.
2090   ExceptionMark em(THREAD);
2091 
2092   // rewrite constant pool references in the methods:
2093   for (int i = methods->length() - 1; i >= 0; i--) {
2094     methodHandle method(THREAD, methods->at(i));
2095     methodHandle new_method;
2096     rewrite_cp_refs_in_method(method, &new_method, THREAD);
2097     if (!new_method.is_null()) {
2098       // the method has been replaced so save the new method version

 592       if (scratch_i != *merge_cp_length_p) {
 593         // The new entry in *merge_cp_p is at a different index than
 594         // the new entry in scratch_cp so we need to map the index values.
 595         map_index(scratch_cp, scratch_i, *merge_cp_length_p);
 596       }
 597       (*merge_cp_length_p)++;
 598     } break;
 599 
 600     // At this stage, Class or UnresolvedClass could be in scratch_cp, but not
 601     // ClassIndex
 602     case JVM_CONSTANT_ClassIndex: // fall through
 603 
 604     // Invalid is used as the tag for the second constant pool entry
 605     // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should
 606     // not be seen by itself.
 607     case JVM_CONSTANT_Invalid: // fall through
 608 
 609     // At this stage, String could be here, but not StringIndex
 610     case JVM_CONSTANT_StringIndex: // fall through
 611 
 612     // At this stage JVM_CONSTANT_UnresolvedClassInError should not be here

 613     case JVM_CONSTANT_UnresolvedClassInError: // fall through
 614 
 615     default:
 616     {
 617       // leave a breadcrumb
 618       jbyte bad_value = scratch_cp->tag_at(scratch_i).value();
 619       ShouldNotReachHere();
 620     } break;
 621   } // end switch tag value
 622 } // end append_entry()
 623 
 624 
 625 u2 VM_RedefineClasses::find_or_append_indirect_entry(const constantPoolHandle& scratch_cp,
 626       int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p) {
 627 
 628   int new_ref_i = ref_i;
 629   bool match = (ref_i < *merge_cp_length_p) &&
 630                scratch_cp->compare_entry_to(ref_i, *merge_cp_p, ref_i);
 631 
 632   if (!match) {

 904        the_class->external_name(), action_str);
 905     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED;
 906   }
 907 
 908   return JVMTI_ERROR_NONE;
 909 }
 910 
 911 
 912 static jvmtiError check_permitted_subclasses_attribute(InstanceKlass* the_class,
 913                                                        InstanceKlass* scratch_class) {
 914   Thread* thread = Thread::current();
 915   ResourceMark rm(thread);
 916 
 917   // Check whether the class PermittedSubclasses attribute has been changed.
 918   return check_attribute_arrays("PermittedSubclasses",
 919                                 the_class, scratch_class,
 920                                 the_class->permitted_subclasses(),
 921                                 scratch_class->permitted_subclasses());
 922 }
 923 
 924 static jvmtiError check_preload_attribute(InstanceKlass* the_class,
 925                                           InstanceKlass* scratch_class) {
 926   Thread* thread = Thread::current();
 927   ResourceMark rm(thread);
 928 
 929   // Check whether the class Preload attribute has been changed.
 930   return check_attribute_arrays("Preload",
 931                                 the_class, scratch_class,
 932                                 the_class->preload_classes(),
 933                                 scratch_class->preload_classes());
 934 }
 935 
 936 static bool can_add_or_delete(Method* m) {
 937       // Compatibility mode
 938   return (AllowRedefinitionToAddDeleteMethods &&
 939           (m->is_private() && (m->is_static() || m->is_final())));
 940 }
 941 
 942 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
 943              InstanceKlass* the_class,
 944              InstanceKlass* scratch_class) {
 945   int i;
 946 
 947   // Check superclasses, or rather their names, since superclasses themselves can be
 948   // requested to replace.
 949   // Check for null superclass first since this might be java.lang.Object
 950   if (the_class->super() != scratch_class->super() &&
 951       (the_class->super() == nullptr || scratch_class->super() == nullptr ||
 952        the_class->super()->name() !=
 953        scratch_class->super()->name())) {
 954     log_info(redefine, class, normalize)
 955       ("redefined class %s superclass change error: superclass changed from %s to %s.",

 995   }
 996 
 997   // Check whether the nest-related attributes have been changed.
 998   jvmtiError err = check_nest_attributes(the_class, scratch_class);
 999   if (err != JVMTI_ERROR_NONE) {
1000     return err;
1001   }
1002 
1003   // Check whether the Record attribute has been changed.
1004   err = check_record_attribute(the_class, scratch_class);
1005   if (err != JVMTI_ERROR_NONE) {
1006     return err;
1007   }
1008 
1009   // Check whether the PermittedSubclasses attribute has been changed.
1010   err = check_permitted_subclasses_attribute(the_class, scratch_class);
1011   if (err != JVMTI_ERROR_NONE) {
1012     return err;
1013   }
1014 
1015   // Check whether the Preload attribute has been changed.
1016   err = check_preload_attribute(the_class, scratch_class);
1017   if (err != JVMTI_ERROR_NONE) {
1018     return err;
1019   }
1020 
1021   // Check whether class modifiers are the same.
1022   jushort old_flags = (jushort) the_class->access_flags().get_flags();
1023   jushort new_flags = (jushort) scratch_class->access_flags().get_flags();
1024   if (old_flags != new_flags) {
1025     log_info(redefine, class, normalize)
1026         ("redefined class %s modifiers change error: modifiers changed from %d to %d.",
1027          the_class->external_name(), old_flags, new_flags);
1028     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
1029   }
1030 
1031   // Check if the number, names, types and order of fields declared in these classes
1032   // are the same.
1033   JavaFieldStream old_fs(the_class);
1034   JavaFieldStream new_fs(scratch_class);
1035   for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) {
1036     // name and signature
1037     Symbol* name_sym1 = the_class->constants()->symbol_at(old_fs.name_index());
1038     Symbol* sig_sym1 = the_class->constants()->symbol_at(old_fs.signature_index());
1039     Symbol* name_sym2 = scratch_class->constants()->symbol_at(new_fs.name_index());
1040     Symbol* sig_sym2 = scratch_class->constants()->symbol_at(new_fs.signature_index());

1928 bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class) {
1929 
1930   // rewrite constant pool references in the nest attributes:
1931   if (!rewrite_cp_refs_in_nest_attributes(scratch_class)) {
1932     // propagate failure back to caller
1933     return false;
1934   }
1935 
1936   // rewrite constant pool references in the Record attribute:
1937   if (!rewrite_cp_refs_in_record_attribute(scratch_class)) {
1938     // propagate failure back to caller
1939     return false;
1940   }
1941 
1942   // rewrite constant pool references in the PermittedSubclasses attribute:
1943   if (!rewrite_cp_refs_in_permitted_subclasses_attribute(scratch_class)) {
1944     // propagate failure back to caller
1945     return false;
1946   }
1947 
1948   // rewrite constant pool references in the Preload attribute:
1949   if (!rewrite_cp_refs_in_preload_attribute(scratch_class)) {
1950     // propagate failure back to caller
1951     return false;
1952   }
1953 
1954   // rewrite constant pool references in the methods:
1955   if (!rewrite_cp_refs_in_methods(scratch_class)) {
1956     // propagate failure back to caller
1957     return false;
1958   }
1959 
1960   // rewrite constant pool references in the class_annotations:
1961   if (!rewrite_cp_refs_in_class_annotations(scratch_class)) {
1962     // propagate failure back to caller
1963     return false;
1964   }
1965 
1966   // rewrite constant pool references in the fields_annotations:
1967   if (!rewrite_cp_refs_in_fields_annotations(scratch_class)) {
1968     // propagate failure back to caller
1969     return false;
1970   }
1971 
1972   // rewrite constant pool references in the methods_annotations:
1973   if (!rewrite_cp_refs_in_methods_annotations(scratch_class)) {

2082         }
2083       }
2084     }
2085   }
2086   return true;
2087 }
2088 
2089 // Rewrite constant pool references in the PermittedSubclasses attribute.
2090 bool VM_RedefineClasses::rewrite_cp_refs_in_permitted_subclasses_attribute(
2091        InstanceKlass* scratch_class) {
2092 
2093   Array<u2>* permitted_subclasses = scratch_class->permitted_subclasses();
2094   assert(permitted_subclasses != nullptr, "unexpected null permitted_subclasses");
2095   for (int i = 0; i < permitted_subclasses->length(); i++) {
2096     u2 cp_index = permitted_subclasses->at(i);
2097     permitted_subclasses->at_put(i, find_new_index(cp_index));
2098   }
2099   return true;
2100 }
2101 
2102 // Rewrite constant pool references in the Preload attribute.
2103 bool VM_RedefineClasses::rewrite_cp_refs_in_preload_attribute(
2104        InstanceKlass* scratch_class) {
2105 
2106   Array<u2>* preload_classes = scratch_class->preload_classes();
2107   assert(preload_classes != nullptr, "unexpected null preload_classes");
2108   for (int i = 0; i < preload_classes->length(); i++) {
2109     u2 cp_index = preload_classes->at(i);
2110     preload_classes->at_put(i, find_new_index(cp_index));
2111   }
2112   return true;
2113 }
2114 
2115 // Rewrite constant pool references in the methods.
2116 bool VM_RedefineClasses::rewrite_cp_refs_in_methods(InstanceKlass* scratch_class) {
2117 
2118   Array<Method*>* methods = scratch_class->methods();
2119 
2120   if (methods == nullptr || methods->length() == 0) {
2121     // no methods so nothing to do
2122     return true;
2123   }
2124 
2125   JavaThread* THREAD = JavaThread::current(); // For exception macros.
2126   ExceptionMark em(THREAD);
2127 
2128   // rewrite constant pool references in the methods:
2129   for (int i = methods->length() - 1; i >= 0; i--) {
2130     methodHandle method(THREAD, methods->at(i));
2131     methodHandle new_method;
2132     rewrite_cp_refs_in_method(method, &new_method, THREAD);
2133     if (!new_method.is_null()) {
2134       // the method has been replaced so save the new method version
< prev index next >