Mercurial > hg > graal-jvmci-8
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 |