hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
changeset 10546 e79347eebbc5
parent 9971 d496ecd7b9de
child 11399 5dd5c4dd4b7d
equal deleted inserted replaced
10545:fec876499aae 10546:e79347eebbc5
    28 #include "code/codeCache.hpp"
    28 #include "code/codeCache.hpp"
    29 #include "interpreter/oopMapCache.hpp"
    29 #include "interpreter/oopMapCache.hpp"
    30 #include "interpreter/rewriter.hpp"
    30 #include "interpreter/rewriter.hpp"
    31 #include "memory/gcLocker.hpp"
    31 #include "memory/gcLocker.hpp"
    32 #include "memory/universe.inline.hpp"
    32 #include "memory/universe.inline.hpp"
       
    33 #include "oops/fieldStreams.hpp"
    33 #include "oops/klassVtable.hpp"
    34 #include "oops/klassVtable.hpp"
    34 #include "prims/jvmtiImpl.hpp"
    35 #include "prims/jvmtiImpl.hpp"
    35 #include "prims/jvmtiRedefineClasses.hpp"
    36 #include "prims/jvmtiRedefineClasses.hpp"
    36 #include "prims/methodComparator.hpp"
    37 #include "prims/methodComparator.hpp"
    37 #include "runtime/deoptimization.hpp"
    38 #include "runtime/deoptimization.hpp"
   549     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
   550     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
   550   }
   551   }
   551 
   552 
   552   // Check if the number, names, types and order of fields declared in these classes
   553   // Check if the number, names, types and order of fields declared in these classes
   553   // are the same.
   554   // are the same.
   554   typeArrayOop k_old_fields = the_class->fields();
   555   JavaFieldStream old_fs(the_class);
   555   typeArrayOop k_new_fields = scratch_class->fields();
   556   JavaFieldStream new_fs(scratch_class);
   556   int n_fields = k_old_fields->length();
   557   for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) {
   557   if (n_fields != k_new_fields->length()) {
       
   558     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
       
   559   }
       
   560 
       
   561   for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
       
   562     // access
   558     // access
   563     old_flags = k_old_fields->ushort_at(i + instanceKlass::access_flags_offset);
   559     old_flags = old_fs.access_flags().as_short();
   564     new_flags = k_new_fields->ushort_at(i + instanceKlass::access_flags_offset);
   560     new_flags = new_fs.access_flags().as_short();
   565     if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {
   561     if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {
   566       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
   562       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
   567     }
   563     }
   568     // offset
   564     // offset
   569     if (k_old_fields->short_at(i + instanceKlass::low_offset) !=
   565     if (old_fs.offset() != new_fs.offset()) {
   570         k_new_fields->short_at(i + instanceKlass::low_offset) ||
       
   571         k_old_fields->short_at(i + instanceKlass::high_offset) !=
       
   572         k_new_fields->short_at(i + instanceKlass::high_offset)) {
       
   573       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
   566       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
   574     }
   567     }
   575     // name and signature
   568     // name and signature
   576     jshort name_index = k_old_fields->short_at(i + instanceKlass::name_index_offset);
   569     Symbol* name_sym1 = the_class->constants()->symbol_at(old_fs.name_index());
   577     jshort sig_index = k_old_fields->short_at(i +instanceKlass::signature_index_offset);
   570     Symbol* sig_sym1 = the_class->constants()->symbol_at(old_fs.signature_index());
   578     Symbol* name_sym1 = the_class->constants()->symbol_at(name_index);
   571     Symbol* name_sym2 = scratch_class->constants()->symbol_at(new_fs.name_index());
   579     Symbol* sig_sym1 = the_class->constants()->symbol_at(sig_index);
   572     Symbol* sig_sym2 = scratch_class->constants()->symbol_at(new_fs.signature_index());
   580     name_index = k_new_fields->short_at(i + instanceKlass::name_index_offset);
       
   581     sig_index = k_new_fields->short_at(i + instanceKlass::signature_index_offset);
       
   582     Symbol* name_sym2 = scratch_class->constants()->symbol_at(name_index);
       
   583     Symbol* sig_sym2 = scratch_class->constants()->symbol_at(sig_index);
       
   584     if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) {
   573     if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) {
   585       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
   574       return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
   586     }
   575     }
       
   576   }
       
   577 
       
   578   // If both streams aren't done then we have a differing number of
       
   579   // fields.
       
   580   if (!old_fs.done() || !new_fs.done()) {
       
   581     return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
   587   }
   582   }
   588 
   583 
   589   // Do a parallel walk through the old and new methods. Detect
   584   // Do a parallel walk through the old and new methods. Detect
   590   // cases where they match (exist in both), have been added in
   585   // cases where they match (exist in both), have been added in
   591   // the new methods, or have been deleted (exist only in the
   586   // the new methods, or have been deleted (exist only in the
  2367   scratch_class->set_constants(scratch_cp());
  2362   scratch_class->set_constants(scratch_cp());
  2368 
  2363 
  2369   int i;  // for portability
  2364   int i;  // for portability
  2370 
  2365 
  2371   // update each field in klass to use new constant pool indices as needed
  2366   // update each field in klass to use new constant pool indices as needed
  2372   typeArrayHandle fields(THREAD, scratch_class->fields());
  2367   for (JavaFieldStream fs(scratch_class); !fs.done(); fs.next()) {
  2373   int n_fields = fields->length();
  2368     jshort cur_index = fs.name_index();
  2374   for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
       
  2375     jshort cur_index = fields->short_at(i + instanceKlass::name_index_offset);
       
  2376     jshort new_index = find_new_index(cur_index);
  2369     jshort new_index = find_new_index(cur_index);
  2377     if (new_index != 0) {
  2370     if (new_index != 0) {
  2378       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
  2371       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
  2379         ("field-name_index change: %d to %d", cur_index, new_index));
  2372         ("field-name_index change: %d to %d", cur_index, new_index));
  2380       fields->short_at_put(i + instanceKlass::name_index_offset, new_index);
  2373       fs.set_name_index(new_index);
  2381     }
  2374     }
  2382     cur_index = fields->short_at(i + instanceKlass::signature_index_offset);
  2375     cur_index = fs.signature_index();
  2383     new_index = find_new_index(cur_index);
  2376     new_index = find_new_index(cur_index);
  2384     if (new_index != 0) {
  2377     if (new_index != 0) {
  2385       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
  2378       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
  2386         ("field-signature_index change: %d to %d", cur_index, new_index));
  2379         ("field-signature_index change: %d to %d", cur_index, new_index));
  2387       fields->short_at_put(i + instanceKlass::signature_index_offset,
  2380       fs.set_signature_index(new_index);
  2388         new_index);
  2381     }
  2389     }
  2382     cur_index = fs.initval_index();
  2390     cur_index = fields->short_at(i + instanceKlass::initval_index_offset);
       
  2391     new_index = find_new_index(cur_index);
  2383     new_index = find_new_index(cur_index);
  2392     if (new_index != 0) {
  2384     if (new_index != 0) {
  2393       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
  2385       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
  2394         ("field-initval_index change: %d to %d", cur_index, new_index));
  2386         ("field-initval_index change: %d to %d", cur_index, new_index));
  2395       fields->short_at_put(i + instanceKlass::initval_index_offset, new_index);
  2387       fs.set_initval_index(new_index);
  2396     }
  2388     }
  2397     cur_index = fields->short_at(i + instanceKlass::generic_signature_offset);
  2389     cur_index = fs.generic_signature_index();
  2398     new_index = find_new_index(cur_index);
  2390     new_index = find_new_index(cur_index);
  2399     if (new_index != 0) {
  2391     if (new_index != 0) {
  2400       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
  2392       RC_TRACE_WITH_THREAD(0x00080000, THREAD,
  2401         ("field-generic_signature change: %d to %d", cur_index, new_index));
  2393         ("field-generic_signature change: %d to %d", cur_index, new_index));
  2402       fields->short_at_put(i + instanceKlass::generic_signature_offset,
  2394       fs.set_generic_signature_index(new_index);
  2403         new_index);
       
  2404     }
  2395     }
  2405   } // end for each field
  2396   } // end for each field
  2406 
  2397 
  2407   // Update constant pool indices in the inner classes info to use
  2398   // Update constant pool indices in the inner classes info to use
  2408   // new constant indices as needed. The inner classes info is a
  2399   // new constant indices as needed. The inner classes info is a