comparison src/share/vm/prims/jvmtiRedefineClasses.cpp @ 3938:e6b1331a51d2

7086585: make Java field injection more flexible Reviewed-by: jrose, twisti, kvn, coleenp
author never
date Sat, 10 Sep 2011 17:29:02 -0700
parents d3b9f2be46ab
children 4ceaf61479fc
comparison
equal deleted inserted replaced
3937:c565834fb592 3938:e6b1331a51d2
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