src/share/vm/oops/constantPool.cpp

changeset 4983
15a99ca4ee34
parent 4889
cc32ccaaf47f
child 4984
c115fac239eb
     1.1 --- a/src/share/vm/oops/constantPool.cpp	Wed Apr 24 15:57:17 2013 -0700
     1.2 +++ b/src/share/vm/oops/constantPool.cpp	Thu Apr 25 03:58:53 2013 -0700
     1.3 @@ -1043,24 +1043,13 @@
     1.4  
     1.5    case JVM_CONSTANT_InvokeDynamic:
     1.6    {
     1.7 -    int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1);
     1.8 -    int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2);
     1.9 -    bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
    1.10 -    if (!match)  return false;
    1.11 -    k1 = invoke_dynamic_name_and_type_ref_index_at(index1);
    1.12 -    k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
    1.13 -    match = compare_entry_to(k1, cp2, k2, CHECK_false);
    1.14 -    if (!match)  return false;
    1.15 -    int argc = invoke_dynamic_argument_count_at(index1);
    1.16 -    if (argc == cp2->invoke_dynamic_argument_count_at(index2)) {
    1.17 -      for (int j = 0; j < argc; j++) {
    1.18 -        k1 = invoke_dynamic_argument_index_at(index1, j);
    1.19 -        k2 = cp2->invoke_dynamic_argument_index_at(index2, j);
    1.20 -        match = compare_entry_to(k1, cp2, k2, CHECK_false);
    1.21 -        if (!match)  return false;
    1.22 -      }
    1.23 -      return true;           // got through loop; all elements equal
    1.24 -    }
    1.25 +    int k1 = invoke_dynamic_name_and_type_ref_index_at(index1);
    1.26 +    int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
    1.27 +    int i1 = invoke_dynamic_bootstrap_specifier_index(index1);
    1.28 +    int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2);
    1.29 +    bool match = compare_entry_to(k1, cp2, k2, CHECK_false) &&
    1.30 +                 compare_operand_to(i1, cp2, i2, CHECK_false);
    1.31 +    return match;
    1.32    } break;
    1.33  
    1.34    case JVM_CONSTANT_String:
    1.35 @@ -1095,6 +1084,80 @@
    1.36  } // end compare_entry_to()
    1.37  
    1.38  
    1.39 +// Resize the operands array with delta_len and delta_size.
    1.40 +// Used in RedefineClasses for CP merge.
    1.41 +void ConstantPool::resize_operands(int delta_len, int delta_size, TRAPS) {
    1.42 +  int old_len  = operand_array_length(operands());
    1.43 +  int new_len  = old_len + delta_len;
    1.44 +  int min_len  = (delta_len > 0) ? old_len : new_len;
    1.45 +
    1.46 +  int old_size = operands()->length();
    1.47 +  int new_size = old_size + delta_size;
    1.48 +  int min_size = (delta_size > 0) ? old_size : new_size;
    1.49 +
    1.50 +  ClassLoaderData* loader_data = pool_holder()->class_loader_data();
    1.51 +  Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, new_size, CHECK);
    1.52 +
    1.53 +  // Set index in the resized array for existing elements only
    1.54 +  for (int idx = 0; idx < min_len; idx++) {
    1.55 +    int offset = operand_offset_at(idx);                       // offset in original array
    1.56 +    operand_offset_at_put(new_ops, idx, offset + 2*delta_len); // offset in resized array
    1.57 +  }
    1.58 +  // Copy the bootstrap specifiers only
    1.59 +  Copy::conjoint_memory_atomic(operands()->adr_at(2*old_len),
    1.60 +                               new_ops->adr_at(2*new_len),
    1.61 +                               (min_size - 2*min_len) * sizeof(u2));
    1.62 +  // Explicitly deallocate old operands array.
    1.63 +  // Note, it is not needed for 7u backport.
    1.64 +  if ( operands() != NULL) { // the safety check
    1.65 +    MetadataFactory::free_array<u2>(loader_data, operands());
    1.66 +  }
    1.67 +  set_operands(new_ops);
    1.68 +} // end resize_operands()
    1.69 +
    1.70 +
    1.71 +// Extend the operands array with the length and size of the ext_cp operands.
    1.72 +// Used in RedefineClasses for CP merge.
    1.73 +void ConstantPool::extend_operands(constantPoolHandle ext_cp, TRAPS) {
    1.74 +  int delta_len = operand_array_length(ext_cp->operands());
    1.75 +  if (delta_len == 0) {
    1.76 +    return; // nothing to do
    1.77 +  }
    1.78 +  int delta_size = ext_cp->operands()->length();
    1.79 +
    1.80 +  assert(delta_len  > 0 && delta_size > 0, "extended operands array must be bigger");
    1.81 +
    1.82 +  if (operand_array_length(operands()) == 0) {
    1.83 +    ClassLoaderData* loader_data = pool_holder()->class_loader_data();
    1.84 +    Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, delta_size, CHECK);
    1.85 +    // The first element index defines the offset of second part
    1.86 +    operand_offset_at_put(new_ops, 0, 2*delta_len); // offset in new array
    1.87 +    set_operands(new_ops);
    1.88 +  } else {
    1.89 +    resize_operands(delta_len, delta_size, CHECK);
    1.90 +  }
    1.91 +
    1.92 +} // end extend_operands()
    1.93 +
    1.94 +
    1.95 +// Shrink the operands array to a smaller array with new_len length.
    1.96 +// Used in RedefineClasses for CP merge.
    1.97 +void ConstantPool::shrink_operands(int new_len, TRAPS) {
    1.98 +  int old_len = operand_array_length(operands());
    1.99 +  if (new_len == old_len) {
   1.100 +    return; // nothing to do
   1.101 +  }
   1.102 +  assert(new_len < old_len, "shrunken operands array must be smaller");
   1.103 +
   1.104 +  int free_base  = operand_next_offset_at(new_len - 1);
   1.105 +  int delta_len  = new_len - old_len;
   1.106 +  int delta_size = 2*delta_len + free_base - operands()->length();
   1.107 +
   1.108 +  resize_operands(delta_len, delta_size, CHECK);
   1.109 +
   1.110 +} // end shrink_operands()
   1.111 +
   1.112 +
   1.113  void ConstantPool::copy_operands(constantPoolHandle from_cp,
   1.114                                   constantPoolHandle to_cp,
   1.115                                   TRAPS) {
   1.116 @@ -1357,6 +1420,46 @@
   1.117  } // end find_matching_entry()
   1.118  
   1.119  
   1.120 +// Compare this constant pool's bootstrap specifier at idx1 to the constant pool
   1.121 +// cp2's bootstrap specifier at idx2.
   1.122 +bool ConstantPool::compare_operand_to(int idx1, constantPoolHandle cp2, int idx2, TRAPS) {
   1.123 +  int k1 = operand_bootstrap_method_ref_index_at(idx1);
   1.124 +  int k2 = cp2->operand_bootstrap_method_ref_index_at(idx2);
   1.125 +  bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
   1.126 +
   1.127 +  if (!match) {
   1.128 +    return false;
   1.129 +  }
   1.130 +  int argc = operand_argument_count_at(idx1);
   1.131 +  if (argc == cp2->operand_argument_count_at(idx2)) {
   1.132 +    for (int j = 0; j < argc; j++) {
   1.133 +      k1 = operand_argument_index_at(idx1, j);
   1.134 +      k2 = cp2->operand_argument_index_at(idx2, j);
   1.135 +      match = compare_entry_to(k1, cp2, k2, CHECK_false);
   1.136 +      if (!match) {
   1.137 +        return false;
   1.138 +      }
   1.139 +    }
   1.140 +    return true;           // got through loop; all elements equal
   1.141 +  }
   1.142 +  return false;
   1.143 +} // end compare_operand_to()
   1.144 +
   1.145 +// Search constant pool search_cp for a bootstrap specifier that matches
   1.146 +// this constant pool's bootstrap specifier at pattern_i index.
   1.147 +// Return the index of a matching bootstrap specifier or (-1) if there is no match.
   1.148 +int ConstantPool::find_matching_operand(int pattern_i,
   1.149 +                    constantPoolHandle search_cp, int search_len, TRAPS) {
   1.150 +  for (int i = 0; i < search_len; i++) {
   1.151 +    bool found = compare_operand_to(pattern_i, search_cp, i, CHECK_(-1));
   1.152 +    if (found) {
   1.153 +      return i;
   1.154 +    }
   1.155 +  }
   1.156 +  return -1;  // bootstrap specifier not found; return unused index (-1)
   1.157 +} // end find_matching_operand()
   1.158 +
   1.159 +
   1.160  #ifndef PRODUCT
   1.161  
   1.162  const char* ConstantPool::printable_name_at(int which) {

mercurial