changeset 38259 | b495d1cfe673 |
parent 38051 | d092550d625d |
child 38309 | 9b8e9c373740 |
38251:6a4902a969d3 | 38259:b495d1cfe673 |
---|---|
30 #include "code/codeCache.hpp" |
30 #include "code/codeCache.hpp" |
31 #include "compiler/compileBroker.hpp" |
31 #include "compiler/compileBroker.hpp" |
32 #include "gc/shared/gcLocker.hpp" |
32 #include "gc/shared/gcLocker.hpp" |
33 #include "interpreter/oopMapCache.hpp" |
33 #include "interpreter/oopMapCache.hpp" |
34 #include "interpreter/rewriter.hpp" |
34 #include "interpreter/rewriter.hpp" |
35 #include "logging/logStream.hpp" |
|
35 #include "memory/metadataFactory.hpp" |
36 #include "memory/metadataFactory.hpp" |
36 #include "memory/metaspaceShared.hpp" |
37 #include "memory/metaspaceShared.hpp" |
37 #include "memory/resourceArea.hpp" |
38 #include "memory/resourceArea.hpp" |
38 #include "memory/universe.inline.hpp" |
39 #include "memory/universe.inline.hpp" |
39 #include "oops/fieldStreams.hpp" |
40 #include "oops/fieldStreams.hpp" |
92 } |
93 } |
93 } |
94 } |
94 |
95 |
95 // Start timer after all the sanity checks; not quite accurate, but |
96 // Start timer after all the sanity checks; not quite accurate, but |
96 // better than adding a bunch of stop() calls. |
97 // better than adding a bunch of stop() calls. |
97 RC_TIMER_START(_timer_vm_op_prologue); |
98 if (log_is_enabled(Info, redefine, class, timer)) { |
99 _timer_vm_op_prologue.start(); |
|
100 } |
|
98 |
101 |
99 // We first load new class versions in the prologue, because somewhere down the |
102 // We first load new class versions in the prologue, because somewhere down the |
100 // call chain it is required that the current thread is a Java thread. |
103 // call chain it is required that the current thread is a Java thread. |
101 _res = load_new_class_versions(Thread::current()); |
104 _res = load_new_class_versions(Thread::current()); |
102 if (_res != JVMTI_ERROR_NONE) { |
105 if (_res != JVMTI_ERROR_NONE) { |
109 cld->add_to_deallocate_list(InstanceKlass::cast(_scratch_classes[i])); |
112 cld->add_to_deallocate_list(InstanceKlass::cast(_scratch_classes[i])); |
110 } |
113 } |
111 } |
114 } |
112 // Free os::malloc allocated memory in load_new_class_version. |
115 // Free os::malloc allocated memory in load_new_class_version. |
113 os::free(_scratch_classes); |
116 os::free(_scratch_classes); |
114 RC_TIMER_STOP(_timer_vm_op_prologue); |
117 _timer_vm_op_prologue.stop(); |
115 return false; |
118 return false; |
116 } |
119 } |
117 |
120 |
118 RC_TIMER_STOP(_timer_vm_op_prologue); |
121 _timer_vm_op_prologue.stop(); |
119 return true; |
122 return true; |
120 } |
123 } |
121 |
124 |
122 void VM_RedefineClasses::doit() { |
125 void VM_RedefineClasses::doit() { |
123 Thread *thread = Thread::current(); |
126 Thread *thread = Thread::current(); |
126 // Sharing is enabled so we remap the shared readonly space to |
129 // Sharing is enabled so we remap the shared readonly space to |
127 // shared readwrite, private just in case we need to redefine |
130 // shared readwrite, private just in case we need to redefine |
128 // a shared class. We do the remap during the doit() phase of |
131 // a shared class. We do the remap during the doit() phase of |
129 // the safepoint to be safer. |
132 // the safepoint to be safer. |
130 if (!MetaspaceShared::remap_shared_readonly_as_readwrite()) { |
133 if (!MetaspaceShared::remap_shared_readonly_as_readwrite()) { |
131 RC_TRACE_WITH_THREAD(0x00000001, thread, |
134 log_info(redefine, class, load)("failed to remap shared readonly space to readwrite, private"); |
132 ("failed to remap shared readonly space to readwrite, private")); |
|
133 _res = JVMTI_ERROR_INTERNAL; |
135 _res = JVMTI_ERROR_INTERNAL; |
134 return; |
136 return; |
135 } |
137 } |
136 } |
138 } |
137 |
139 |
159 JvmtiExport::set_has_redefined_a_class(); |
161 JvmtiExport::set_has_redefined_a_class(); |
160 |
162 |
161 // check_class() is optionally called for product bits, but is |
163 // check_class() is optionally called for product bits, but is |
162 // always called for non-product bits. |
164 // always called for non-product bits. |
163 #ifdef PRODUCT |
165 #ifdef PRODUCT |
164 if (RC_TRACE_ENABLED(0x00004000)) { |
166 if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) { |
165 #endif |
167 #endif |
166 RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class")); |
168 log_trace(redefine, class, obsolete, metadata)("calling check_class"); |
167 CheckClass check_class(thread); |
169 CheckClass check_class(thread); |
168 ClassLoaderDataGraph::classes_do(&check_class); |
170 ClassLoaderDataGraph::classes_do(&check_class); |
169 #ifdef PRODUCT |
171 #ifdef PRODUCT |
170 } |
172 } |
171 #endif |
173 #endif |
176 os::free(_scratch_classes); |
178 os::free(_scratch_classes); |
177 |
179 |
178 // Reset the_class_oop to null for error printing. |
180 // Reset the_class_oop to null for error printing. |
179 _the_class_oop = NULL; |
181 _the_class_oop = NULL; |
180 |
182 |
181 if (RC_TRACE_ENABLED(0x00000004)) { |
183 if (log_is_enabled(Info, redefine, class, timer)) { |
182 // Used to have separate timers for "doit" and "all", but the timer |
184 // Used to have separate timers for "doit" and "all", but the timer |
183 // overhead skewed the measurements. |
185 // overhead skewed the measurements. |
184 jlong doit_time = _timer_rsc_phase1.milliseconds() + |
186 jlong doit_time = _timer_rsc_phase1.milliseconds() + |
185 _timer_rsc_phase2.milliseconds(); |
187 _timer_rsc_phase2.milliseconds(); |
186 jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time; |
188 jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time; |
187 |
189 |
188 RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT |
190 log_info(redefine, class, timer) |
189 " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT, all_time, |
191 ("vm_op: all=" UINT64_FORMAT " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT, |
190 _timer_vm_op_prologue.milliseconds(), doit_time)); |
192 all_time, _timer_vm_op_prologue.milliseconds(), doit_time); |
191 RC_TRACE(0x00000004, |
193 log_info(redefine, class, timer) |
192 ("redefine_single_class: phase1=" UINT64_FORMAT " phase2=" UINT64_FORMAT, |
194 ("redefine_single_class: phase1=" UINT64_FORMAT " phase2=" UINT64_FORMAT, |
193 _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds())); |
195 _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds()); |
194 } |
196 } |
195 } |
197 } |
196 |
198 |
197 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) { |
199 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) { |
198 // classes for primitives cannot be redefined |
200 // classes for primitives cannot be redefined |
303 |
305 |
304 // If the referenced entries already exist in *merge_cp_p, then |
306 // If the referenced entries already exist in *merge_cp_p, then |
305 // both new_name_ref_i and new_signature_ref_i will both be 0. |
307 // both new_name_ref_i and new_signature_ref_i will both be 0. |
306 // In that case, all we are appending is the current entry. |
308 // In that case, all we are appending is the current entry. |
307 if (new_name_ref_i != name_ref_i) { |
309 if (new_name_ref_i != name_ref_i) { |
308 RC_TRACE(0x00080000, |
310 log_trace(redefine, class, constantpool) |
309 ("NameAndType entry@%d name_ref_index change: %d to %d", |
311 ("NameAndType entry@%d name_ref_index change: %d to %d", |
310 *merge_cp_length_p, name_ref_i, new_name_ref_i)); |
312 *merge_cp_length_p, name_ref_i, new_name_ref_i); |
311 } |
313 } |
312 if (new_signature_ref_i != signature_ref_i) { |
314 if (new_signature_ref_i != signature_ref_i) { |
313 RC_TRACE(0x00080000, |
315 log_trace(redefine, class, constantpool) |
314 ("NameAndType entry@%d signature_ref_index change: %d to %d", |
316 ("NameAndType entry@%d signature_ref_index change: %d to %d", |
315 *merge_cp_length_p, signature_ref_i, new_signature_ref_i)); |
317 *merge_cp_length_p, signature_ref_i, new_signature_ref_i); |
316 } |
318 } |
317 |
319 |
318 (*merge_cp_p)->name_and_type_at_put(*merge_cp_length_p, |
320 (*merge_cp_p)->name_and_type_at_put(*merge_cp_length_p, |
319 new_name_ref_i, new_signature_ref_i); |
321 new_name_ref_i, new_signature_ref_i); |
320 if (scratch_i != *merge_cp_length_p) { |
322 if (scratch_i != *merge_cp_length_p) { |
359 guarantee(false, "bad switch"); |
361 guarantee(false, "bad switch"); |
360 break; |
362 break; |
361 } |
363 } |
362 |
364 |
363 if (klass_ref_i != new_klass_ref_i) { |
365 if (klass_ref_i != new_klass_ref_i) { |
364 RC_TRACE(0x00080000, ("%s entry@%d class_index changed: %d to %d", |
366 log_trace(redefine, class, constantpool) |
365 entry_name, *merge_cp_length_p, klass_ref_i, new_klass_ref_i)); |
367 ("%s entry@%d class_index changed: %d to %d", entry_name, *merge_cp_length_p, klass_ref_i, new_klass_ref_i); |
366 } |
368 } |
367 if (name_and_type_ref_i != new_name_and_type_ref_i) { |
369 if (name_and_type_ref_i != new_name_and_type_ref_i) { |
368 RC_TRACE(0x00080000, |
370 log_trace(redefine, class, constantpool) |
369 ("%s entry@%d name_and_type_index changed: %d to %d", |
371 ("%s entry@%d name_and_type_index changed: %d to %d", |
370 entry_name, *merge_cp_length_p, name_and_type_ref_i, |
372 entry_name, *merge_cp_length_p, name_and_type_ref_i, new_name_and_type_ref_i); |
371 new_name_and_type_ref_i)); |
|
372 } |
373 } |
373 |
374 |
374 if (scratch_i != *merge_cp_length_p) { |
375 if (scratch_i != *merge_cp_length_p) { |
375 // The new entry in *merge_cp_p is at a different index than |
376 // The new entry in *merge_cp_p is at a different index than |
376 // the new entry in scratch_cp so we need to map the index values. |
377 // the new entry in scratch_cp so we need to map the index values. |
384 { |
385 { |
385 int ref_i = scratch_cp->method_type_index_at(scratch_i); |
386 int ref_i = scratch_cp->method_type_index_at(scratch_i); |
386 int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, |
387 int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, |
387 merge_cp_length_p, THREAD); |
388 merge_cp_length_p, THREAD); |
388 if (new_ref_i != ref_i) { |
389 if (new_ref_i != ref_i) { |
389 RC_TRACE(0x00080000, |
390 log_trace(redefine, class, constantpool) |
390 ("MethodType entry@%d ref_index change: %d to %d", |
391 ("MethodType entry@%d ref_index change: %d to %d", *merge_cp_length_p, ref_i, new_ref_i); |
391 *merge_cp_length_p, ref_i, new_ref_i)); |
|
392 } |
392 } |
393 (*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i); |
393 (*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i); |
394 if (scratch_i != *merge_cp_length_p) { |
394 if (scratch_i != *merge_cp_length_p) { |
395 // The new entry in *merge_cp_p is at a different index than |
395 // The new entry in *merge_cp_p is at a different index than |
396 // the new entry in scratch_cp so we need to map the index values. |
396 // the new entry in scratch_cp so we need to map the index values. |
405 int ref_kind = scratch_cp->method_handle_ref_kind_at(scratch_i); |
405 int ref_kind = scratch_cp->method_handle_ref_kind_at(scratch_i); |
406 int ref_i = scratch_cp->method_handle_index_at(scratch_i); |
406 int ref_i = scratch_cp->method_handle_index_at(scratch_i); |
407 int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, |
407 int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, |
408 merge_cp_length_p, THREAD); |
408 merge_cp_length_p, THREAD); |
409 if (new_ref_i != ref_i) { |
409 if (new_ref_i != ref_i) { |
410 RC_TRACE(0x00080000, |
410 log_trace(redefine, class, constantpool) |
411 ("MethodHandle entry@%d ref_index change: %d to %d", |
411 ("MethodHandle entry@%d ref_index change: %d to %d", *merge_cp_length_p, ref_i, new_ref_i); |
412 *merge_cp_length_p, ref_i, new_ref_i)); |
|
413 } |
412 } |
414 (*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i); |
413 (*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i); |
415 if (scratch_i != *merge_cp_length_p) { |
414 if (scratch_i != *merge_cp_length_p) { |
416 // The new entry in *merge_cp_p is at a different index than |
415 // The new entry in *merge_cp_p is at a different index than |
417 // the new entry in scratch_cp so we need to map the index values. |
416 // the new entry in scratch_cp so we need to map the index values. |
430 // The bootstrap method NameAndType_info index |
429 // The bootstrap method NameAndType_info index |
431 int old_ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i); |
430 int old_ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i); |
432 int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p, |
431 int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p, |
433 merge_cp_length_p, THREAD); |
432 merge_cp_length_p, THREAD); |
434 if (new_bs_i != old_bs_i) { |
433 if (new_bs_i != old_bs_i) { |
435 RC_TRACE(0x00080000, |
434 log_trace(redefine, class, constantpool) |
436 ("InvokeDynamic entry@%d bootstrap_method_attr_index change: %d to %d", |
435 ("InvokeDynamic entry@%d bootstrap_method_attr_index change: %d to %d", |
437 *merge_cp_length_p, old_bs_i, new_bs_i)); |
436 *merge_cp_length_p, old_bs_i, new_bs_i); |
438 } |
437 } |
439 if (new_ref_i != old_ref_i) { |
438 if (new_ref_i != old_ref_i) { |
440 RC_TRACE(0x00080000, |
439 log_trace(redefine, class, constantpool) |
441 ("InvokeDynamic entry@%d name_and_type_index change: %d to %d", |
440 ("InvokeDynamic entry@%d name_and_type_index change: %d to %d", *merge_cp_length_p, old_ref_i, new_ref_i); |
442 *merge_cp_length_p, old_ref_i, new_ref_i)); |
|
443 } |
441 } |
444 |
442 |
445 (*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, new_bs_i, new_ref_i); |
443 (*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, new_bs_i, new_ref_i); |
446 if (scratch_i != *merge_cp_length_p) { |
444 if (scratch_i != *merge_cp_length_p) { |
447 // The new entry in *merge_cp_p is at a different index than |
445 // The new entry in *merge_cp_p is at a different index than |
514 |
512 |
515 int old_ref_i = scratch_cp->operand_bootstrap_method_ref_index_at(old_bs_i); |
513 int old_ref_i = scratch_cp->operand_bootstrap_method_ref_index_at(old_bs_i); |
516 int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p, |
514 int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p, |
517 merge_cp_length_p, THREAD); |
515 merge_cp_length_p, THREAD); |
518 if (new_ref_i != old_ref_i) { |
516 if (new_ref_i != old_ref_i) { |
519 RC_TRACE(0x00080000, |
517 log_trace(redefine, class, constantpool) |
520 ("operands entry@%d bootstrap method ref_index change: %d to %d", |
518 ("operands entry@%d bootstrap method ref_index change: %d to %d", _operands_cur_length, old_ref_i, new_ref_i); |
521 _operands_cur_length, old_ref_i, new_ref_i)); |
|
522 } |
519 } |
523 |
520 |
524 Array<u2>* merge_ops = (*merge_cp_p)->operands(); |
521 Array<u2>* merge_ops = (*merge_cp_p)->operands(); |
525 int new_bs_i = _operands_cur_length; |
522 int new_bs_i = _operands_cur_length; |
526 // We have _operands_cur_length == 0 when the merge_cp operands is empty yet. |
523 // We have _operands_cur_length == 0 when the merge_cp operands is empty yet. |
537 int old_arg_ref_i = scratch_cp->operand_argument_index_at(old_bs_i, i); |
534 int old_arg_ref_i = scratch_cp->operand_argument_index_at(old_bs_i, i); |
538 int new_arg_ref_i = find_or_append_indirect_entry(scratch_cp, old_arg_ref_i, merge_cp_p, |
535 int new_arg_ref_i = find_or_append_indirect_entry(scratch_cp, old_arg_ref_i, merge_cp_p, |
539 merge_cp_length_p, THREAD); |
536 merge_cp_length_p, THREAD); |
540 merge_ops->at_put(new_base++, new_arg_ref_i); |
537 merge_ops->at_put(new_base++, new_arg_ref_i); |
541 if (new_arg_ref_i != old_arg_ref_i) { |
538 if (new_arg_ref_i != old_arg_ref_i) { |
542 RC_TRACE(0x00080000, |
539 log_trace(redefine, class, constantpool) |
543 ("operands entry@%d bootstrap method argument ref_index change: %d to %d", |
540 ("operands entry@%d bootstrap method argument ref_index change: %d to %d", |
544 _operands_cur_length, old_arg_ref_i, new_arg_ref_i)); |
541 _operands_cur_length, old_arg_ref_i, new_arg_ref_i); |
545 } |
542 } |
546 } |
543 } |
547 if (old_bs_i != _operands_cur_length) { |
544 if (old_bs_i != _operands_cur_length) { |
548 // The bootstrap specifier in *merge_cp_p is at a different index than |
545 // The bootstrap specifier in *merge_cp_p is at a different index than |
549 // that in scratch_cp so we need to map the index values. |
546 // that in scratch_cp so we need to map the index values. |
584 return; |
581 return; |
585 } |
582 } |
586 // Shrink the merge_cp operands |
583 // Shrink the merge_cp operands |
587 merge_cp->shrink_operands(_operands_cur_length, CHECK); |
584 merge_cp->shrink_operands(_operands_cur_length, CHECK); |
588 |
585 |
589 if (RC_TRACE_ENABLED(0x00040000)) { |
586 if (log_is_enabled(Trace, redefine, class, constantpool)) { |
590 // don't want to loop unless we are tracing |
587 // don't want to loop unless we are tracing |
591 int count = 0; |
588 int count = 0; |
592 for (int i = 1; i < _operands_index_map_p->length(); i++) { |
589 for (int i = 1; i < _operands_index_map_p->length(); i++) { |
593 int value = _operands_index_map_p->at(i); |
590 int value = _operands_index_map_p->at(i); |
594 if (value != -1) { |
591 if (value != -1) { |
595 RC_TRACE_WITH_THREAD(0x00040000, THREAD, |
592 log_trace(redefine, class, constantpool)("operands_index_map[%d]: old=%d new=%d", count, i, value); |
596 ("operands_index_map[%d]: old=%d new=%d", count, i, value)); |
|
597 count++; |
593 count++; |
598 } |
594 } |
599 } |
595 } |
600 } |
596 } |
601 // Clean-up |
597 // Clean-up |
793 if (thread->has_pending_exception()) { |
789 if (thread->has_pending_exception()) { |
794 return JVMTI_ERROR_OUT_OF_MEMORY; |
790 return JVMTI_ERROR_OUT_OF_MEMORY; |
795 } |
791 } |
796 } |
792 } |
797 } |
793 } |
798 RC_TRACE(0x00008000, ("Method matched: new: %s [%d] == old: %s [%d]", |
794 log_trace(redefine, class, normalize) |
799 k_new_method->name_and_sig_as_C_string(), ni, |
795 ("Method matched: new: %s [%d] == old: %s [%d]", |
800 k_old_method->name_and_sig_as_C_string(), oi)); |
796 k_new_method->name_and_sig_as_C_string(), ni, k_old_method->name_and_sig_as_C_string(), oi); |
801 // advance to next pair of methods |
797 // advance to next pair of methods |
802 ++oi; |
798 ++oi; |
803 ++ni; |
799 ++ni; |
804 break; |
800 break; |
805 case added: |
801 case added: |
830 k_new_method->set_orig_method_idnum(num); |
826 k_new_method->set_orig_method_idnum(num); |
831 if (thread->has_pending_exception()) { |
827 if (thread->has_pending_exception()) { |
832 return JVMTI_ERROR_OUT_OF_MEMORY; |
828 return JVMTI_ERROR_OUT_OF_MEMORY; |
833 } |
829 } |
834 } |
830 } |
835 RC_TRACE(0x00008000, ("Method added: new: %s [%d]", |
831 log_trace(redefine, class, normalize) |
836 k_new_method->name_and_sig_as_C_string(), ni)); |
832 ("Method added: new: %s [%d]", k_new_method->name_and_sig_as_C_string(), ni); |
837 ++ni; // advance to next new method |
833 ++ni; // advance to next new method |
838 break; |
834 break; |
839 case deleted: |
835 case deleted: |
840 // method deleted, see if it is OK |
836 // method deleted, see if it is OK |
841 old_flags = (jushort) k_old_method->access_flags().get_flags(); |
837 old_flags = (jushort) k_old_method->access_flags().get_flags(); |
844 || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0 |
840 || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0 |
845 ) { |
841 ) { |
846 // deleted methods must be private |
842 // deleted methods must be private |
847 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED; |
843 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED; |
848 } |
844 } |
849 RC_TRACE(0x00008000, ("Method deleted: old: %s [%d]", |
845 log_trace(redefine, class, normalize) |
850 k_old_method->name_and_sig_as_C_string(), oi)); |
846 ("Method deleted: old: %s [%d]", k_old_method->name_and_sig_as_C_string(), oi); |
851 ++oi; // advance to next old method |
847 ++oi; // advance to next old method |
852 break; |
848 break; |
853 default: |
849 default: |
854 ShouldNotReachHere(); |
850 ShouldNotReachHere(); |
855 } |
851 } |
971 } |
967 } |
972 Klass* the_class_oop = java_lang_Class::as_Klass(mirror); |
968 Klass* the_class_oop = java_lang_Class::as_Klass(mirror); |
973 instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop); |
969 instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop); |
974 Symbol* the_class_sym = the_class->name(); |
970 Symbol* the_class_sym = the_class->name(); |
975 |
971 |
976 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
972 log_debug(redefine, class, load) |
977 RC_TRACE_WITH_THREAD(0x00000001, THREAD, |
|
978 ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)", |
973 ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)", |
979 the_class->external_name(), _class_load_kind, |
974 the_class->external_name(), _class_load_kind, os::available_memory() >> 10); |
980 os::available_memory() >> 10)); |
|
981 |
975 |
982 ClassFileStream st((u1*)_class_defs[i].class_bytes, |
976 ClassFileStream st((u1*)_class_defs[i].class_bytes, |
983 _class_defs[i].class_byte_count, |
977 _class_defs[i].class_byte_count, |
984 "__VM_RedefineClasses__", |
978 "__VM_RedefineClasses__", |
985 ClassFileStream::verify); |
979 ClassFileStream::verify); |
1009 // an error. |
1003 // an error. |
1010 _scratch_classes[i] = k; |
1004 _scratch_classes[i] = k; |
1011 |
1005 |
1012 if (HAS_PENDING_EXCEPTION) { |
1006 if (HAS_PENDING_EXCEPTION) { |
1013 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1007 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1014 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1008 log_info(redefine, class, load, exceptions)("parse_stream exception: '%s'", ex_name->as_C_string()); |
1015 RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("parse_stream exception: '%s'", |
|
1016 ex_name->as_C_string())); |
|
1017 CLEAR_PENDING_EXCEPTION; |
1009 CLEAR_PENDING_EXCEPTION; |
1018 |
1010 |
1019 if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) { |
1011 if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) { |
1020 return JVMTI_ERROR_UNSUPPORTED_VERSION; |
1012 return JVMTI_ERROR_UNSUPPORTED_VERSION; |
1021 } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) { |
1013 } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) { |
1035 // Ensure class is linked before redefine |
1027 // Ensure class is linked before redefine |
1036 if (!the_class->is_linked()) { |
1028 if (!the_class->is_linked()) { |
1037 the_class->link_class(THREAD); |
1029 the_class->link_class(THREAD); |
1038 if (HAS_PENDING_EXCEPTION) { |
1030 if (HAS_PENDING_EXCEPTION) { |
1039 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1031 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1040 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1032 log_info(redefine, class, load, exceptions)("link_class exception: '%s'", ex_name->as_C_string()); |
1041 RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("link_class exception: '%s'", |
|
1042 ex_name->as_C_string())); |
|
1043 CLEAR_PENDING_EXCEPTION; |
1033 CLEAR_PENDING_EXCEPTION; |
1044 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1034 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1045 return JVMTI_ERROR_OUT_OF_MEMORY; |
1035 return JVMTI_ERROR_OUT_OF_MEMORY; |
1046 } else { |
1036 } else { |
1047 return JVMTI_ERROR_INTERNAL; |
1037 return JVMTI_ERROR_INTERNAL; |
1073 scratch_class, Verifier::ThrowException, true, THREAD); |
1063 scratch_class, Verifier::ThrowException, true, THREAD); |
1074 } |
1064 } |
1075 |
1065 |
1076 if (HAS_PENDING_EXCEPTION) { |
1066 if (HAS_PENDING_EXCEPTION) { |
1077 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1067 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1078 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1068 log_info(redefine, class, load, exceptions)("verify_byte_codes exception: '%s'", ex_name->as_C_string()); |
1079 RC_TRACE_WITH_THREAD(0x00000002, THREAD, |
|
1080 ("verify_byte_codes exception: '%s'", ex_name->as_C_string())); |
|
1081 CLEAR_PENDING_EXCEPTION; |
1069 CLEAR_PENDING_EXCEPTION; |
1082 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1070 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1083 return JVMTI_ERROR_OUT_OF_MEMORY; |
1071 return JVMTI_ERROR_OUT_OF_MEMORY; |
1084 } else { |
1072 } else { |
1085 // tell the caller the bytecodes are bad |
1073 // tell the caller the bytecodes are bad |
1088 } |
1076 } |
1089 |
1077 |
1090 res = merge_cp_and_rewrite(the_class, scratch_class, THREAD); |
1078 res = merge_cp_and_rewrite(the_class, scratch_class, THREAD); |
1091 if (HAS_PENDING_EXCEPTION) { |
1079 if (HAS_PENDING_EXCEPTION) { |
1092 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1080 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1093 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1081 log_info(redefine, class, load, exceptions)("merge_cp_and_rewrite exception: '%s'", ex_name->as_C_string()); |
1094 RC_TRACE_WITH_THREAD(0x00000002, THREAD, |
|
1095 ("merge_cp_and_rewrite exception: '%s'", ex_name->as_C_string())); |
|
1096 CLEAR_PENDING_EXCEPTION; |
1082 CLEAR_PENDING_EXCEPTION; |
1097 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1083 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1098 return JVMTI_ERROR_OUT_OF_MEMORY; |
1084 return JVMTI_ERROR_OUT_OF_MEMORY; |
1099 } else { |
1085 } else { |
1100 return JVMTI_ERROR_INTERNAL; |
1086 return JVMTI_ERROR_INTERNAL; |
1108 Verifier::verify(scratch_class, Verifier::ThrowException, true, THREAD); |
1094 Verifier::verify(scratch_class, Verifier::ThrowException, true, THREAD); |
1109 } |
1095 } |
1110 |
1096 |
1111 if (HAS_PENDING_EXCEPTION) { |
1097 if (HAS_PENDING_EXCEPTION) { |
1112 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1098 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1113 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1099 log_info(redefine, class, load, exceptions) |
1114 RC_TRACE_WITH_THREAD(0x00000002, THREAD, |
1100 ("verify_byte_codes post merge-CP exception: '%s'", ex_name->as_C_string()); |
1115 ("verify_byte_codes post merge-CP exception: '%s'", |
|
1116 ex_name->as_C_string())); |
|
1117 CLEAR_PENDING_EXCEPTION; |
1101 CLEAR_PENDING_EXCEPTION; |
1118 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1102 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1119 return JVMTI_ERROR_OUT_OF_MEMORY; |
1103 return JVMTI_ERROR_OUT_OF_MEMORY; |
1120 } else { |
1104 } else { |
1121 // tell the caller that constant pool merging screwed up |
1105 // tell the caller that constant pool merging screwed up |
1128 if (!HAS_PENDING_EXCEPTION) { |
1112 if (!HAS_PENDING_EXCEPTION) { |
1129 scratch_class->link_methods(THREAD); |
1113 scratch_class->link_methods(THREAD); |
1130 } |
1114 } |
1131 if (HAS_PENDING_EXCEPTION) { |
1115 if (HAS_PENDING_EXCEPTION) { |
1132 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1116 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1133 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1117 log_info(redefine, class, load, exceptions) |
1134 RC_TRACE_WITH_THREAD(0x00000002, THREAD, |
1118 ("Rewriter::rewrite or link_methods exception: '%s'", ex_name->as_C_string()); |
1135 ("Rewriter::rewrite or link_methods exception: '%s'", ex_name->as_C_string())); |
|
1136 CLEAR_PENDING_EXCEPTION; |
1119 CLEAR_PENDING_EXCEPTION; |
1137 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1120 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { |
1138 return JVMTI_ERROR_OUT_OF_MEMORY; |
1121 return JVMTI_ERROR_OUT_OF_MEMORY; |
1139 } else { |
1122 } else { |
1140 return JVMTI_ERROR_INTERNAL; |
1123 return JVMTI_ERROR_INTERNAL; |
1141 } |
1124 } |
1142 } |
1125 } |
1143 |
1126 |
1144 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1127 log_debug(redefine, class, load) |
1145 RC_TRACE_WITH_THREAD(0x00000001, THREAD, |
1128 ("loaded name=%s (avail_mem=" UINT64_FORMAT "K)", the_class->external_name(), os::available_memory() >> 10); |
1146 ("loaded name=%s (avail_mem=" UINT64_FORMAT "K)", |
|
1147 the_class->external_name(), os::available_memory() >> 10)); |
|
1148 } |
1129 } |
1149 |
1130 |
1150 return JVMTI_ERROR_NONE; |
1131 return JVMTI_ERROR_NONE; |
1151 } |
1132 } |
1152 |
1133 |
1153 |
1134 |
1154 // Map old_index to new_index as needed. scratch_cp is only needed |
1135 // Map old_index to new_index as needed. scratch_cp is only needed |
1155 // for RC_TRACE() calls. |
1136 // for log calls. |
1156 void VM_RedefineClasses::map_index(const constantPoolHandle& scratch_cp, |
1137 void VM_RedefineClasses::map_index(const constantPoolHandle& scratch_cp, |
1157 int old_index, int new_index) { |
1138 int old_index, int new_index) { |
1158 if (find_new_index(old_index) != 0) { |
1139 if (find_new_index(old_index) != 0) { |
1159 // old_index is already mapped |
1140 // old_index is already mapped |
1160 return; |
1141 return; |
1166 } |
1147 } |
1167 |
1148 |
1168 _index_map_p->at_put(old_index, new_index); |
1149 _index_map_p->at_put(old_index, new_index); |
1169 _index_map_count++; |
1150 _index_map_count++; |
1170 |
1151 |
1171 RC_TRACE(0x00040000, ("mapped tag %d at index %d to %d", |
1152 log_trace(redefine, class, constantpool) |
1172 scratch_cp->tag_at(old_index).value(), old_index, new_index)); |
1153 ("mapped tag %d at index %d to %d", scratch_cp->tag_at(old_index).value(), old_index, new_index); |
1173 } // end map_index() |
1154 } // end map_index() |
1174 |
1155 |
1175 |
1156 |
1176 // Map old_index to new_index as needed. |
1157 // Map old_index to new_index as needed. |
1177 void VM_RedefineClasses::map_operand_index(int old_index, int new_index) { |
1158 void VM_RedefineClasses::map_operand_index(int old_index, int new_index) { |
1186 } |
1167 } |
1187 |
1168 |
1188 _operands_index_map_p->at_put(old_index, new_index); |
1169 _operands_index_map_p->at_put(old_index, new_index); |
1189 _operands_index_map_count++; |
1170 _operands_index_map_count++; |
1190 |
1171 |
1191 RC_TRACE(0x00040000, ("mapped bootstrap specifier at index %d to %d", old_index, new_index)); |
1172 log_trace(redefine, class, constantpool)("mapped bootstrap specifier at index %d to %d", old_index, new_index); |
1192 } // end map_index() |
1173 } // end map_index() |
1193 |
1174 |
1194 |
1175 |
1195 // Merge old_cp and scratch_cp and return the results of the merge via |
1176 // Merge old_cp and scratch_cp and return the results of the merge via |
1196 // merge_cp_p. The number of entries in *merge_cp_p is returned via |
1177 // merge_cp_p. The number of entries in *merge_cp_p is returned via |
1217 if ((*merge_cp_p)->length() < old_cp->length()) { |
1198 if ((*merge_cp_p)->length() < old_cp->length()) { |
1218 assert(false, "merge area too small"); |
1199 assert(false, "merge area too small"); |
1219 return false; // robustness |
1200 return false; // robustness |
1220 } |
1201 } |
1221 |
1202 |
1222 RC_TRACE_WITH_THREAD(0x00010000, THREAD, |
1203 log_info(redefine, class, constantpool)("old_cp_len=%d, scratch_cp_len=%d", old_cp->length(), scratch_cp->length()); |
1223 ("old_cp_len=%d, scratch_cp_len=%d", old_cp->length(), |
|
1224 scratch_cp->length())); |
|
1225 |
1204 |
1226 { |
1205 { |
1227 // Pass 0: |
1206 // Pass 0: |
1228 // The old_cp is copied to *merge_cp_p; this means that any code |
1207 // The old_cp is copied to *merge_cp_p; this means that any code |
1229 // using old_cp does not have to change. This work looks like a |
1208 // using old_cp does not have to change. This work looks like a |
1271 (*merge_cp_length_p) = old_i; |
1250 (*merge_cp_length_p) = old_i; |
1272 } |
1251 } |
1273 |
1252 |
1274 // merge_cp_len should be the same as old_cp->length() at this point |
1253 // merge_cp_len should be the same as old_cp->length() at this point |
1275 // so this trace message is really a "warm-and-breathing" message. |
1254 // so this trace message is really a "warm-and-breathing" message. |
1276 RC_TRACE_WITH_THREAD(0x00020000, THREAD, |
1255 log_debug(redefine, class, constantpool)("after pass 0: merge_cp_len=%d", *merge_cp_length_p); |
1277 ("after pass 0: merge_cp_len=%d", *merge_cp_length_p)); |
|
1278 |
1256 |
1279 int scratch_i; // index into scratch_cp |
1257 int scratch_i; // index into scratch_cp |
1280 { |
1258 { |
1281 // Pass 1a: |
1259 // Pass 1a: |
1282 // Compare scratch_cp entries to the old_cp entries that we have |
1260 // Compare scratch_cp entries to the old_cp entries that we have |
1337 append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p, |
1315 append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p, |
1338 CHECK_0); |
1316 CHECK_0); |
1339 } |
1317 } |
1340 } |
1318 } |
1341 |
1319 |
1342 RC_TRACE_WITH_THREAD(0x00020000, THREAD, |
1320 log_debug(redefine, class, constantpool) |
1343 ("after pass 1a: merge_cp_len=%d, scratch_i=%d, index_map_len=%d", |
1321 ("after pass 1a: merge_cp_len=%d, scratch_i=%d, index_map_len=%d", |
1344 *merge_cp_length_p, scratch_i, _index_map_count)); |
1322 *merge_cp_length_p, scratch_i, _index_map_count); |
1345 |
1323 |
1346 if (scratch_i < scratch_cp->length()) { |
1324 if (scratch_i < scratch_cp->length()) { |
1347 // Pass 1b: |
1325 // Pass 1b: |
1348 // old_cp is smaller than scratch_cp so there are entries in |
1326 // old_cp is smaller than scratch_cp so there are entries in |
1349 // scratch_cp that we have not yet processed. We take care of |
1327 // scratch_cp that we have not yet processed. We take care of |
1375 // referenced entries to *merge_cp_p. |
1353 // referenced entries to *merge_cp_p. |
1376 append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p, |
1354 append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p, |
1377 CHECK_0); |
1355 CHECK_0); |
1378 } |
1356 } |
1379 |
1357 |
1380 RC_TRACE_WITH_THREAD(0x00020000, THREAD, |
1358 log_debug(redefine, class, constantpool) |
1381 ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d", |
1359 ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d", |
1382 *merge_cp_length_p, scratch_i, _index_map_count)); |
1360 *merge_cp_length_p, scratch_i, _index_map_count); |
1383 } |
1361 } |
1384 finalize_operands_merge(*merge_cp_p, THREAD); |
1362 finalize_operands_merge(*merge_cp_p, THREAD); |
1385 |
1363 |
1386 return true; |
1364 return true; |
1387 } // end merge_constant_pools() |
1365 } // end merge_constant_pools() |
1466 // The merge can fail due to memory allocation failure or due |
1444 // The merge can fail due to memory allocation failure or due |
1467 // to robustness checks. |
1445 // to robustness checks. |
1468 return JVMTI_ERROR_INTERNAL; |
1446 return JVMTI_ERROR_INTERNAL; |
1469 } |
1447 } |
1470 |
1448 |
1471 RC_TRACE_WITH_THREAD(0x00010000, THREAD, |
1449 log_info(redefine, class, constantpool)("merge_cp_len=%d, index_map_len=%d", merge_cp_length, _index_map_count); |
1472 ("merge_cp_len=%d, index_map_len=%d", merge_cp_length, _index_map_count)); |
|
1473 |
1450 |
1474 if (_index_map_count == 0) { |
1451 if (_index_map_count == 0) { |
1475 // there is nothing to map between the new and merged constant pools |
1452 // there is nothing to map between the new and merged constant pools |
1476 |
1453 |
1477 if (old_cp->length() == scratch_cp->length()) { |
1454 if (old_cp->length() == scratch_cp->length()) { |
1506 // The new constant pool replaces scratch_cp so have cleaner clean it up. |
1483 // The new constant pool replaces scratch_cp so have cleaner clean it up. |
1507 // It can't be cleaned up while there are handles to it. |
1484 // It can't be cleaned up while there are handles to it. |
1508 cp_cleaner.add_scratch_cp(scratch_cp()); |
1485 cp_cleaner.add_scratch_cp(scratch_cp()); |
1509 } |
1486 } |
1510 } else { |
1487 } else { |
1511 if (RC_TRACE_ENABLED(0x00040000)) { |
1488 if (log_is_enabled(Trace, redefine, class, constantpool)) { |
1512 // don't want to loop unless we are tracing |
1489 // don't want to loop unless we are tracing |
1513 int count = 0; |
1490 int count = 0; |
1514 for (int i = 1; i < _index_map_p->length(); i++) { |
1491 for (int i = 1; i < _index_map_p->length(); i++) { |
1515 int value = _index_map_p->at(i); |
1492 int value = _index_map_p->at(i); |
1516 |
1493 |
1517 if (value != -1) { |
1494 if (value != -1) { |
1518 RC_TRACE_WITH_THREAD(0x00040000, THREAD, |
1495 log_trace(redefine, class, constantpool)("index_map[%d]: old=%d new=%d", count, i, value); |
1519 ("index_map[%d]: old=%d new=%d", count, i, value)); |
|
1520 count++; |
1496 count++; |
1521 } |
1497 } |
1522 } |
1498 } |
1523 } |
1499 } |
1524 |
1500 |
1651 // deallocation list. |
1627 // deallocation list. |
1652 methods->at_put(i, new_method()); |
1628 methods->at_put(i, new_method()); |
1653 } |
1629 } |
1654 if (HAS_PENDING_EXCEPTION) { |
1630 if (HAS_PENDING_EXCEPTION) { |
1655 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1631 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
1656 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1632 log_info(redefine, class, load, exceptions)("rewrite_cp_refs_in_method exception: '%s'", ex_name->as_C_string()); |
1657 RC_TRACE_WITH_THREAD(0x00000002, THREAD, |
|
1658 ("rewrite_cp_refs_in_method exception: '%s'", ex_name->as_C_string())); |
|
1659 // Need to clear pending exception here as the super caller sets |
1633 // Need to clear pending exception here as the super caller sets |
1660 // the JVMTI_ERROR_INTERNAL if the returned value is false. |
1634 // the JVMTI_ERROR_INTERNAL if the returned value is false. |
1661 CLEAR_PENDING_EXCEPTION; |
1635 CLEAR_PENDING_EXCEPTION; |
1662 return false; |
1636 return false; |
1663 } |
1637 } |
1713 if (new_index != 0) { |
1687 if (new_index != 0) { |
1714 // the original index is mapped so we have more work to do |
1688 // the original index is mapped so we have more work to do |
1715 if (!StressLdcRewrite && new_index <= max_jubyte) { |
1689 if (!StressLdcRewrite && new_index <= max_jubyte) { |
1716 // The new value can still use ldc instead of ldc_w |
1690 // The new value can still use ldc instead of ldc_w |
1717 // unless we are trying to stress ldc -> ldc_w rewriting |
1691 // unless we are trying to stress ldc -> ldc_w rewriting |
1718 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
1692 log_trace(redefine, class, constantpool) |
1719 ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c), |
1693 ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c), p2i(bcp), cp_index, new_index); |
1720 p2i(bcp), cp_index, new_index)); |
|
1721 *(bcp + 1) = new_index; |
1694 *(bcp + 1) = new_index; |
1722 } else { |
1695 } else { |
1723 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
1696 log_trace(redefine, class, constantpool) |
1724 ("%s->ldc_w@" INTPTR_FORMAT " old=%d, new=%d", |
1697 ("%s->ldc_w@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c), p2i(bcp), cp_index, new_index); |
1725 Bytecodes::name(c), p2i(bcp), cp_index, new_index)); |
|
1726 // the new value needs ldc_w instead of ldc |
1698 // the new value needs ldc_w instead of ldc |
1727 u_char inst_buffer[4]; // max instruction size is 4 bytes |
1699 u_char inst_buffer[4]; // max instruction size is 4 bytes |
1728 bcp = (address)inst_buffer; |
1700 bcp = (address)inst_buffer; |
1729 // construct new instruction sequence |
1701 // construct new instruction sequence |
1730 *bcp = Bytecodes::_ldc_w; |
1702 *bcp = Bytecodes::_ldc_w; |
1779 address p = bcp + 1; |
1751 address p = bcp + 1; |
1780 int cp_index = Bytes::get_Java_u2(p); |
1752 int cp_index = Bytes::get_Java_u2(p); |
1781 int new_index = find_new_index(cp_index); |
1753 int new_index = find_new_index(cp_index); |
1782 if (new_index != 0) { |
1754 if (new_index != 0) { |
1783 // the original index is mapped so update w/ new value |
1755 // the original index is mapped so update w/ new value |
1784 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
1756 log_trace(redefine, class, constantpool) |
1785 ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c), |
1757 ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),p2i(bcp), cp_index, new_index); |
1786 p2i(bcp), cp_index, new_index)); |
|
1787 // Rewriter::rewrite_method() uses put_native_u2() in this |
1758 // Rewriter::rewrite_method() uses put_native_u2() in this |
1788 // situation because it is reusing the constant pool index |
1759 // situation because it is reusing the constant pool index |
1789 // location for a native index into the ConstantPoolCache. |
1760 // location for a native index into the ConstantPoolCache. |
1790 // Since we are updating the constant pool index prior to |
1761 // Since we are updating the constant pool index prior to |
1791 // verification and ConstantPoolCache initialization, we |
1762 // verification and ConstantPoolCache initialization, we |
1821 if (class_annotations == NULL || class_annotations->length() == 0) { |
1792 if (class_annotations == NULL || class_annotations->length() == 0) { |
1822 // no class_annotations so nothing to do |
1793 // no class_annotations so nothing to do |
1823 return true; |
1794 return true; |
1824 } |
1795 } |
1825 |
1796 |
1826 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1797 log_debug(redefine, class, annotation)("class_annotations length=%d", class_annotations->length()); |
1827 ("class_annotations length=%d", class_annotations->length())); |
|
1828 |
1798 |
1829 int byte_i = 0; // byte index into class_annotations |
1799 int byte_i = 0; // byte index into class_annotations |
1830 return rewrite_cp_refs_in_annotations_typeArray(class_annotations, byte_i, |
1800 return rewrite_cp_refs_in_annotations_typeArray(class_annotations, byte_i, |
1831 THREAD); |
1801 THREAD); |
1832 } |
1802 } |
1844 bool VM_RedefineClasses::rewrite_cp_refs_in_annotations_typeArray( |
1814 bool VM_RedefineClasses::rewrite_cp_refs_in_annotations_typeArray( |
1845 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
1815 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
1846 |
1816 |
1847 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
1817 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
1848 // not enough room for num_annotations field |
1818 // not enough room for num_annotations field |
1849 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1819 log_debug(redefine, class, annotation)("length() is too small for num_annotations field"); |
1850 ("length() is too small for num_annotations field")); |
|
1851 return false; |
1820 return false; |
1852 } |
1821 } |
1853 |
1822 |
1854 u2 num_annotations = Bytes::get_Java_u2((address) |
1823 u2 num_annotations = Bytes::get_Java_u2((address) |
1855 annotations_typeArray->adr_at(byte_i_ref)); |
1824 annotations_typeArray->adr_at(byte_i_ref)); |
1856 byte_i_ref += 2; |
1825 byte_i_ref += 2; |
1857 |
1826 |
1858 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1827 log_debug(redefine, class, annotation)("num_annotations=%d", num_annotations); |
1859 ("num_annotations=%d", num_annotations)); |
|
1860 |
1828 |
1861 int calc_num_annotations = 0; |
1829 int calc_num_annotations = 0; |
1862 for (; calc_num_annotations < num_annotations; calc_num_annotations++) { |
1830 for (; calc_num_annotations < num_annotations; calc_num_annotations++) { |
1863 if (!rewrite_cp_refs_in_annotation_struct(annotations_typeArray, |
1831 if (!rewrite_cp_refs_in_annotation_struct(annotations_typeArray, |
1864 byte_i_ref, THREAD)) { |
1832 byte_i_ref, THREAD)) { |
1865 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1833 log_debug(redefine, class, annotation)("bad annotation_struct at %d", calc_num_annotations); |
1866 ("bad annotation_struct at %d", calc_num_annotations)); |
|
1867 // propagate failure back to caller |
1834 // propagate failure back to caller |
1868 return false; |
1835 return false; |
1869 } |
1836 } |
1870 } |
1837 } |
1871 assert(num_annotations == calc_num_annotations, "sanity check"); |
1838 assert(num_annotations == calc_num_annotations, "sanity check"); |
1889 // |
1856 // |
1890 bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct( |
1857 bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct( |
1891 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
1858 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
1892 if ((byte_i_ref + 2 + 2) > annotations_typeArray->length()) { |
1859 if ((byte_i_ref + 2 + 2) > annotations_typeArray->length()) { |
1893 // not enough room for smallest annotation_struct |
1860 // not enough room for smallest annotation_struct |
1894 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1861 log_debug(redefine, class, annotation)("length() is too small for annotation_struct"); |
1895 ("length() is too small for annotation_struct")); |
|
1896 return false; |
1862 return false; |
1897 } |
1863 } |
1898 |
1864 |
1899 u2 type_index = rewrite_cp_ref_in_annotation_data(annotations_typeArray, |
1865 u2 type_index = rewrite_cp_ref_in_annotation_data(annotations_typeArray, |
1900 byte_i_ref, "type_index", THREAD); |
1866 byte_i_ref, "type_index", THREAD); |
1901 |
1867 |
1902 u2 num_element_value_pairs = Bytes::get_Java_u2((address) |
1868 u2 num_element_value_pairs = Bytes::get_Java_u2((address) |
1903 annotations_typeArray->adr_at(byte_i_ref)); |
1869 annotations_typeArray->adr_at(byte_i_ref)); |
1904 byte_i_ref += 2; |
1870 byte_i_ref += 2; |
1905 |
1871 |
1906 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1872 log_debug(redefine, class, annotation) |
1907 ("type_index=%d num_element_value_pairs=%d", type_index, |
1873 ("type_index=%d num_element_value_pairs=%d", type_index, num_element_value_pairs); |
1908 num_element_value_pairs)); |
|
1909 |
1874 |
1910 int calc_num_element_value_pairs = 0; |
1875 int calc_num_element_value_pairs = 0; |
1911 for (; calc_num_element_value_pairs < num_element_value_pairs; |
1876 for (; calc_num_element_value_pairs < num_element_value_pairs; |
1912 calc_num_element_value_pairs++) { |
1877 calc_num_element_value_pairs++) { |
1913 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
1878 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
1914 // not enough room for another element_name_index, let alone |
1879 // not enough room for another element_name_index, let alone |
1915 // the rest of another component |
1880 // the rest of another component |
1916 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1881 log_debug(redefine, class, annotation)("length() is too small for element_name_index"); |
1917 ("length() is too small for element_name_index")); |
|
1918 return false; |
1882 return false; |
1919 } |
1883 } |
1920 |
1884 |
1921 u2 element_name_index = rewrite_cp_ref_in_annotation_data( |
1885 u2 element_name_index = rewrite_cp_ref_in_annotation_data( |
1922 annotations_typeArray, byte_i_ref, |
1886 annotations_typeArray, byte_i_ref, |
1923 "element_name_index", THREAD); |
1887 "element_name_index", THREAD); |
1924 |
1888 |
1925 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1889 log_debug(redefine, class, annotation)("element_name_index=%d", element_name_index); |
1926 ("element_name_index=%d", element_name_index)); |
|
1927 |
1890 |
1928 if (!rewrite_cp_refs_in_element_value(annotations_typeArray, |
1891 if (!rewrite_cp_refs_in_element_value(annotations_typeArray, |
1929 byte_i_ref, THREAD)) { |
1892 byte_i_ref, THREAD)) { |
1930 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1893 log_debug(redefine, class, annotation)("bad element_value at %d", calc_num_element_value_pairs); |
1931 ("bad element_value at %d", calc_num_element_value_pairs)); |
|
1932 // propagate failure back to caller |
1894 // propagate failure back to caller |
1933 return false; |
1895 return false; |
1934 } |
1896 } |
1935 } // end for each component |
1897 } // end for each component |
1936 assert(num_element_value_pairs == calc_num_element_value_pairs, |
1898 assert(num_element_value_pairs == calc_num_element_value_pairs, |
1951 address cp_index_addr = (address) |
1913 address cp_index_addr = (address) |
1952 annotations_typeArray->adr_at(byte_i_ref); |
1914 annotations_typeArray->adr_at(byte_i_ref); |
1953 u2 old_cp_index = Bytes::get_Java_u2(cp_index_addr); |
1915 u2 old_cp_index = Bytes::get_Java_u2(cp_index_addr); |
1954 u2 new_cp_index = find_new_index(old_cp_index); |
1916 u2 new_cp_index = find_new_index(old_cp_index); |
1955 if (new_cp_index != 0) { |
1917 if (new_cp_index != 0) { |
1956 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("mapped old %s=%d", trace_mesg, old_cp_index)); |
1918 log_debug(redefine, class, annotation)("mapped old %s=%d", trace_mesg, old_cp_index); |
1957 Bytes::put_Java_u2(cp_index_addr, new_cp_index); |
1919 Bytes::put_Java_u2(cp_index_addr, new_cp_index); |
1958 old_cp_index = new_cp_index; |
1920 old_cp_index = new_cp_index; |
1959 } |
1921 } |
1960 byte_i_ref += 2; |
1922 byte_i_ref += 2; |
1961 return old_cp_index; |
1923 return old_cp_index; |
1986 bool VM_RedefineClasses::rewrite_cp_refs_in_element_value( |
1948 bool VM_RedefineClasses::rewrite_cp_refs_in_element_value( |
1987 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
1949 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
1988 |
1950 |
1989 if ((byte_i_ref + 1) > annotations_typeArray->length()) { |
1951 if ((byte_i_ref + 1) > annotations_typeArray->length()) { |
1990 // not enough room for a tag let alone the rest of an element_value |
1952 // not enough room for a tag let alone the rest of an element_value |
1991 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1953 log_debug(redefine, class, annotation)("length() is too small for a tag"); |
1992 ("length() is too small for a tag")); |
|
1993 return false; |
1954 return false; |
1994 } |
1955 } |
1995 |
1956 |
1996 u1 tag = annotations_typeArray->at(byte_i_ref); |
1957 u1 tag = annotations_typeArray->at(byte_i_ref); |
1997 byte_i_ref++; |
1958 byte_i_ref++; |
1998 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("tag='%c'", tag)); |
1959 log_debug(redefine, class, annotation)("tag='%c'", tag); |
1999 |
1960 |
2000 switch (tag) { |
1961 switch (tag) { |
2001 // These BaseType tag values are from Table 4.2 in VM spec: |
1962 // These BaseType tag values are from Table 4.2 in VM spec: |
2002 case 'B': // byte |
1963 case 'B': // byte |
2003 case 'C': // char |
1964 case 'C': // char |
2015 // For the above tag values (including the BaseType values), |
1976 // For the above tag values (including the BaseType values), |
2016 // value.const_value_index is right union field. |
1977 // value.const_value_index is right union field. |
2017 |
1978 |
2018 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
1979 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
2019 // not enough room for a const_value_index |
1980 // not enough room for a const_value_index |
2020 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1981 log_debug(redefine, class, annotation)("length() is too small for a const_value_index"); |
2021 ("length() is too small for a const_value_index")); |
|
2022 return false; |
1982 return false; |
2023 } |
1983 } |
2024 |
1984 |
2025 u2 const_value_index = rewrite_cp_ref_in_annotation_data( |
1985 u2 const_value_index = rewrite_cp_ref_in_annotation_data( |
2026 annotations_typeArray, byte_i_ref, |
1986 annotations_typeArray, byte_i_ref, |
2027 "const_value_index", THREAD); |
1987 "const_value_index", THREAD); |
2028 |
1988 |
2029 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1989 log_debug(redefine, class, annotation)("const_value_index=%d", const_value_index); |
2030 ("const_value_index=%d", const_value_index)); |
|
2031 } break; |
1990 } break; |
2032 |
1991 |
2033 case 'e': |
1992 case 'e': |
2034 { |
1993 { |
2035 // for the above tag value, value.enum_const_value is right union field |
1994 // for the above tag value, value.enum_const_value is right union field |
2036 |
1995 |
2037 if ((byte_i_ref + 4) > annotations_typeArray->length()) { |
1996 if ((byte_i_ref + 4) > annotations_typeArray->length()) { |
2038 // not enough room for a enum_const_value |
1997 // not enough room for a enum_const_value |
2039 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
1998 log_debug(redefine, class, annotation)("length() is too small for a enum_const_value"); |
2040 ("length() is too small for a enum_const_value")); |
|
2041 return false; |
1999 return false; |
2042 } |
2000 } |
2043 |
2001 |
2044 u2 type_name_index = rewrite_cp_ref_in_annotation_data( |
2002 u2 type_name_index = rewrite_cp_ref_in_annotation_data( |
2045 annotations_typeArray, byte_i_ref, |
2003 annotations_typeArray, byte_i_ref, |
2047 |
2005 |
2048 u2 const_name_index = rewrite_cp_ref_in_annotation_data( |
2006 u2 const_name_index = rewrite_cp_ref_in_annotation_data( |
2049 annotations_typeArray, byte_i_ref, |
2007 annotations_typeArray, byte_i_ref, |
2050 "const_name_index", THREAD); |
2008 "const_name_index", THREAD); |
2051 |
2009 |
2052 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2010 log_debug(redefine, class, annotation) |
2053 ("type_name_index=%d const_name_index=%d", type_name_index, |
2011 ("type_name_index=%d const_name_index=%d", type_name_index, const_name_index); |
2054 const_name_index)); |
|
2055 } break; |
2012 } break; |
2056 |
2013 |
2057 case 'c': |
2014 case 'c': |
2058 { |
2015 { |
2059 // for the above tag value, value.class_info_index is right union field |
2016 // for the above tag value, value.class_info_index is right union field |
2060 |
2017 |
2061 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
2018 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
2062 // not enough room for a class_info_index |
2019 // not enough room for a class_info_index |
2063 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2020 log_debug(redefine, class, annotation)("length() is too small for a class_info_index"); |
2064 ("length() is too small for a class_info_index")); |
|
2065 return false; |
2021 return false; |
2066 } |
2022 } |
2067 |
2023 |
2068 u2 class_info_index = rewrite_cp_ref_in_annotation_data( |
2024 u2 class_info_index = rewrite_cp_ref_in_annotation_data( |
2069 annotations_typeArray, byte_i_ref, |
2025 annotations_typeArray, byte_i_ref, |
2070 "class_info_index", THREAD); |
2026 "class_info_index", THREAD); |
2071 |
2027 |
2072 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2028 log_debug(redefine, class, annotation)("class_info_index=%d", class_info_index); |
2073 ("class_info_index=%d", class_info_index)); |
|
2074 } break; |
2029 } break; |
2075 |
2030 |
2076 case '@': |
2031 case '@': |
2077 // For the above tag value, value.attr_value is the right union |
2032 // For the above tag value, value.attr_value is the right union |
2078 // field. This is a nested annotation. |
2033 // field. This is a nested annotation. |
2085 |
2040 |
2086 case '[': |
2041 case '[': |
2087 { |
2042 { |
2088 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
2043 if ((byte_i_ref + 2) > annotations_typeArray->length()) { |
2089 // not enough room for a num_values field |
2044 // not enough room for a num_values field |
2090 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2045 log_debug(redefine, class, annotation)("length() is too small for a num_values field"); |
2091 ("length() is too small for a num_values field")); |
|
2092 return false; |
2046 return false; |
2093 } |
2047 } |
2094 |
2048 |
2095 // For the above tag value, value.array_value is the right union |
2049 // For the above tag value, value.array_value is the right union |
2096 // field. This is an array of nested element_value. |
2050 // field. This is an array of nested element_value. |
2097 u2 num_values = Bytes::get_Java_u2((address) |
2051 u2 num_values = Bytes::get_Java_u2((address) |
2098 annotations_typeArray->adr_at(byte_i_ref)); |
2052 annotations_typeArray->adr_at(byte_i_ref)); |
2099 byte_i_ref += 2; |
2053 byte_i_ref += 2; |
2100 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("num_values=%d", num_values)); |
2054 log_debug(redefine, class, annotation)("num_values=%d", num_values); |
2101 |
2055 |
2102 int calc_num_values = 0; |
2056 int calc_num_values = 0; |
2103 for (; calc_num_values < num_values; calc_num_values++) { |
2057 for (; calc_num_values < num_values; calc_num_values++) { |
2104 if (!rewrite_cp_refs_in_element_value( |
2058 if (!rewrite_cp_refs_in_element_value( |
2105 annotations_typeArray, byte_i_ref, THREAD)) { |
2059 annotations_typeArray, byte_i_ref, THREAD)) { |
2106 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2060 log_debug(redefine, class, annotation)("bad nested element_value at %d", calc_num_values); |
2107 ("bad nested element_value at %d", calc_num_values)); |
|
2108 // propagate failure back to caller |
2061 // propagate failure back to caller |
2109 return false; |
2062 return false; |
2110 } |
2063 } |
2111 } |
2064 } |
2112 assert(num_values == calc_num_values, "sanity check"); |
2065 assert(num_values == calc_num_values, "sanity check"); |
2113 } break; |
2066 } break; |
2114 |
2067 |
2115 default: |
2068 default: |
2116 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad tag=0x%x", tag)); |
2069 log_debug(redefine, class, annotation)("bad tag=0x%x", tag); |
2117 return false; |
2070 return false; |
2118 } // end decode tag field |
2071 } // end decode tag field |
2119 |
2072 |
2120 return true; |
2073 return true; |
2121 } // end rewrite_cp_refs_in_element_value() |
2074 } // end rewrite_cp_refs_in_element_value() |
2130 if (fields_annotations == NULL || fields_annotations->length() == 0) { |
2083 if (fields_annotations == NULL || fields_annotations->length() == 0) { |
2131 // no fields_annotations so nothing to do |
2084 // no fields_annotations so nothing to do |
2132 return true; |
2085 return true; |
2133 } |
2086 } |
2134 |
2087 |
2135 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2088 log_debug(redefine, class, annotation)("fields_annotations length=%d", fields_annotations->length()); |
2136 ("fields_annotations length=%d", fields_annotations->length())); |
|
2137 |
2089 |
2138 for (int i = 0; i < fields_annotations->length(); i++) { |
2090 for (int i = 0; i < fields_annotations->length(); i++) { |
2139 AnnotationArray* field_annotations = fields_annotations->at(i); |
2091 AnnotationArray* field_annotations = fields_annotations->at(i); |
2140 if (field_annotations == NULL || field_annotations->length() == 0) { |
2092 if (field_annotations == NULL || field_annotations->length() == 0) { |
2141 // this field does not have any annotations so skip it |
2093 // this field does not have any annotations so skip it |
2143 } |
2095 } |
2144 |
2096 |
2145 int byte_i = 0; // byte index into field_annotations |
2097 int byte_i = 0; // byte index into field_annotations |
2146 if (!rewrite_cp_refs_in_annotations_typeArray(field_annotations, byte_i, |
2098 if (!rewrite_cp_refs_in_annotations_typeArray(field_annotations, byte_i, |
2147 THREAD)) { |
2099 THREAD)) { |
2148 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2100 log_debug(redefine, class, annotation)("bad field_annotations at %d", i); |
2149 ("bad field_annotations at %d", i)); |
|
2150 // propagate failure back to caller |
2101 // propagate failure back to caller |
2151 return false; |
2102 return false; |
2152 } |
2103 } |
2153 } |
2104 } |
2154 |
2105 |
2170 } |
2121 } |
2171 |
2122 |
2172 int byte_i = 0; // byte index into method_annotations |
2123 int byte_i = 0; // byte index into method_annotations |
2173 if (!rewrite_cp_refs_in_annotations_typeArray(method_annotations, byte_i, |
2124 if (!rewrite_cp_refs_in_annotations_typeArray(method_annotations, byte_i, |
2174 THREAD)) { |
2125 THREAD)) { |
2175 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2126 log_debug(redefine, class, annotation)("bad method_annotations at %d", i); |
2176 ("bad method_annotations at %d", i)); |
|
2177 // propagate failure back to caller |
2127 // propagate failure back to caller |
2178 return false; |
2128 return false; |
2179 } |
2129 } |
2180 } |
2130 } |
2181 |
2131 |
2208 continue; |
2158 continue; |
2209 } |
2159 } |
2210 |
2160 |
2211 if (method_parameter_annotations->length() < 1) { |
2161 if (method_parameter_annotations->length() < 1) { |
2212 // not enough room for a num_parameters field |
2162 // not enough room for a num_parameters field |
2213 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2163 log_debug(redefine, class, annotation)("length() is too small for a num_parameters field at %d", i); |
2214 ("length() is too small for a num_parameters field at %d", i)); |
|
2215 return false; |
2164 return false; |
2216 } |
2165 } |
2217 |
2166 |
2218 int byte_i = 0; // byte index into method_parameter_annotations |
2167 int byte_i = 0; // byte index into method_parameter_annotations |
2219 |
2168 |
2220 u1 num_parameters = method_parameter_annotations->at(byte_i); |
2169 u1 num_parameters = method_parameter_annotations->at(byte_i); |
2221 byte_i++; |
2170 byte_i++; |
2222 |
2171 |
2223 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2172 log_debug(redefine, class, annotation)("num_parameters=%d", num_parameters); |
2224 ("num_parameters=%d", num_parameters)); |
|
2225 |
2173 |
2226 int calc_num_parameters = 0; |
2174 int calc_num_parameters = 0; |
2227 for (; calc_num_parameters < num_parameters; calc_num_parameters++) { |
2175 for (; calc_num_parameters < num_parameters; calc_num_parameters++) { |
2228 if (!rewrite_cp_refs_in_annotations_typeArray( |
2176 if (!rewrite_cp_refs_in_annotations_typeArray( |
2229 method_parameter_annotations, byte_i, THREAD)) { |
2177 method_parameter_annotations, byte_i, THREAD)) { |
2230 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2178 log_debug(redefine, class, annotation)("bad method_parameter_annotations at %d", calc_num_parameters); |
2231 ("bad method_parameter_annotations at %d", calc_num_parameters)); |
|
2232 // propagate failure back to caller |
2179 // propagate failure back to caller |
2233 return false; |
2180 return false; |
2234 } |
2181 } |
2235 } |
2182 } |
2236 assert(num_parameters == calc_num_parameters, "sanity check"); |
2183 assert(num_parameters == calc_num_parameters, "sanity check"); |
2262 |
2209 |
2263 int byte_i = 0; // byte index into method_default_annotations |
2210 int byte_i = 0; // byte index into method_default_annotations |
2264 |
2211 |
2265 if (!rewrite_cp_refs_in_element_value( |
2212 if (!rewrite_cp_refs_in_element_value( |
2266 method_default_annotations, byte_i, THREAD)) { |
2213 method_default_annotations, byte_i, THREAD)) { |
2267 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2214 log_debug(redefine, class, annotation)("bad default element_value at %d", i); |
2268 ("bad default element_value at %d", i)); |
|
2269 // propagate failure back to caller |
2215 // propagate failure back to caller |
2270 return false; |
2216 return false; |
2271 } |
2217 } |
2272 } |
2218 } |
2273 |
2219 |
2283 if (class_type_annotations == NULL || class_type_annotations->length() == 0) { |
2229 if (class_type_annotations == NULL || class_type_annotations->length() == 0) { |
2284 // no class_type_annotations so nothing to do |
2230 // no class_type_annotations so nothing to do |
2285 return true; |
2231 return true; |
2286 } |
2232 } |
2287 |
2233 |
2288 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2234 log_debug(redefine, class, annotation)("class_type_annotations length=%d", class_type_annotations->length()); |
2289 ("class_type_annotations length=%d", class_type_annotations->length())); |
|
2290 |
2235 |
2291 int byte_i = 0; // byte index into class_type_annotations |
2236 int byte_i = 0; // byte index into class_type_annotations |
2292 return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations, |
2237 return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations, |
2293 byte_i, "ClassFile", THREAD); |
2238 byte_i, "ClassFile", THREAD); |
2294 } // end rewrite_cp_refs_in_class_type_annotations() |
2239 } // end rewrite_cp_refs_in_class_type_annotations() |
2302 if (fields_type_annotations == NULL || fields_type_annotations->length() == 0) { |
2247 if (fields_type_annotations == NULL || fields_type_annotations->length() == 0) { |
2303 // no fields_type_annotations so nothing to do |
2248 // no fields_type_annotations so nothing to do |
2304 return true; |
2249 return true; |
2305 } |
2250 } |
2306 |
2251 |
2307 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2252 log_debug(redefine, class, annotation)("fields_type_annotations length=%d", fields_type_annotations->length()); |
2308 ("fields_type_annotations length=%d", fields_type_annotations->length())); |
|
2309 |
2253 |
2310 for (int i = 0; i < fields_type_annotations->length(); i++) { |
2254 for (int i = 0; i < fields_type_annotations->length(); i++) { |
2311 AnnotationArray* field_type_annotations = fields_type_annotations->at(i); |
2255 AnnotationArray* field_type_annotations = fields_type_annotations->at(i); |
2312 if (field_type_annotations == NULL || field_type_annotations->length() == 0) { |
2256 if (field_type_annotations == NULL || field_type_annotations->length() == 0) { |
2313 // this field does not have any annotations so skip it |
2257 // this field does not have any annotations so skip it |
2315 } |
2259 } |
2316 |
2260 |
2317 int byte_i = 0; // byte index into field_type_annotations |
2261 int byte_i = 0; // byte index into field_type_annotations |
2318 if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations, |
2262 if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations, |
2319 byte_i, "field_info", THREAD)) { |
2263 byte_i, "field_info", THREAD)) { |
2320 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2264 log_debug(redefine, class, annotation)("bad field_type_annotations at %d", i); |
2321 ("bad field_type_annotations at %d", i)); |
|
2322 // propagate failure back to caller |
2265 // propagate failure back to caller |
2323 return false; |
2266 return false; |
2324 } |
2267 } |
2325 } |
2268 } |
2326 |
2269 |
2339 if (method_type_annotations == NULL || method_type_annotations->length() == 0) { |
2282 if (method_type_annotations == NULL || method_type_annotations->length() == 0) { |
2340 // this method does not have any annotations so skip it |
2283 // this method does not have any annotations so skip it |
2341 continue; |
2284 continue; |
2342 } |
2285 } |
2343 |
2286 |
2344 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2287 log_debug(redefine, class, annotation)("methods type_annotations length=%d", method_type_annotations->length()); |
2345 ("methods type_annotations length=%d", method_type_annotations->length())); |
|
2346 |
2288 |
2347 int byte_i = 0; // byte index into method_type_annotations |
2289 int byte_i = 0; // byte index into method_type_annotations |
2348 if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations, |
2290 if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations, |
2349 byte_i, "method_info", THREAD)) { |
2291 byte_i, "method_info", THREAD)) { |
2350 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2292 log_debug(redefine, class, annotation)("bad method_type_annotations at %d", i); |
2351 ("bad method_type_annotations at %d", i)); |
|
2352 // propagate failure back to caller |
2293 // propagate failure back to caller |
2353 return false; |
2294 return false; |
2354 } |
2295 } |
2355 } |
2296 } |
2356 |
2297 |
2372 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, |
2313 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, |
2373 const char * location_mesg, TRAPS) { |
2314 const char * location_mesg, TRAPS) { |
2374 |
2315 |
2375 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2316 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2376 // not enough room for num_annotations field |
2317 // not enough room for num_annotations field |
2377 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2318 log_debug(redefine, class, annotation)("length() is too small for num_annotations field"); |
2378 ("length() is too small for num_annotations field")); |
|
2379 return false; |
2319 return false; |
2380 } |
2320 } |
2381 |
2321 |
2382 u2 num_annotations = Bytes::get_Java_u2((address) |
2322 u2 num_annotations = Bytes::get_Java_u2((address) |
2383 type_annotations_typeArray->adr_at(byte_i_ref)); |
2323 type_annotations_typeArray->adr_at(byte_i_ref)); |
2384 byte_i_ref += 2; |
2324 byte_i_ref += 2; |
2385 |
2325 |
2386 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2326 log_debug(redefine, class, annotation)("num_type_annotations=%d", num_annotations); |
2387 ("num_type_annotations=%d", num_annotations)); |
|
2388 |
2327 |
2389 int calc_num_annotations = 0; |
2328 int calc_num_annotations = 0; |
2390 for (; calc_num_annotations < num_annotations; calc_num_annotations++) { |
2329 for (; calc_num_annotations < num_annotations; calc_num_annotations++) { |
2391 if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray, |
2330 if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray, |
2392 byte_i_ref, location_mesg, THREAD)) { |
2331 byte_i_ref, location_mesg, THREAD)) { |
2393 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2332 log_debug(redefine, class, annotation)("bad type_annotation_struct at %d", calc_num_annotations); |
2394 ("bad type_annotation_struct at %d", calc_num_annotations)); |
|
2395 // propagate failure back to caller |
2333 // propagate failure back to caller |
2396 return false; |
2334 return false; |
2397 } |
2335 } |
2398 } |
2336 } |
2399 assert(num_annotations == calc_num_annotations, "sanity check"); |
2337 assert(num_annotations == calc_num_annotations, "sanity check"); |
2400 |
2338 |
2401 if (byte_i_ref != type_annotations_typeArray->length()) { |
2339 if (byte_i_ref != type_annotations_typeArray->length()) { |
2402 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2340 log_debug(redefine, class, annotation) |
2403 ("read wrong amount of bytes at end of processing " |
2341 ("read wrong amount of bytes at end of processing type_annotations_typeArray (%d of %d bytes were read)", |
2404 "type_annotations_typeArray (%d of %d bytes were read)", |
2342 byte_i_ref, type_annotations_typeArray->length()); |
2405 byte_i_ref, type_annotations_typeArray->length())); |
|
2406 return false; |
2343 return false; |
2407 } |
2344 } |
2408 |
2345 |
2409 return true; |
2346 return true; |
2410 } // end rewrite_cp_refs_in_type_annotations_typeArray() |
2347 } // end rewrite_cp_refs_in_type_annotations_typeArray() |
2477 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, |
2414 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, |
2478 const char * location_mesg, TRAPS) { |
2415 const char * location_mesg, TRAPS) { |
2479 |
2416 |
2480 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
2417 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
2481 // not enough room for a target_type let alone the rest of a type_annotation |
2418 // not enough room for a target_type let alone the rest of a type_annotation |
2482 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2419 log_debug(redefine, class, annotation)("length() is too small for a target_type"); |
2483 ("length() is too small for a target_type")); |
|
2484 return false; |
2420 return false; |
2485 } |
2421 } |
2486 |
2422 |
2487 u1 target_type = type_annotations_typeArray->at(byte_i_ref); |
2423 u1 target_type = type_annotations_typeArray->at(byte_i_ref); |
2488 byte_i_ref += 1; |
2424 byte_i_ref += 1; |
2489 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("target_type=0x%.2x", target_type)); |
2425 log_debug(redefine, class, annotation)("target_type=0x%.2x", target_type); |
2490 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("location=%s", location_mesg)); |
2426 log_debug(redefine, class, annotation)("location=%s", location_mesg); |
2491 |
2427 |
2492 // Skip over target_info |
2428 // Skip over target_info |
2493 switch (target_type) { |
2429 switch (target_type) { |
2494 case 0x00: |
2430 case 0x00: |
2495 // kind: type parameter declaration of generic class or interface |
2431 // kind: type parameter declaration of generic class or interface |
2503 // type_parameter_target { |
2439 // type_parameter_target { |
2504 // u1 type_parameter_index; |
2440 // u1 type_parameter_index; |
2505 // } |
2441 // } |
2506 // |
2442 // |
2507 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
2443 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
2508 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2444 log_debug(redefine, class, annotation)("length() is too small for a type_parameter_target"); |
2509 ("length() is too small for a type_parameter_target")); |
|
2510 return false; |
2445 return false; |
2511 } |
2446 } |
2512 |
2447 |
2513 u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
2448 u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
2514 byte_i_ref += 1; |
2449 byte_i_ref += 1; |
2515 |
2450 |
2516 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2451 log_debug(redefine, class, annotation)("type_parameter_target: type_parameter_index=%d", type_parameter_index); |
2517 ("type_parameter_target: type_parameter_index=%d", |
|
2518 type_parameter_index)); |
|
2519 } break; |
2452 } break; |
2520 |
2453 |
2521 case 0x10: |
2454 case 0x10: |
2522 // kind: type in extends clause of class or interface declaration |
2455 // kind: type in extends clause of class or interface declaration |
2523 // (including the direct superclass of an anonymous class declaration), |
2456 // (including the direct superclass of an anonymous class declaration), |
2529 // supertype_target { |
2462 // supertype_target { |
2530 // u2 supertype_index; |
2463 // u2 supertype_index; |
2531 // } |
2464 // } |
2532 // |
2465 // |
2533 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2466 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2534 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2467 log_debug(redefine, class, annotation)("length() is too small for a supertype_target"); |
2535 ("length() is too small for a supertype_target")); |
|
2536 return false; |
2468 return false; |
2537 } |
2469 } |
2538 |
2470 |
2539 u2 supertype_index = Bytes::get_Java_u2((address) |
2471 u2 supertype_index = Bytes::get_Java_u2((address) |
2540 type_annotations_typeArray->adr_at(byte_i_ref)); |
2472 type_annotations_typeArray->adr_at(byte_i_ref)); |
2541 byte_i_ref += 2; |
2473 byte_i_ref += 2; |
2542 |
2474 |
2543 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2475 log_debug(redefine, class, annotation)("supertype_target: supertype_index=%d", supertype_index); |
2544 ("supertype_target: supertype_index=%d", supertype_index)); |
|
2545 } break; |
2476 } break; |
2546 |
2477 |
2547 case 0x11: |
2478 case 0x11: |
2548 // kind: type in bound of type parameter declaration of generic class or interface |
2479 // kind: type in bound of type parameter declaration of generic class or interface |
2549 // location: ClassFile |
2480 // location: ClassFile |
2557 // u1 type_parameter_index; |
2488 // u1 type_parameter_index; |
2558 // u1 bound_index; |
2489 // u1 bound_index; |
2559 // } |
2490 // } |
2560 // |
2491 // |
2561 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2492 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2562 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2493 log_debug(redefine, class, annotation)("length() is too small for a type_parameter_bound_target"); |
2563 ("length() is too small for a type_parameter_bound_target")); |
|
2564 return false; |
2494 return false; |
2565 } |
2495 } |
2566 |
2496 |
2567 u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
2497 u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
2568 byte_i_ref += 1; |
2498 byte_i_ref += 1; |
2569 u1 bound_index = type_annotations_typeArray->at(byte_i_ref); |
2499 u1 bound_index = type_annotations_typeArray->at(byte_i_ref); |
2570 byte_i_ref += 1; |
2500 byte_i_ref += 1; |
2571 |
2501 |
2572 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2502 log_debug(redefine, class, annotation) |
2573 ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d", |
2503 ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d", type_parameter_index, bound_index); |
2574 type_parameter_index, bound_index)); |
|
2575 } break; |
2504 } break; |
2576 |
2505 |
2577 case 0x13: |
2506 case 0x13: |
2578 // kind: type in field declaration |
2507 // kind: type in field declaration |
2579 // location: field_info |
2508 // location: field_info |
2587 { |
2516 { |
2588 // struct: |
2517 // struct: |
2589 // empty_target { |
2518 // empty_target { |
2590 // } |
2519 // } |
2591 // |
2520 // |
2592 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2521 log_debug(redefine, class, annotation)("empty_target"); |
2593 ("empty_target")); |
|
2594 } break; |
2522 } break; |
2595 |
2523 |
2596 case 0x16: |
2524 case 0x16: |
2597 // kind: type in formal parameter declaration of method, constructor, or lambda expression |
2525 // kind: type in formal parameter declaration of method, constructor, or lambda expression |
2598 // location: method_info |
2526 // location: method_info |
2602 // formal_parameter_target { |
2530 // formal_parameter_target { |
2603 // u1 formal_parameter_index; |
2531 // u1 formal_parameter_index; |
2604 // } |
2532 // } |
2605 // |
2533 // |
2606 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
2534 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
2607 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2535 log_debug(redefine, class, annotation)("length() is too small for a formal_parameter_target"); |
2608 ("length() is too small for a formal_parameter_target")); |
|
2609 return false; |
2536 return false; |
2610 } |
2537 } |
2611 |
2538 |
2612 u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
2539 u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref); |
2613 byte_i_ref += 1; |
2540 byte_i_ref += 1; |
2614 |
2541 |
2615 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2542 log_debug(redefine, class, annotation) |
2616 ("formal_parameter_target: formal_parameter_index=%d", |
2543 ("formal_parameter_target: formal_parameter_index=%d", formal_parameter_index); |
2617 formal_parameter_index)); |
|
2618 } break; |
2544 } break; |
2619 |
2545 |
2620 case 0x17: |
2546 case 0x17: |
2621 // kind: type in throws clause of method or constructor |
2547 // kind: type in throws clause of method or constructor |
2622 // location: method_info |
2548 // location: method_info |
2626 // throws_target { |
2552 // throws_target { |
2627 // u2 throws_type_index |
2553 // u2 throws_type_index |
2628 // } |
2554 // } |
2629 // |
2555 // |
2630 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2556 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2631 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2557 log_debug(redefine, class, annotation)("length() is too small for a throws_target"); |
2632 ("length() is too small for a throws_target")); |
|
2633 return false; |
2558 return false; |
2634 } |
2559 } |
2635 |
2560 |
2636 u2 throws_type_index = Bytes::get_Java_u2((address) |
2561 u2 throws_type_index = Bytes::get_Java_u2((address) |
2637 type_annotations_typeArray->adr_at(byte_i_ref)); |
2562 type_annotations_typeArray->adr_at(byte_i_ref)); |
2638 byte_i_ref += 2; |
2563 byte_i_ref += 2; |
2639 |
2564 |
2640 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2565 log_debug(redefine, class, annotation)("throws_target: throws_type_index=%d", throws_type_index); |
2641 ("throws_target: throws_type_index=%d", throws_type_index)); |
|
2642 } break; |
2566 } break; |
2643 |
2567 |
2644 case 0x40: |
2568 case 0x40: |
2645 // kind: type in local variable declaration |
2569 // kind: type in local variable declaration |
2646 // location: Code |
2570 // location: Code |
2659 // } table[table_length]; |
2583 // } table[table_length]; |
2660 // } |
2584 // } |
2661 // |
2585 // |
2662 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2586 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2663 // not enough room for a table_length let alone the rest of a localvar_target |
2587 // not enough room for a table_length let alone the rest of a localvar_target |
2664 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2588 log_debug(redefine, class, annotation)("length() is too small for a localvar_target table_length"); |
2665 ("length() is too small for a localvar_target table_length")); |
|
2666 return false; |
2589 return false; |
2667 } |
2590 } |
2668 |
2591 |
2669 u2 table_length = Bytes::get_Java_u2((address) |
2592 u2 table_length = Bytes::get_Java_u2((address) |
2670 type_annotations_typeArray->adr_at(byte_i_ref)); |
2593 type_annotations_typeArray->adr_at(byte_i_ref)); |
2671 byte_i_ref += 2; |
2594 byte_i_ref += 2; |
2672 |
2595 |
2673 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2596 log_debug(redefine, class, annotation)("localvar_target: table_length=%d", table_length); |
2674 ("localvar_target: table_length=%d", table_length)); |
|
2675 |
2597 |
2676 int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry |
2598 int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry |
2677 int table_size = table_length * table_struct_size; |
2599 int table_size = table_length * table_struct_size; |
2678 |
2600 |
2679 if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) { |
2601 if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) { |
2680 // not enough room for a table |
2602 // not enough room for a table |
2681 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2603 log_debug(redefine, class, annotation)("length() is too small for a table array of length %d", table_length); |
2682 ("length() is too small for a table array of length %d", table_length)); |
|
2683 return false; |
2604 return false; |
2684 } |
2605 } |
2685 |
2606 |
2686 // Skip over table |
2607 // Skip over table |
2687 byte_i_ref += table_size; |
2608 byte_i_ref += table_size; |
2696 // catch_target { |
2617 // catch_target { |
2697 // u2 exception_table_index; |
2618 // u2 exception_table_index; |
2698 // } |
2619 // } |
2699 // |
2620 // |
2700 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2621 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2701 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2622 log_debug(redefine, class, annotation)("length() is too small for a catch_target"); |
2702 ("length() is too small for a catch_target")); |
|
2703 return false; |
2623 return false; |
2704 } |
2624 } |
2705 |
2625 |
2706 u2 exception_table_index = Bytes::get_Java_u2((address) |
2626 u2 exception_table_index = Bytes::get_Java_u2((address) |
2707 type_annotations_typeArray->adr_at(byte_i_ref)); |
2627 type_annotations_typeArray->adr_at(byte_i_ref)); |
2708 byte_i_ref += 2; |
2628 byte_i_ref += 2; |
2709 |
2629 |
2710 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2630 log_debug(redefine, class, annotation)("catch_target: exception_table_index=%d", exception_table_index); |
2711 ("catch_target: exception_table_index=%d", exception_table_index)); |
|
2712 } break; |
2631 } break; |
2713 |
2632 |
2714 case 0x43: |
2633 case 0x43: |
2715 // kind: type in instanceof expression |
2634 // kind: type in instanceof expression |
2716 // location: Code |
2635 // location: Code |
2729 // offset_target { |
2648 // offset_target { |
2730 // u2 offset; |
2649 // u2 offset; |
2731 // } |
2650 // } |
2732 // |
2651 // |
2733 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2652 if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { |
2734 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2653 log_debug(redefine, class, annotation)("length() is too small for a offset_target"); |
2735 ("length() is too small for a offset_target")); |
|
2736 return false; |
2654 return false; |
2737 } |
2655 } |
2738 |
2656 |
2739 u2 offset = Bytes::get_Java_u2((address) |
2657 u2 offset = Bytes::get_Java_u2((address) |
2740 type_annotations_typeArray->adr_at(byte_i_ref)); |
2658 type_annotations_typeArray->adr_at(byte_i_ref)); |
2741 byte_i_ref += 2; |
2659 byte_i_ref += 2; |
2742 |
2660 |
2743 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2661 log_debug(redefine, class, annotation)("offset_target: offset=%d", offset); |
2744 ("offset_target: offset=%d", offset)); |
|
2745 } break; |
2662 } break; |
2746 |
2663 |
2747 case 0x47: |
2664 case 0x47: |
2748 // kind: type in cast expression |
2665 // kind: type in cast expression |
2749 // location: Code |
2666 // location: Code |
2767 // u2 offset; |
2684 // u2 offset; |
2768 // u1 type_argument_index; |
2685 // u1 type_argument_index; |
2769 // } |
2686 // } |
2770 // |
2687 // |
2771 if ((byte_i_ref + 3) > type_annotations_typeArray->length()) { |
2688 if ((byte_i_ref + 3) > type_annotations_typeArray->length()) { |
2772 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2689 log_debug(redefine, class, annotation)("length() is too small for a type_argument_target"); |
2773 ("length() is too small for a type_argument_target")); |
|
2774 return false; |
2690 return false; |
2775 } |
2691 } |
2776 |
2692 |
2777 u2 offset = Bytes::get_Java_u2((address) |
2693 u2 offset = Bytes::get_Java_u2((address) |
2778 type_annotations_typeArray->adr_at(byte_i_ref)); |
2694 type_annotations_typeArray->adr_at(byte_i_ref)); |
2779 byte_i_ref += 2; |
2695 byte_i_ref += 2; |
2780 u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); |
2696 u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); |
2781 byte_i_ref += 1; |
2697 byte_i_ref += 1; |
2782 |
2698 |
2783 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2699 log_debug(redefine, class, annotation) |
2784 ("type_argument_target: offset=%d, type_argument_index=%d", |
2700 ("type_argument_target: offset=%d, type_argument_index=%d", offset, type_argument_index); |
2785 offset, type_argument_index)); |
|
2786 } break; |
2701 } break; |
2787 |
2702 |
2788 default: |
2703 default: |
2789 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2704 log_debug(redefine, class, annotation)("unknown target_type"); |
2790 ("unknown target_type")); |
|
2791 #ifdef ASSERT |
2705 #ifdef ASSERT |
2792 ShouldNotReachHere(); |
2706 ShouldNotReachHere(); |
2793 #endif |
2707 #endif |
2794 return false; |
2708 return false; |
2795 } |
2709 } |
2812 bool VM_RedefineClasses::skip_type_annotation_type_path( |
2726 bool VM_RedefineClasses::skip_type_annotation_type_path( |
2813 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS) { |
2727 AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS) { |
2814 |
2728 |
2815 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
2729 if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { |
2816 // not enough room for a path_length let alone the rest of the type_path |
2730 // not enough room for a path_length let alone the rest of the type_path |
2817 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2731 log_debug(redefine, class, annotation)("length() is too small for a type_path"); |
2818 ("length() is too small for a type_path")); |
|
2819 return false; |
2732 return false; |
2820 } |
2733 } |
2821 |
2734 |
2822 u1 path_length = type_annotations_typeArray->at(byte_i_ref); |
2735 u1 path_length = type_annotations_typeArray->at(byte_i_ref); |
2823 byte_i_ref += 1; |
2736 byte_i_ref += 1; |
2824 |
2737 |
2825 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2738 log_debug(redefine, class, annotation)("type_path: path_length=%d", path_length); |
2826 ("type_path: path_length=%d", path_length)); |
|
2827 |
2739 |
2828 int calc_path_length = 0; |
2740 int calc_path_length = 0; |
2829 for (; calc_path_length < path_length; calc_path_length++) { |
2741 for (; calc_path_length < path_length; calc_path_length++) { |
2830 if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) { |
2742 if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) { |
2831 // not enough room for a path |
2743 // not enough room for a path |
2832 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2744 log_debug(redefine, class, annotation) |
2833 ("length() is too small for path entry %d of %d", |
2745 ("length() is too small for path entry %d of %d", calc_path_length, path_length); |
2834 calc_path_length, path_length)); |
|
2835 return false; |
2746 return false; |
2836 } |
2747 } |
2837 |
2748 |
2838 u1 type_path_kind = type_annotations_typeArray->at(byte_i_ref); |
2749 u1 type_path_kind = type_annotations_typeArray->at(byte_i_ref); |
2839 byte_i_ref += 1; |
2750 byte_i_ref += 1; |
2840 u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); |
2751 u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); |
2841 byte_i_ref += 1; |
2752 byte_i_ref += 1; |
2842 |
2753 |
2843 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2754 log_debug(redefine, class, annotation) |
2844 ("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d", |
2755 ("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d", |
2845 calc_path_length, type_path_kind, type_argument_index)); |
2756 calc_path_length, type_path_kind, type_argument_index); |
2846 |
2757 |
2847 if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) { |
2758 if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) { |
2848 // not enough room for a path |
2759 // not enough room for a path |
2849 RC_TRACE_WITH_THREAD(0x02000000, THREAD, |
2760 log_debug(redefine, class, annotation)("inconsistent type_path values"); |
2850 ("inconsistent type_path values")); |
|
2851 return false; |
2761 return false; |
2852 } |
2762 } |
2853 } |
2763 } |
2854 assert(path_length == calc_path_length, "sanity check"); |
2764 assert(path_length == calc_path_length, "sanity check"); |
2855 |
2765 |
2881 |
2791 |
2882 assert(stackmap_p + 2 <= stackmap_end, "no room for number_of_entries"); |
2792 assert(stackmap_p + 2 <= stackmap_end, "no room for number_of_entries"); |
2883 u2 number_of_entries = Bytes::get_Java_u2(stackmap_p); |
2793 u2 number_of_entries = Bytes::get_Java_u2(stackmap_p); |
2884 stackmap_p += 2; |
2794 stackmap_p += 2; |
2885 |
2795 |
2886 RC_TRACE_WITH_THREAD(0x04000000, THREAD, |
2796 log_debug(redefine, class, stackmap)("number_of_entries=%u", number_of_entries); |
2887 ("number_of_entries=%u", number_of_entries)); |
|
2888 |
2797 |
2889 // walk through each stack_map_frame |
2798 // walk through each stack_map_frame |
2890 u2 calc_number_of_entries = 0; |
2799 u2 calc_number_of_entries = 0; |
2891 for (; calc_number_of_entries < number_of_entries; calc_number_of_entries++) { |
2800 for (; calc_number_of_entries < number_of_entries; calc_number_of_entries++) { |
2892 // The stack_map_frame structure is a u1 frame_type followed by |
2801 // The stack_map_frame structure is a u1 frame_type followed by |
3082 { |
2991 { |
3083 assert(stackmap_p_ref + 2 <= stackmap_end, "no room for cpool_index"); |
2992 assert(stackmap_p_ref + 2 <= stackmap_end, "no room for cpool_index"); |
3084 u2 cpool_index = Bytes::get_Java_u2(stackmap_p_ref); |
2993 u2 cpool_index = Bytes::get_Java_u2(stackmap_p_ref); |
3085 u2 new_cp_index = find_new_index(cpool_index); |
2994 u2 new_cp_index = find_new_index(cpool_index); |
3086 if (new_cp_index != 0) { |
2995 if (new_cp_index != 0) { |
3087 RC_TRACE_WITH_THREAD(0x04000000, THREAD, |
2996 log_debug(redefine, class, stackmap)("mapped old cpool_index=%d", cpool_index); |
3088 ("mapped old cpool_index=%d", cpool_index)); |
|
3089 Bytes::put_Java_u2(stackmap_p_ref, new_cp_index); |
2997 Bytes::put_Java_u2(stackmap_p_ref, new_cp_index); |
3090 cpool_index = new_cp_index; |
2998 cpool_index = new_cp_index; |
3091 } |
2999 } |
3092 stackmap_p_ref += 2; |
3000 stackmap_p_ref += 2; |
3093 |
3001 |
3094 RC_TRACE_WITH_THREAD(0x04000000, THREAD, |
3002 log_debug(redefine, class, stackmap) |
3095 ("frame_i=%u, frame_type=%u, cpool_index=%d", frame_i, |
3003 ("frame_i=%u, frame_type=%u, cpool_index=%d", frame_i, frame_type, cpool_index); |
3096 frame_type, cpool_index)); |
|
3097 } break; |
3004 } break; |
3098 |
3005 |
3099 // Uninitialized_variable_info { |
3006 // Uninitialized_variable_info { |
3100 // u1 tag = ITEM_Uninitialized; /* 8 */ |
3007 // u1 tag = ITEM_Uninitialized; /* 8 */ |
3101 // u2 offset; |
3008 // u2 offset; |
3104 assert(stackmap_p_ref + 2 <= stackmap_end, "no room for offset"); |
3011 assert(stackmap_p_ref + 2 <= stackmap_end, "no room for offset"); |
3105 stackmap_p_ref += 2; |
3012 stackmap_p_ref += 2; |
3106 break; |
3013 break; |
3107 |
3014 |
3108 default: |
3015 default: |
3109 RC_TRACE_WITH_THREAD(0x04000000, THREAD, |
3016 log_debug(redefine, class, stackmap)("frame_i=%u, frame_type=%u, bad tag=0x%x", frame_i, frame_type, tag); |
3110 ("frame_i=%u, frame_type=%u, bad tag=0x%x", frame_i, frame_type, tag)); |
|
3111 ShouldNotReachHere(); |
3017 ShouldNotReachHere(); |
3112 break; |
3018 break; |
3113 } // end switch (tag) |
3019 } // end switch (tag) |
3114 } // end rewrite_cp_refs_in_verification_type_info() |
3020 } // end rewrite_cp_refs_in_verification_type_info() |
3115 |
3021 |
3155 // update each field in klass to use new constant pool indices as needed |
3061 // update each field in klass to use new constant pool indices as needed |
3156 for (JavaFieldStream fs(scratch_class); !fs.done(); fs.next()) { |
3062 for (JavaFieldStream fs(scratch_class); !fs.done(); fs.next()) { |
3157 jshort cur_index = fs.name_index(); |
3063 jshort cur_index = fs.name_index(); |
3158 jshort new_index = find_new_index(cur_index); |
3064 jshort new_index = find_new_index(cur_index); |
3159 if (new_index != 0) { |
3065 if (new_index != 0) { |
3160 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3066 log_trace(redefine, class, constantpool)("field-name_index change: %d to %d", cur_index, new_index); |
3161 ("field-name_index change: %d to %d", cur_index, new_index)); |
|
3162 fs.set_name_index(new_index); |
3067 fs.set_name_index(new_index); |
3163 } |
3068 } |
3164 cur_index = fs.signature_index(); |
3069 cur_index = fs.signature_index(); |
3165 new_index = find_new_index(cur_index); |
3070 new_index = find_new_index(cur_index); |
3166 if (new_index != 0) { |
3071 if (new_index != 0) { |
3167 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3072 log_trace(redefine, class, constantpool)("field-signature_index change: %d to %d", cur_index, new_index); |
3168 ("field-signature_index change: %d to %d", cur_index, new_index)); |
|
3169 fs.set_signature_index(new_index); |
3073 fs.set_signature_index(new_index); |
3170 } |
3074 } |
3171 cur_index = fs.initval_index(); |
3075 cur_index = fs.initval_index(); |
3172 new_index = find_new_index(cur_index); |
3076 new_index = find_new_index(cur_index); |
3173 if (new_index != 0) { |
3077 if (new_index != 0) { |
3174 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3078 log_trace(redefine, class, constantpool)("field-initval_index change: %d to %d", cur_index, new_index); |
3175 ("field-initval_index change: %d to %d", cur_index, new_index)); |
|
3176 fs.set_initval_index(new_index); |
3079 fs.set_initval_index(new_index); |
3177 } |
3080 } |
3178 cur_index = fs.generic_signature_index(); |
3081 cur_index = fs.generic_signature_index(); |
3179 new_index = find_new_index(cur_index); |
3082 new_index = find_new_index(cur_index); |
3180 if (new_index != 0) { |
3083 if (new_index != 0) { |
3181 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3084 log_trace(redefine, class, constantpool)("field-generic_signature change: %d to %d", cur_index, new_index); |
3182 ("field-generic_signature change: %d to %d", cur_index, new_index)); |
|
3183 fs.set_generic_signature_index(new_index); |
3085 fs.set_generic_signature_index(new_index); |
3184 } |
3086 } |
3185 } // end for each field |
3087 } // end for each field |
3186 |
3088 |
3187 // Update constant pool indices in the inner classes info to use |
3089 // Update constant pool indices in the inner classes info to use |
3194 if (cur_index == 0) { |
3096 if (cur_index == 0) { |
3195 continue; // JVM spec. allows null inner class refs so skip it |
3097 continue; // JVM spec. allows null inner class refs so skip it |
3196 } |
3098 } |
3197 int new_index = find_new_index(cur_index); |
3099 int new_index = find_new_index(cur_index); |
3198 if (new_index != 0) { |
3100 if (new_index != 0) { |
3199 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3101 log_trace(redefine, class, constantpool)("inner_class_info change: %d to %d", cur_index, new_index); |
3200 ("inner_class_info change: %d to %d", cur_index, new_index)); |
|
3201 iter.set_inner_class_info_index(new_index); |
3102 iter.set_inner_class_info_index(new_index); |
3202 } |
3103 } |
3203 cur_index = iter.outer_class_info_index(); |
3104 cur_index = iter.outer_class_info_index(); |
3204 new_index = find_new_index(cur_index); |
3105 new_index = find_new_index(cur_index); |
3205 if (new_index != 0) { |
3106 if (new_index != 0) { |
3206 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3107 log_trace(redefine, class, constantpool)("outer_class_info change: %d to %d", cur_index, new_index); |
3207 ("outer_class_info change: %d to %d", cur_index, new_index)); |
|
3208 iter.set_outer_class_info_index(new_index); |
3108 iter.set_outer_class_info_index(new_index); |
3209 } |
3109 } |
3210 cur_index = iter.inner_name_index(); |
3110 cur_index = iter.inner_name_index(); |
3211 new_index = find_new_index(cur_index); |
3111 new_index = find_new_index(cur_index); |
3212 if (new_index != 0) { |
3112 if (new_index != 0) { |
3213 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3113 log_trace(redefine, class, constantpool)("inner_name change: %d to %d", cur_index, new_index); |
3214 ("inner_name change: %d to %d", cur_index, new_index)); |
|
3215 iter.set_inner_name_index(new_index); |
3114 iter.set_inner_name_index(new_index); |
3216 } |
3115 } |
3217 } // end for each inner class |
3116 } // end for each inner class |
3218 |
3117 |
3219 // Attach each method in klass to the new constant pool and update |
3118 // Attach each method in klass to the new constant pool and update |
3223 methodHandle method(THREAD, methods->at(i)); |
3122 methodHandle method(THREAD, methods->at(i)); |
3224 method->set_constants(scratch_cp()); |
3123 method->set_constants(scratch_cp()); |
3225 |
3124 |
3226 int new_index = find_new_index(method->name_index()); |
3125 int new_index = find_new_index(method->name_index()); |
3227 if (new_index != 0) { |
3126 if (new_index != 0) { |
3228 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3127 log_trace(redefine, class, constantpool) |
3229 ("method-name_index change: %d to %d", method->name_index(), |
3128 ("method-name_index change: %d to %d", method->name_index(), new_index); |
3230 new_index)); |
|
3231 method->set_name_index(new_index); |
3129 method->set_name_index(new_index); |
3232 } |
3130 } |
3233 new_index = find_new_index(method->signature_index()); |
3131 new_index = find_new_index(method->signature_index()); |
3234 if (new_index != 0) { |
3132 if (new_index != 0) { |
3235 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3133 log_trace(redefine, class, constantpool) |
3236 ("method-signature_index change: %d to %d", |
3134 ("method-signature_index change: %d to %d", method->signature_index(), new_index); |
3237 method->signature_index(), new_index)); |
|
3238 method->set_signature_index(new_index); |
3135 method->set_signature_index(new_index); |
3239 } |
3136 } |
3240 new_index = find_new_index(method->generic_signature_index()); |
3137 new_index = find_new_index(method->generic_signature_index()); |
3241 if (new_index != 0) { |
3138 if (new_index != 0) { |
3242 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3139 log_trace(redefine, class, constantpool) |
3243 ("method-generic_signature_index change: %d to %d", |
3140 ("method-generic_signature_index change: %d to %d", method->generic_signature_index(), new_index); |
3244 method->generic_signature_index(), new_index)); |
|
3245 method->set_generic_signature_index(new_index); |
3141 method->set_generic_signature_index(new_index); |
3246 } |
3142 } |
3247 |
3143 |
3248 // Update constant pool indices in the method's checked exception |
3144 // Update constant pool indices in the method's checked exception |
3249 // table to use new constant indices as needed. |
3145 // table to use new constant indices as needed. |
3253 method->checked_exceptions_start(); |
3149 method->checked_exceptions_start(); |
3254 for (int j = 0; j < cext_length; j++) { |
3150 for (int j = 0; j < cext_length; j++) { |
3255 int cur_index = cext_table[j].class_cp_index; |
3151 int cur_index = cext_table[j].class_cp_index; |
3256 int new_index = find_new_index(cur_index); |
3152 int new_index = find_new_index(cur_index); |
3257 if (new_index != 0) { |
3153 if (new_index != 0) { |
3258 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3154 log_trace(redefine, class, constantpool)("cext-class_cp_index change: %d to %d", cur_index, new_index); |
3259 ("cext-class_cp_index change: %d to %d", cur_index, new_index)); |
|
3260 cext_table[j].class_cp_index = (u2)new_index; |
3155 cext_table[j].class_cp_index = (u2)new_index; |
3261 } |
3156 } |
3262 } // end for each checked exception table entry |
3157 } // end for each checked exception table entry |
3263 } // end if there are checked exception table entries |
3158 } // end if there are checked exception table entries |
3264 |
3159 |
3272 |
3167 |
3273 for (int j = 0; j < ext_length; j ++) { |
3168 for (int j = 0; j < ext_length; j ++) { |
3274 int cur_index = ex_table.catch_type_index(j); |
3169 int cur_index = ex_table.catch_type_index(j); |
3275 int new_index = find_new_index(cur_index); |
3170 int new_index = find_new_index(cur_index); |
3276 if (new_index != 0) { |
3171 if (new_index != 0) { |
3277 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3172 log_trace(redefine, class, constantpool)("ext-klass_index change: %d to %d", cur_index, new_index); |
3278 ("ext-klass_index change: %d to %d", cur_index, new_index)); |
|
3279 ex_table.set_catch_type_index(j, new_index); |
3173 ex_table.set_catch_type_index(j, new_index); |
3280 } |
3174 } |
3281 } // end for each exception table entry |
3175 } // end for each exception table entry |
3282 |
3176 |
3283 // Update constant pool indices in the method's local variable |
3177 // Update constant pool indices in the method's local variable |
3290 method->localvariable_table_start(); |
3184 method->localvariable_table_start(); |
3291 for (int j = 0; j < lvt_length; j++) { |
3185 for (int j = 0; j < lvt_length; j++) { |
3292 int cur_index = lv_table[j].name_cp_index; |
3186 int cur_index = lv_table[j].name_cp_index; |
3293 int new_index = find_new_index(cur_index); |
3187 int new_index = find_new_index(cur_index); |
3294 if (new_index != 0) { |
3188 if (new_index != 0) { |
3295 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3189 log_trace(redefine, class, constantpool)("lvt-name_cp_index change: %d to %d", cur_index, new_index); |
3296 ("lvt-name_cp_index change: %d to %d", cur_index, new_index)); |
|
3297 lv_table[j].name_cp_index = (u2)new_index; |
3190 lv_table[j].name_cp_index = (u2)new_index; |
3298 } |
3191 } |
3299 cur_index = lv_table[j].descriptor_cp_index; |
3192 cur_index = lv_table[j].descriptor_cp_index; |
3300 new_index = find_new_index(cur_index); |
3193 new_index = find_new_index(cur_index); |
3301 if (new_index != 0) { |
3194 if (new_index != 0) { |
3302 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3195 log_trace(redefine, class, constantpool)("lvt-descriptor_cp_index change: %d to %d", cur_index, new_index); |
3303 ("lvt-descriptor_cp_index change: %d to %d", cur_index, |
|
3304 new_index)); |
|
3305 lv_table[j].descriptor_cp_index = (u2)new_index; |
3196 lv_table[j].descriptor_cp_index = (u2)new_index; |
3306 } |
3197 } |
3307 cur_index = lv_table[j].signature_cp_index; |
3198 cur_index = lv_table[j].signature_cp_index; |
3308 new_index = find_new_index(cur_index); |
3199 new_index = find_new_index(cur_index); |
3309 if (new_index != 0) { |
3200 if (new_index != 0) { |
3310 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
3201 log_trace(redefine, class, constantpool)("lvt-signature_cp_index change: %d to %d", cur_index, new_index); |
3311 ("lvt-signature_cp_index change: %d to %d", cur_index, new_index)); |
|
3312 lv_table[j].signature_cp_index = (u2)new_index; |
3202 lv_table[j].signature_cp_index = (u2)new_index; |
3313 } |
3203 } |
3314 } // end for each local variable table entry |
3204 } // end for each local variable table entry |
3315 } // end if there are local variable table entries |
3205 } // end if there are local variable table entries |
3316 |
3206 |
3329 |
3219 |
3330 // This is a very busy routine. We don't want too much tracing |
3220 // This is a very busy routine. We don't want too much tracing |
3331 // printed out. |
3221 // printed out. |
3332 bool trace_name_printed = false; |
3222 bool trace_name_printed = false; |
3333 InstanceKlass *the_class = InstanceKlass::cast(_the_class_oop); |
3223 InstanceKlass *the_class = InstanceKlass::cast(_the_class_oop); |
3334 |
|
3335 // Very noisy: only enable this call if you are trying to determine |
|
3336 // that a specific class gets found by this routine. |
|
3337 // RC_TRACE macro has an embedded ResourceMark |
|
3338 // RC_TRACE_WITH_THREAD(0x00100000, THREAD, |
|
3339 // ("adjust check: name=%s", k->external_name())); |
|
3340 // trace_name_printed = true; |
|
3341 |
3224 |
3342 // If the class being redefined is java.lang.Object, we need to fix all |
3225 // If the class being redefined is java.lang.Object, we need to fix all |
3343 // array class vtables also |
3226 // array class vtables also |
3344 if (k->is_array_klass() && _the_class_oop == SystemDictionary::Object_klass()) { |
3227 if (k->is_array_klass() && _the_class_oop == SystemDictionary::Object_klass()) { |
3345 k->vtable()->adjust_method_entries(the_class, &trace_name_printed); |
3228 k->vtable()->adjust_method_entries(the_class, &trace_name_printed); |
3574 } |
3457 } |
3575 |
3458 |
3576 // With tracing we try not to "yack" too much. The position of |
3459 // With tracing we try not to "yack" too much. The position of |
3577 // this trace assumes there are fewer obsolete methods than |
3460 // this trace assumes there are fewer obsolete methods than |
3578 // EMCP methods. |
3461 // EMCP methods. |
3579 RC_TRACE(0x00000100, ("mark %s(%s) as obsolete", |
3462 if (log_is_enabled(Trace, redefine, class, obsolete, mark)) { |
3580 old_method->name()->as_C_string(), |
3463 ResourceMark rm; |
3581 old_method->signature()->as_C_string())); |
3464 log_trace(redefine, class, obsolete, mark) |
3465 ("mark %s(%s) as obsolete", old_method->name()->as_C_string(), old_method->signature()->as_C_string()); |
|
3466 } |
|
3582 } |
3467 } |
3583 old_method->set_is_old(); |
3468 old_method->set_is_old(); |
3584 } |
3469 } |
3585 for (int i = 0; i < _deleted_methods_length; ++i) { |
3470 for (int i = 0; i < _deleted_methods_length; ++i) { |
3586 Method* old_method = _deleted_methods[i]; |
3471 Method* old_method = _deleted_methods[i]; |
3594 old_method->set_is_obsolete(); |
3479 old_method->set_is_obsolete(); |
3595 ++obsolete_count; |
3480 ++obsolete_count; |
3596 // With tracing we try not to "yack" too much. The position of |
3481 // With tracing we try not to "yack" too much. The position of |
3597 // this trace assumes there are fewer obsolete methods than |
3482 // this trace assumes there are fewer obsolete methods than |
3598 // EMCP methods. |
3483 // EMCP methods. |
3599 RC_TRACE(0x00000100, ("mark deleted %s(%s) as obsolete", |
3484 if (log_is_enabled(Trace, redefine, class, obsolete, mark)) { |
3600 old_method->name()->as_C_string(), |
3485 ResourceMark rm; |
3601 old_method->signature()->as_C_string())); |
3486 log_trace(redefine, class, obsolete, mark) |
3487 ("mark deleted %s(%s) as obsolete", old_method->name()->as_C_string(), old_method->signature()->as_C_string()); |
|
3488 } |
|
3602 } |
3489 } |
3603 assert((emcp_method_count + obsolete_count) == _old_methods->length(), |
3490 assert((emcp_method_count + obsolete_count) == _old_methods->length(), |
3604 "sanity check"); |
3491 "sanity check"); |
3605 RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", emcp_method_count, |
3492 log_trace(redefine, class, obsolete, mark)("EMCP_cnt=%d, obsolete_cnt=%d", emcp_method_count, obsolete_count); |
3606 obsolete_count)); |
|
3607 return emcp_method_count; |
3493 return emcp_method_count; |
3608 } |
3494 } |
3609 |
3495 |
3610 // This internal class transfers the native function registration from old methods |
3496 // This internal class transfers the native function registration from old methods |
3611 // to new methods. It is designed to handle both the simple case of unchanged |
3497 // to new methods. It is designed to handle both the simple case of unchanged |
3864 // static global fields in the VM operation. |
3750 // static global fields in the VM operation. |
3865 void VM_RedefineClasses::redefine_single_class(jclass the_jclass, |
3751 void VM_RedefineClasses::redefine_single_class(jclass the_jclass, |
3866 Klass* scratch_class_oop, TRAPS) { |
3752 Klass* scratch_class_oop, TRAPS) { |
3867 |
3753 |
3868 HandleMark hm(THREAD); // make sure handles from this call are freed |
3754 HandleMark hm(THREAD); // make sure handles from this call are freed |
3869 RC_TIMER_START(_timer_rsc_phase1); |
3755 |
3756 if (log_is_enabled(Info, redefine, class, timer)) { |
|
3757 _timer_rsc_phase1.start(); |
|
3758 } |
|
3870 |
3759 |
3871 instanceKlassHandle scratch_class(scratch_class_oop); |
3760 instanceKlassHandle scratch_class(scratch_class_oop); |
3872 |
3761 |
3873 oop the_class_mirror = JNIHandles::resolve_non_null(the_jclass); |
3762 oop the_class_mirror = JNIHandles::resolve_non_null(the_jclass); |
3874 Klass* the_class_oop = java_lang_Class::as_Klass(the_class_mirror); |
3763 Klass* the_class_oop = java_lang_Class::as_Klass(the_class_mirror); |
4081 the_class->set_has_been_redefined(); |
3970 the_class->set_has_been_redefined(); |
4082 |
3971 |
4083 // keep track of previous versions of this class |
3972 // keep track of previous versions of this class |
4084 the_class->add_previous_version(scratch_class, emcp_method_count); |
3973 the_class->add_previous_version(scratch_class, emcp_method_count); |
4085 |
3974 |
4086 RC_TIMER_STOP(_timer_rsc_phase1); |
3975 _timer_rsc_phase1.stop(); |
4087 RC_TIMER_START(_timer_rsc_phase2); |
3976 if (log_is_enabled(Info, redefine, class, timer)) { |
3977 _timer_rsc_phase2.start(); |
|
3978 } |
|
4088 |
3979 |
4089 // Adjust constantpool caches and vtables for all classes |
3980 // Adjust constantpool caches and vtables for all classes |
4090 // that reference methods of the evolved class. |
3981 // that reference methods of the evolved class. |
4091 AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD); |
3982 AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD); |
4092 ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable); |
3983 ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable); |
4102 // Flush references to any obsolete methods from the oop map cache |
3993 // Flush references to any obsolete methods from the oop map cache |
4103 // so that obsolete methods are not pinned. |
3994 // so that obsolete methods are not pinned. |
4104 the_class->oop_map_cache()->flush_obsolete_entries(); |
3995 the_class->oop_map_cache()->flush_obsolete_entries(); |
4105 } |
3996 } |
4106 |
3997 |
4107 // increment the classRedefinedCount field in the_class and in any |
|
4108 // direct and indirect subclasses of the_class |
|
4109 increment_class_counter((InstanceKlass *)the_class(), THREAD); |
|
4110 |
|
4111 // RC_TRACE macro has an embedded ResourceMark |
|
4112 RC_TRACE_WITH_THREAD(0x00000001, THREAD, |
|
4113 ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)", |
|
4114 the_class->external_name(), |
|
4115 java_lang_Class::classRedefinedCount(the_class_mirror), |
|
4116 os::available_memory() >> 10)); |
|
4117 |
|
4118 { |
3998 { |
4119 ResourceMark rm(THREAD); |
3999 ResourceMark rm(THREAD); |
4000 // increment the classRedefinedCount field in the_class and in any |
|
4001 // direct and indirect subclasses of the_class |
|
4002 increment_class_counter((InstanceKlass *)the_class(), THREAD); |
|
4003 log_info(redefine, class, load) |
|
4004 ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)", |
|
4005 the_class->external_name(), java_lang_Class::classRedefinedCount(the_class_mirror), os::available_memory() >> 10); |
|
4120 Events::log_redefinition(THREAD, "redefined class name=%s, count=%d", |
4006 Events::log_redefinition(THREAD, "redefined class name=%s, count=%d", |
4121 the_class->external_name(), |
4007 the_class->external_name(), |
4122 java_lang_Class::classRedefinedCount(the_class_mirror)); |
4008 java_lang_Class::classRedefinedCount(the_class_mirror)); |
4123 |
4009 |
4124 } |
4010 } |
4125 RC_TIMER_STOP(_timer_rsc_phase2); |
4011 _timer_rsc_phase2.stop(); |
4126 } // end redefine_single_class() |
4012 } // end redefine_single_class() |
4127 |
4013 |
4128 |
4014 |
4129 // Increment the classRedefinedCount field in the specific InstanceKlass |
4015 // Increment the classRedefinedCount field in the specific InstanceKlass |
4130 // and in all direct and indirect subclasses. |
4016 // and in all direct and indirect subclasses. |
4134 int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1; |
4020 int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1; |
4135 java_lang_Class::set_classRedefinedCount(class_mirror, new_count); |
4021 java_lang_Class::set_classRedefinedCount(class_mirror, new_count); |
4136 |
4022 |
4137 if (class_oop != _the_class_oop) { |
4023 if (class_oop != _the_class_oop) { |
4138 // _the_class_oop count is printed at end of redefine_single_class() |
4024 // _the_class_oop count is printed at end of redefine_single_class() |
4139 RC_TRACE_WITH_THREAD(0x00000008, THREAD, |
4025 log_debug(redefine, class, subclass)("updated count in subclass=%s to %d", ik->external_name(), new_count); |
4140 ("updated count in subclass=%s to %d", ik->external_name(), new_count)); |
|
4141 } |
4026 } |
4142 |
4027 |
4143 for (Klass *subk = ik->subklass(); subk != NULL; |
4028 for (Klass *subk = ik->subklass(); subk != NULL; |
4144 subk = subk->next_sibling()) { |
4029 subk = subk->next_sibling()) { |
4145 if (subk->is_instance_klass()) { |
4030 if (subk->is_instance_klass()) { |
4157 // Both array and instance classes have vtables. |
4042 // Both array and instance classes have vtables. |
4158 // a vtable should never contain old or obsolete methods |
4043 // a vtable should never contain old or obsolete methods |
4159 ResourceMark rm(_thread); |
4044 ResourceMark rm(_thread); |
4160 if (k->vtable_length() > 0 && |
4045 if (k->vtable_length() > 0 && |
4161 !k->vtable()->check_no_old_or_obsolete_entries()) { |
4046 !k->vtable()->check_no_old_or_obsolete_entries()) { |
4162 if (RC_TRACE_ENABLED(0x00004000)) { |
4047 if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) { |
4163 RC_TRACE_WITH_THREAD(0x00004000, _thread, |
4048 log_trace(redefine, class, obsolete, metadata) |
4164 ("klassVtable::check_no_old_or_obsolete_entries failure" |
4049 ("klassVtable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s", |
4165 " -- OLD or OBSOLETE method found -- class: %s", |
4050 k->signature_name()); |
4166 k->signature_name())); |
|
4167 k->vtable()->dump_vtable(); |
4051 k->vtable()->dump_vtable(); |
4168 } |
4052 } |
4169 no_old_methods = false; |
4053 no_old_methods = false; |
4170 } |
4054 } |
4171 |
4055 |
4174 InstanceKlass *ik = InstanceKlass::cast(k); |
4058 InstanceKlass *ik = InstanceKlass::cast(k); |
4175 |
4059 |
4176 // an itable should never contain old or obsolete methods |
4060 // an itable should never contain old or obsolete methods |
4177 if (ik->itable_length() > 0 && |
4061 if (ik->itable_length() > 0 && |
4178 !ik->itable()->check_no_old_or_obsolete_entries()) { |
4062 !ik->itable()->check_no_old_or_obsolete_entries()) { |
4179 if (RC_TRACE_ENABLED(0x00004000)) { |
4063 if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) { |
4180 RC_TRACE_WITH_THREAD(0x00004000, _thread, |
4064 log_trace(redefine, class, obsolete, metadata) |
4181 ("klassItable::check_no_old_or_obsolete_entries failure" |
4065 ("klassItable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s", |
4182 " -- OLD or OBSOLETE method found -- class: %s", |
4066 ik->signature_name()); |
4183 ik->signature_name())); |
|
4184 ik->itable()->dump_itable(); |
4067 ik->itable()->dump_itable(); |
4185 } |
4068 } |
4186 no_old_methods = false; |
4069 no_old_methods = false; |
4187 } |
4070 } |
4188 |
4071 |
4189 // the constant pool cache should never contain non-deleted old or obsolete methods |
4072 // the constant pool cache should never contain non-deleted old or obsolete methods |
4190 if (ik->constants() != NULL && |
4073 if (ik->constants() != NULL && |
4191 ik->constants()->cache() != NULL && |
4074 ik->constants()->cache() != NULL && |
4192 !ik->constants()->cache()->check_no_old_or_obsolete_entries()) { |
4075 !ik->constants()->cache()->check_no_old_or_obsolete_entries()) { |
4193 if (RC_TRACE_ENABLED(0x00004000)) { |
4076 if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) { |
4194 RC_TRACE_WITH_THREAD(0x00004000, _thread, |
4077 log_trace(redefine, class, obsolete, metadata) |
4195 ("cp-cache::check_no_old_or_obsolete_entries failure" |
4078 ("cp-cache::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s", |
4196 " -- OLD or OBSOLETE method found -- class: %s", |
4079 ik->signature_name()); |
4197 ik->signature_name())); |
|
4198 ik->constants()->cache()->dump_cache(); |
4080 ik->constants()->cache()->dump_cache(); |
4199 } |
4081 } |
4200 no_old_methods = false; |
4082 no_old_methods = false; |
4201 } |
4083 } |
4202 } |
4084 } |
4203 |
4085 |
4204 // print and fail guarantee if old methods are found. |
4086 // print and fail guarantee if old methods are found. |
4205 if (!no_old_methods) { |
4087 if (!no_old_methods) { |
4206 if (RC_TRACE_ENABLED(0x00004000)) { |
4088 if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) { |
4207 dump_methods(); |
4089 dump_methods(); |
4208 } else { |
4090 } else { |
4209 tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option " |
4091 log_trace(redefine, class)("Use the '-Xlog:redefine+class*:' option " |
4210 "to see more info about the following guarantee() failure."); |
4092 "to see more info about the following guarantee() failure."); |
4211 } |
4093 } |
4212 guarantee(false, "OLD and/or OBSOLETE method(s) found"); |
4094 guarantee(false, "OLD and/or OBSOLETE method(s) found"); |
4213 } |
4095 } |
4214 } |
4096 } |
4215 |
4097 |
4216 |
4098 |
4217 void VM_RedefineClasses::dump_methods() { |
4099 void VM_RedefineClasses::dump_methods() { |
4218 int j; |
4100 int j; |
4219 RC_TRACE(0x00004000, ("_old_methods --")); |
4101 log_trace(redefine, class, dump)("_old_methods --"); |
4220 for (j = 0; j < _old_methods->length(); ++j) { |
4102 for (j = 0; j < _old_methods->length(); ++j) { |
4103 LogStreamHandle(Trace, redefine, class, dump) log_stream; |
|
4221 Method* m = _old_methods->at(j); |
4104 Method* m = _old_methods->at(j); |
4222 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
4105 log_stream.print("%4d (%5d) ", j, m->vtable_index()); |
4223 m->access_flags().print_on(tty); |
4106 m->access_flags().print_on(&log_stream); |
4224 tty->print(" -- "); |
4107 log_stream.print(" -- "); |
4225 m->print_name(tty); |
4108 m->print_name(&log_stream); |
4226 tty->cr(); |
4109 log_stream.cr(); |
4227 } |
4110 } |
4228 RC_TRACE(0x00004000, ("_new_methods --")); |
4111 log_trace(redefine, class, dump)("_new_methods --"); |
4229 for (j = 0; j < _new_methods->length(); ++j) { |
4112 for (j = 0; j < _new_methods->length(); ++j) { |
4113 LogStreamHandle(Trace, redefine, class, dump) log_stream; |
|
4230 Method* m = _new_methods->at(j); |
4114 Method* m = _new_methods->at(j); |
4231 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
4115 log_stream.print("%4d (%5d) ", j, m->vtable_index()); |
4232 m->access_flags().print_on(tty); |
4116 m->access_flags().print_on(&log_stream); |
4233 tty->print(" -- "); |
4117 log_stream.print(" -- "); |
4234 m->print_name(tty); |
4118 m->print_name(&log_stream); |
4235 tty->cr(); |
4119 log_stream.cr(); |
4236 } |
4120 } |
4237 RC_TRACE(0x00004000, ("_matching_(old/new)_methods --")); |
4121 log_trace(redefine, class, dump)("_matching_methods --"); |
4238 for (j = 0; j < _matching_methods_length; ++j) { |
4122 for (j = 0; j < _matching_methods_length; ++j) { |
4123 LogStreamHandle(Trace, redefine, class, dump) log_stream; |
|
4239 Method* m = _matching_old_methods[j]; |
4124 Method* m = _matching_old_methods[j]; |
4240 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
4125 log_stream.print("%4d (%5d) ", j, m->vtable_index()); |
4241 m->access_flags().print_on(tty); |
4126 m->access_flags().print_on(&log_stream); |
4242 tty->print(" -- "); |
4127 log_stream.print(" -- "); |
4243 m->print_name(tty); |
4128 m->print_name(); |
4244 tty->cr(); |
4129 log_stream.cr(); |
4130 |
|
4245 m = _matching_new_methods[j]; |
4131 m = _matching_new_methods[j]; |
4246 RC_TRACE_NO_CR(0x00004000, (" (%5d) ", m->vtable_index())); |
4132 log_stream.print(" (%5d) ", m->vtable_index()); |
4247 m->access_flags().print_on(tty); |
4133 m->access_flags().print_on(&log_stream); |
4248 tty->cr(); |
4134 log_stream.cr(); |
4249 } |
4135 } |
4250 RC_TRACE(0x00004000, ("_deleted_methods --")); |
4136 log_trace(redefine, class, dump)("_deleted_methods --"); |
4251 for (j = 0; j < _deleted_methods_length; ++j) { |
4137 for (j = 0; j < _deleted_methods_length; ++j) { |
4138 LogStreamHandle(Trace, redefine, class, dump) log_stream; |
|
4252 Method* m = _deleted_methods[j]; |
4139 Method* m = _deleted_methods[j]; |
4253 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
4140 log_stream.print("%4d (%5d) ", j, m->vtable_index()); |
4254 m->access_flags().print_on(tty); |
4141 m->access_flags().print_on(&log_stream); |
4255 tty->print(" -- "); |
4142 log_stream.print(" -- "); |
4256 m->print_name(tty); |
4143 m->print_name(&log_stream); |
4257 tty->cr(); |
4144 log_stream.cr(); |
4258 } |
4145 } |
4259 RC_TRACE(0x00004000, ("_added_methods --")); |
4146 log_trace(redefine, class, dump)("_added_methods --"); |
4260 for (j = 0; j < _added_methods_length; ++j) { |
4147 for (j = 0; j < _added_methods_length; ++j) { |
4148 LogStreamHandle(Trace, redefine, class, dump) log_stream; |
|
4261 Method* m = _added_methods[j]; |
4149 Method* m = _added_methods[j]; |
4262 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
4150 log_stream.print("%4d (%5d) ", j, m->vtable_index()); |
4263 m->access_flags().print_on(tty); |
4151 m->access_flags().print_on(&log_stream); |
4264 tty->print(" -- "); |
4152 log_stream.print(" -- "); |
4265 m->print_name(tty); |
4153 m->print_name(&log_stream); |
4266 tty->cr(); |
4154 log_stream.cr(); |
4267 } |
4155 } |
4268 } |
4156 } |
4269 |
4157 |
4270 void VM_RedefineClasses::print_on_error(outputStream* st) const { |
4158 void VM_RedefineClasses::print_on_error(outputStream* st) const { |
4271 VM_Operation::print_on_error(st); |
4159 VM_Operation::print_on_error(st); |