src/share/vm/runtime/relocator.cpp

changeset 2232
a4c7fe54bf3f
parent 1907
c18cbe5936b8
child 2314
f95d63e2154a
     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;

mercurial