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) {