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 |