1.1 --- a/src/share/vm/runtime/relocator.cpp Mon Oct 18 09:33:24 2010 -0700 1.2 +++ b/src/share/vm/runtime/relocator.cpp Thu Oct 21 10:10:23 2010 -0400 1.3 @@ -435,6 +435,120 @@ 1.4 } 1.5 } 1.6 1.7 +// Create a new array, copying the src array but adding a hole at 1.8 +// the specified location 1.9 +static typeArrayOop insert_hole_at( 1.10 + size_t where, int hole_sz, typeArrayOop src) { 1.11 + Thread* THREAD = Thread::current(); 1.12 + Handle src_hnd(THREAD, src); 1.13 + typeArrayOop dst = 1.14 + oopFactory::new_permanent_byteArray(src->length() + hole_sz, CHECK_NULL); 1.15 + src = (typeArrayOop)src_hnd(); 1.16 + 1.17 + address src_addr = (address)src->byte_at_addr(0); 1.18 + address dst_addr = (address)dst->byte_at_addr(0); 1.19 + 1.20 + memcpy(dst_addr, src_addr, where); 1.21 + memcpy(dst_addr + where + hole_sz, 1.22 + src_addr + where, src->length() - where); 1.23 + return dst; 1.24 +} 1.25 + 1.26 +// The width of instruction at "bci" is changing by "delta". Adjust the stack 1.27 +// map frames. 1.28 +void Relocator::adjust_stack_map_table(int bci, int delta) { 1.29 + if (method()->has_stackmap_table()) { 1.30 + typeArrayOop data = method()->stackmap_data(); 1.31 + // The data in the array is a classfile representation of the stackmap 1.32 + // table attribute, less the initial u2 tag and u4 attribute_length fields. 1.33 + stack_map_table_attribute* attr = stack_map_table_attribute::at( 1.34 + (address)data->byte_at_addr(0) - (sizeof(u2) + sizeof(u4))); 1.35 + 1.36 + int count = attr->number_of_entries(); 1.37 + stack_map_frame* frame = attr->entries(); 1.38 + int bci_iter = -1; 1.39 + bool offset_adjusted = false; // only need to adjust one offset 1.40 + 1.41 + for (int i = 0; i < count; ++i) { 1.42 + int offset_delta = frame->offset_delta(); 1.43 + bci_iter += offset_delta; 1.44 + 1.45 + if (!offset_adjusted && bci_iter > bci) { 1.46 + int new_offset_delta = offset_delta + delta; 1.47 + 1.48 + if (frame->is_valid_offset(new_offset_delta)) { 1.49 + frame->set_offset_delta(new_offset_delta); 1.50 + } else { 1.51 + assert(frame->is_same_frame() || 1.52 + frame->is_same_frame_1_stack_item_frame(), 1.53 + "Frame must be one of the compressed forms"); 1.54 + // The new delta exceeds the capacity of the 'same_frame' or 1.55 + // 'same_frame_1_stack_item_frame' frame types. We need to 1.56 + // convert these frames to the extended versions, but the extended 1.57 + // version is bigger and requires more room. So we allocate a 1.58 + // new array and copy the data, being sure to leave u2-sized hole 1.59 + // right after the 'frame_type' for the new offset field. 1.60 + // 1.61 + // We can safely ignore the reverse situation as a small delta 1.62 + // can still be used in an extended version of the frame. 1.63 + 1.64 + size_t frame_offset = (address)frame - (address)data->byte_at_addr(0); 1.65 + 1.66 + data = insert_hole_at(frame_offset + 1, 2, data); 1.67 + if (data == NULL) { 1.68 + return; // out-of-memory? 1.69 + } 1.70 + 1.71 + address frame_addr = (address)(data->byte_at_addr(0) + frame_offset); 1.72 + frame = stack_map_frame::at(frame_addr); 1.73 + 1.74 + 1.75 + // Now convert the frames in place 1.76 + if (frame->is_same_frame()) { 1.77 + same_frame_extended::create_at(frame_addr, new_offset_delta); 1.78 + } else { 1.79 + same_frame_1_stack_item_extended::create_at( 1.80 + frame_addr, new_offset_delta, NULL); 1.81 + // the verification_info_type should already be at the right spot 1.82 + } 1.83 + } 1.84 + offset_adjusted = true; // needs to be done only once, since subsequent 1.85 + // values are offsets from the current 1.86 + } 1.87 + 1.88 + // The stack map frame may contain verification types, if so we need to 1.89 + // check and update any Uninitialized type's bci (no matter where it is). 1.90 + int number_of_types = frame->number_of_types(); 1.91 + verification_type_info* types = frame->types(); 1.92 + 1.93 + for (int i = 0; i < number_of_types; ++i) { 1.94 + if (types->is_uninitialized() && types->bci() > bci) { 1.95 + types->set_bci(types->bci() + delta); 1.96 + } 1.97 + types = types->next(); 1.98 + } 1.99 + 1.100 + // Full frame has stack values too 1.101 + full_frame* ff = frame->as_full_frame(); 1.102 + if (ff != NULL) { 1.103 + address eol = (address)types; 1.104 + number_of_types = ff->stack_slots(eol); 1.105 + types = ff->stack(eol); 1.106 + for (int i = 0; i < number_of_types; ++i) { 1.107 + if (types->is_uninitialized() && types->bci() > bci) { 1.108 + types->set_bci(types->bci() + delta); 1.109 + } 1.110 + types = types->next(); 1.111 + } 1.112 + } 1.113 + 1.114 + frame = frame->next(); 1.115 + } 1.116 + 1.117 + method()->set_stackmap_data(data); // in case it has changed 1.118 + } 1.119 +} 1.120 + 1.121 1.122 bool Relocator::expand_code_array(int delta) { 1.123 int length = MAX2(code_length() + delta, code_length() * (100+code_slop_pct()) / 100); 1.124 @@ -499,6 +613,9 @@ 1.125 // And local variable table... 1.126 adjust_local_var_table(bci, delta); 1.127 1.128 + // Adjust stack maps 1.129 + adjust_stack_map_table(bci, delta); 1.130 + 1.131 // Relocate the pending change stack... 1.132 for (int j = 0; j < _changes->length(); j++) { 1.133 ChangeItem* ci = _changes->at(j); 1.134 @@ -641,6 +758,7 @@ 1.135 memmove(addr_at(bci +1 + new_pad), 1.136 addr_at(bci +1 + old_pad), 1.137 len * 4); 1.138 + memset(addr_at(bci + 1), 0, new_pad); // pad must be 0 1.139 } 1.140 } 1.141 return true;