23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/stackMapTableFormat.hpp" |
26 #include "classfile/stackMapTableFormat.hpp" |
27 #include "interpreter/bytecodes.hpp" |
27 #include "interpreter/bytecodes.hpp" |
|
28 #include "memory/metadataFactory.hpp" |
28 #include "memory/oopFactory.hpp" |
29 #include "memory/oopFactory.hpp" |
29 #include "memory/universe.inline.hpp" |
30 #include "memory/universe.inline.hpp" |
30 #include "oops/oop.inline.hpp" |
31 #include "oops/oop.inline.hpp" |
31 #include "runtime/handles.inline.hpp" |
32 #include "runtime/handles.inline.hpp" |
32 #include "runtime/relocator.hpp" |
33 #include "runtime/relocator.hpp" |
153 } |
154 } |
154 |
155 |
155 if (!handle_code_changes()) return methodHandle(); |
156 if (!handle_code_changes()) return methodHandle(); |
156 |
157 |
157 // Construct the new method |
158 // Construct the new method |
158 methodHandle new_method = methodOopDesc::clone_with_new_data(method(), |
159 methodHandle new_method = Method::clone_with_new_data(method(), |
159 code_array(), code_length(), |
160 code_array(), code_length(), |
160 compressed_line_number_table(), |
161 compressed_line_number_table(), |
161 compressed_line_number_table_size(), |
162 compressed_line_number_table_size(), |
162 CHECK_(methodHandle())); |
163 CHECK_(methodHandle())); |
|
164 |
|
165 // Deallocate the old Method* from metadata |
|
166 ClassLoaderData* loader_data = method()->method_holder()->class_loader_data(); |
|
167 loader_data->add_to_deallocate_list(method()()); |
|
168 |
163 set_method(new_method); |
169 set_method(new_method); |
164 |
170 |
165 if (TraceRelocator) { |
171 if (TraceRelocator) { |
166 tty->print_cr("-------------------------------------------------"); |
172 tty->print_cr("-------------------------------------------------"); |
167 tty->print_cr("new method"); |
173 tty->print_cr("new method"); |
441 } |
447 } |
442 } |
448 } |
443 |
449 |
444 // Create a new array, copying the src array but adding a hole at |
450 // Create a new array, copying the src array but adding a hole at |
445 // the specified location |
451 // the specified location |
446 static typeArrayOop insert_hole_at( |
452 static Array<u1>* insert_hole_at(ClassLoaderData* loader_data, |
447 size_t where, int hole_sz, typeArrayOop src) { |
453 size_t where, int hole_sz, Array<u1>* src) { |
448 Thread* THREAD = Thread::current(); |
454 Thread* THREAD = Thread::current(); |
449 Handle src_hnd(THREAD, src); |
455 Array<u1>* dst = |
450 typeArrayOop dst = |
456 MetadataFactory::new_array<u1>(loader_data, src->length() + hole_sz, 0, CHECK_NULL); |
451 oopFactory::new_permanent_byteArray(src->length() + hole_sz, CHECK_NULL); |
457 |
452 src = (typeArrayOop)src_hnd(); |
458 address src_addr = (address)src->adr_at(0); |
453 |
459 address dst_addr = (address)dst->adr_at(0); |
454 address src_addr = (address)src->byte_at_addr(0); |
|
455 address dst_addr = (address)dst->byte_at_addr(0); |
|
456 |
460 |
457 memcpy(dst_addr, src_addr, where); |
461 memcpy(dst_addr, src_addr, where); |
458 memcpy(dst_addr + where + hole_sz, |
462 memcpy(dst_addr + where + hole_sz, |
459 src_addr + where, src->length() - where); |
463 src_addr + where, src->length() - where); |
460 return dst; |
464 return dst; |
462 |
466 |
463 // The width of instruction at "bci" is changing by "delta". Adjust the stack |
467 // The width of instruction at "bci" is changing by "delta". Adjust the stack |
464 // map frames. |
468 // map frames. |
465 void Relocator::adjust_stack_map_table(int bci, int delta) { |
469 void Relocator::adjust_stack_map_table(int bci, int delta) { |
466 if (method()->has_stackmap_table()) { |
470 if (method()->has_stackmap_table()) { |
467 typeArrayOop data = method()->stackmap_data(); |
471 Array<u1>* data = method()->stackmap_data(); |
468 // The data in the array is a classfile representation of the stackmap table |
472 // The data in the array is a classfile representation of the stackmap table |
469 stack_map_table* sm_table = |
473 stack_map_table* sm_table = |
470 stack_map_table::at((address)data->byte_at_addr(0)); |
474 stack_map_table::at((address)data->adr_at(0)); |
471 |
475 |
472 int count = sm_table->number_of_entries(); |
476 int count = sm_table->number_of_entries(); |
473 stack_map_frame* frame = sm_table->entries(); |
477 stack_map_frame* frame = sm_table->entries(); |
474 int bci_iter = -1; |
478 int bci_iter = -1; |
475 bool offset_adjusted = false; // only need to adjust one offset |
479 bool offset_adjusted = false; // only need to adjust one offset |
495 // right after the 'frame_type' for the new offset field. |
499 // right after the 'frame_type' for the new offset field. |
496 // |
500 // |
497 // We can safely ignore the reverse situation as a small delta |
501 // We can safely ignore the reverse situation as a small delta |
498 // can still be used in an extended version of the frame. |
502 // can still be used in an extended version of the frame. |
499 |
503 |
500 size_t frame_offset = (address)frame - (address)data->byte_at_addr(0); |
504 size_t frame_offset = (address)frame - (address)data->adr_at(0); |
501 |
505 |
502 data = insert_hole_at(frame_offset + 1, 2, data); |
506 ClassLoaderData* loader_data = method()->method_holder()->class_loader_data(); |
503 if (data == NULL) { |
507 Array<u1>* new_data = insert_hole_at(loader_data, frame_offset + 1, 2, data); |
|
508 if (new_data == NULL) { |
504 return; // out-of-memory? |
509 return; // out-of-memory? |
505 } |
510 } |
506 |
511 // Deallocate old data |
507 address frame_addr = (address)(data->byte_at_addr(0) + frame_offset); |
512 MetadataFactory::free_array<u1>(loader_data, data); |
|
513 data = new_data; |
|
514 |
|
515 address frame_addr = (address)(data->adr_at(0) + frame_offset); |
508 frame = stack_map_frame::at(frame_addr); |
516 frame = stack_map_frame::at(frame_addr); |
509 |
517 |
510 |
518 |
511 // Now convert the frames in place |
519 // Now convert the frames in place |
512 if (frame->is_same_frame()) { |
520 if (frame->is_same_frame()) { |
571 |
579 |
572 // Expanding current array |
580 // Expanding current array |
573 if (code_array() != NULL) { |
581 if (code_array() != NULL) { |
574 memcpy(new_code_array, code_array(), code_length()); |
582 memcpy(new_code_array, code_array(), code_length()); |
575 } else { |
583 } else { |
576 // Initial copy. Copy directly from methodOop |
584 // Initial copy. Copy directly from Method* |
577 memcpy(new_code_array, method()->code_base(), code_length()); |
585 memcpy(new_code_array, method()->code_base(), code_length()); |
578 } |
586 } |
579 |
587 |
580 set_code_array(new_code_array); |
588 set_code_array(new_code_array); |
581 set_code_array_length(length); |
589 set_code_array_length(length); |