Fri, 01 Feb 2013 14:42:43 -0800
Merge
1.1 --- a/src/share/vm/oops/constantPool.cpp Fri Feb 01 13:30:12 2013 -0500 1.2 +++ b/src/share/vm/oops/constantPool.cpp Fri Feb 01 14:42:43 2013 -0800 1.3 @@ -1129,7 +1129,7 @@ 1.4 (len = old_off) * sizeof(u2)); 1.5 fillp += len; 1.6 // first part of src 1.7 - Copy::conjoint_memory_atomic(to_cp->operands()->adr_at(0), 1.8 + Copy::conjoint_memory_atomic(from_cp->operands()->adr_at(0), 1.9 new_operands->adr_at(fillp), 1.10 (len = from_off) * sizeof(u2)); 1.11 fillp += len; 1.12 @@ -1139,7 +1139,7 @@ 1.13 (len = old_len - old_off) * sizeof(u2)); 1.14 fillp += len; 1.15 // second part of src 1.16 - Copy::conjoint_memory_atomic(to_cp->operands()->adr_at(from_off), 1.17 + Copy::conjoint_memory_atomic(from_cp->operands()->adr_at(from_off), 1.18 new_operands->adr_at(fillp), 1.19 (len = from_len - from_off) * sizeof(u2)); 1.20 fillp += len;
2.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Feb 01 13:30:12 2013 -0500 2.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Feb 01 14:42:43 2013 -0800 2.3 @@ -278,76 +278,23 @@ 2.4 case JVM_CONSTANT_NameAndType: 2.5 { 2.6 int name_ref_i = scratch_cp->name_ref_index_at(scratch_i); 2.7 - int new_name_ref_i = 0; 2.8 - bool match = (name_ref_i < *merge_cp_length_p) && 2.9 - scratch_cp->compare_entry_to(name_ref_i, *merge_cp_p, name_ref_i, 2.10 - THREAD); 2.11 - if (!match) { 2.12 - // forward reference in *merge_cp_p or not a direct match 2.13 - 2.14 - int found_i = scratch_cp->find_matching_entry(name_ref_i, *merge_cp_p, 2.15 - THREAD); 2.16 - if (found_i != 0) { 2.17 - guarantee(found_i != name_ref_i, 2.18 - "compare_entry_to() and find_matching_entry() do not agree"); 2.19 - 2.20 - // Found a matching entry somewhere else in *merge_cp_p so 2.21 - // just need a mapping entry. 2.22 - new_name_ref_i = found_i; 2.23 - map_index(scratch_cp, name_ref_i, found_i); 2.24 - } else { 2.25 - // no match found so we have to append this entry to *merge_cp_p 2.26 - append_entry(scratch_cp, name_ref_i, merge_cp_p, merge_cp_length_p, 2.27 - THREAD); 2.28 - // The above call to append_entry() can only append one entry 2.29 - // so the post call query of *merge_cp_length_p is only for 2.30 - // the sake of consistency. 2.31 - new_name_ref_i = *merge_cp_length_p - 1; 2.32 - } 2.33 - } 2.34 + int new_name_ref_i = find_or_append_indirect_entry(scratch_cp, name_ref_i, merge_cp_p, 2.35 + merge_cp_length_p, THREAD); 2.36 2.37 int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i); 2.38 - int new_signature_ref_i = 0; 2.39 - match = (signature_ref_i < *merge_cp_length_p) && 2.40 - scratch_cp->compare_entry_to(signature_ref_i, *merge_cp_p, 2.41 - signature_ref_i, THREAD); 2.42 - if (!match) { 2.43 - // forward reference in *merge_cp_p or not a direct match 2.44 - 2.45 - int found_i = scratch_cp->find_matching_entry(signature_ref_i, 2.46 - *merge_cp_p, THREAD); 2.47 - if (found_i != 0) { 2.48 - guarantee(found_i != signature_ref_i, 2.49 - "compare_entry_to() and find_matching_entry() do not agree"); 2.50 - 2.51 - // Found a matching entry somewhere else in *merge_cp_p so 2.52 - // just need a mapping entry. 2.53 - new_signature_ref_i = found_i; 2.54 - map_index(scratch_cp, signature_ref_i, found_i); 2.55 - } else { 2.56 - // no match found so we have to append this entry to *merge_cp_p 2.57 - append_entry(scratch_cp, signature_ref_i, merge_cp_p, 2.58 - merge_cp_length_p, THREAD); 2.59 - // The above call to append_entry() can only append one entry 2.60 - // so the post call query of *merge_cp_length_p is only for 2.61 - // the sake of consistency. 2.62 - new_signature_ref_i = *merge_cp_length_p - 1; 2.63 - } 2.64 - } 2.65 + int new_signature_ref_i = find_or_append_indirect_entry(scratch_cp, signature_ref_i, 2.66 + merge_cp_p, merge_cp_length_p, 2.67 + THREAD); 2.68 2.69 // If the referenced entries already exist in *merge_cp_p, then 2.70 // both new_name_ref_i and new_signature_ref_i will both be 0. 2.71 // In that case, all we are appending is the current entry. 2.72 - if (new_name_ref_i == 0) { 2.73 - new_name_ref_i = name_ref_i; 2.74 - } else { 2.75 + if (new_name_ref_i != name_ref_i) { 2.76 RC_TRACE(0x00080000, 2.77 ("NameAndType entry@%d name_ref_index change: %d to %d", 2.78 *merge_cp_length_p, name_ref_i, new_name_ref_i)); 2.79 } 2.80 - if (new_signature_ref_i == 0) { 2.81 - new_signature_ref_i = signature_ref_i; 2.82 - } else { 2.83 + if (new_signature_ref_i != signature_ref_i) { 2.84 RC_TRACE(0x00080000, 2.85 ("NameAndType entry@%d signature_ref_index change: %d to %d", 2.86 *merge_cp_length_p, signature_ref_i, new_signature_ref_i)); 2.87 @@ -369,76 +316,12 @@ 2.88 case JVM_CONSTANT_Methodref: 2.89 { 2.90 int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i); 2.91 - int new_klass_ref_i = 0; 2.92 - bool match = (klass_ref_i < *merge_cp_length_p) && 2.93 - scratch_cp->compare_entry_to(klass_ref_i, *merge_cp_p, klass_ref_i, 2.94 - THREAD); 2.95 - if (!match) { 2.96 - // forward reference in *merge_cp_p or not a direct match 2.97 - 2.98 - int found_i = scratch_cp->find_matching_entry(klass_ref_i, *merge_cp_p, 2.99 - THREAD); 2.100 - if (found_i != 0) { 2.101 - guarantee(found_i != klass_ref_i, 2.102 - "compare_entry_to() and find_matching_entry() do not agree"); 2.103 - 2.104 - // Found a matching entry somewhere else in *merge_cp_p so 2.105 - // just need a mapping entry. 2.106 - new_klass_ref_i = found_i; 2.107 - map_index(scratch_cp, klass_ref_i, found_i); 2.108 - } else { 2.109 - // no match found so we have to append this entry to *merge_cp_p 2.110 - append_entry(scratch_cp, klass_ref_i, merge_cp_p, merge_cp_length_p, 2.111 - THREAD); 2.112 - // The above call to append_entry() can only append one entry 2.113 - // so the post call query of *merge_cp_length_p is only for 2.114 - // the sake of consistency. Without the optimization where we 2.115 - // use JVM_CONSTANT_UnresolvedClass, then up to two entries 2.116 - // could be appended. 2.117 - new_klass_ref_i = *merge_cp_length_p - 1; 2.118 - } 2.119 - } 2.120 - 2.121 - int name_and_type_ref_i = 2.122 - scratch_cp->uncached_name_and_type_ref_index_at(scratch_i); 2.123 - int new_name_and_type_ref_i = 0; 2.124 - match = (name_and_type_ref_i < *merge_cp_length_p) && 2.125 - scratch_cp->compare_entry_to(name_and_type_ref_i, *merge_cp_p, 2.126 - name_and_type_ref_i, THREAD); 2.127 - if (!match) { 2.128 - // forward reference in *merge_cp_p or not a direct match 2.129 - 2.130 - int found_i = scratch_cp->find_matching_entry(name_and_type_ref_i, 2.131 - *merge_cp_p, THREAD); 2.132 - if (found_i != 0) { 2.133 - guarantee(found_i != name_and_type_ref_i, 2.134 - "compare_entry_to() and find_matching_entry() do not agree"); 2.135 - 2.136 - // Found a matching entry somewhere else in *merge_cp_p so 2.137 - // just need a mapping entry. 2.138 - new_name_and_type_ref_i = found_i; 2.139 - map_index(scratch_cp, name_and_type_ref_i, found_i); 2.140 - } else { 2.141 - // no match found so we have to append this entry to *merge_cp_p 2.142 - append_entry(scratch_cp, name_and_type_ref_i, merge_cp_p, 2.143 - merge_cp_length_p, THREAD); 2.144 - // The above call to append_entry() can append more than 2.145 - // one entry so the post call query of *merge_cp_length_p 2.146 - // is required in order to get the right index for the 2.147 - // JVM_CONSTANT_NameAndType entry. 2.148 - new_name_and_type_ref_i = *merge_cp_length_p - 1; 2.149 - } 2.150 - } 2.151 - 2.152 - // If the referenced entries already exist in *merge_cp_p, then 2.153 - // both new_klass_ref_i and new_name_and_type_ref_i will both be 2.154 - // 0. In that case, all we are appending is the current entry. 2.155 - if (new_klass_ref_i == 0) { 2.156 - new_klass_ref_i = klass_ref_i; 2.157 - } 2.158 - if (new_name_and_type_ref_i == 0) { 2.159 - new_name_and_type_ref_i = name_and_type_ref_i; 2.160 - } 2.161 + int new_klass_ref_i = find_or_append_indirect_entry(scratch_cp, klass_ref_i, 2.162 + merge_cp_p, merge_cp_length_p, THREAD); 2.163 + 2.164 + int name_and_type_ref_i = scratch_cp->uncached_name_and_type_ref_index_at(scratch_i); 2.165 + int new_name_and_type_ref_i = find_or_append_indirect_entry(scratch_cp, name_and_type_ref_i, 2.166 + merge_cp_p, merge_cp_length_p, THREAD); 2.167 2.168 const char *entry_name; 2.169 switch (scratch_cp->tag_at(scratch_i).value()) { 2.170 @@ -481,6 +364,72 @@ 2.171 (*merge_cp_length_p)++; 2.172 } break; 2.173 2.174 + // this is an indirect CP entry so it needs special handling 2.175 + case JVM_CONSTANT_MethodType: 2.176 + { 2.177 + int ref_i = scratch_cp->method_type_index_at(scratch_i); 2.178 + int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, 2.179 + merge_cp_length_p, THREAD); 2.180 + if (new_ref_i != ref_i) { 2.181 + RC_TRACE(0x00080000, 2.182 + ("MethodType entry@%d ref_index change: %d to %d", 2.183 + *merge_cp_length_p, ref_i, new_ref_i)); 2.184 + } 2.185 + (*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i); 2.186 + if (scratch_i != *merge_cp_length_p) { 2.187 + // The new entry in *merge_cp_p is at a different index than 2.188 + // the new entry in scratch_cp so we need to map the index values. 2.189 + map_index(scratch_cp, scratch_i, *merge_cp_length_p); 2.190 + } 2.191 + (*merge_cp_length_p)++; 2.192 + } break; 2.193 + 2.194 + // this is an indirect CP entry so it needs special handling 2.195 + case JVM_CONSTANT_MethodHandle: 2.196 + { 2.197 + int ref_kind = scratch_cp->method_handle_ref_kind_at(scratch_i); 2.198 + int ref_i = scratch_cp->method_handle_index_at(scratch_i); 2.199 + int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, 2.200 + merge_cp_length_p, THREAD); 2.201 + if (new_ref_i != ref_i) { 2.202 + RC_TRACE(0x00080000, 2.203 + ("MethodHandle entry@%d ref_index change: %d to %d", 2.204 + *merge_cp_length_p, ref_i, new_ref_i)); 2.205 + } 2.206 + (*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i); 2.207 + if (scratch_i != *merge_cp_length_p) { 2.208 + // The new entry in *merge_cp_p is at a different index than 2.209 + // the new entry in scratch_cp so we need to map the index values. 2.210 + map_index(scratch_cp, scratch_i, *merge_cp_length_p); 2.211 + } 2.212 + (*merge_cp_length_p)++; 2.213 + } break; 2.214 + 2.215 + // this is an indirect CP entry so it needs special handling 2.216 + case JVM_CONSTANT_InvokeDynamic: 2.217 + { 2.218 + // TBD: cross-checks and possible extra appends into CP and bsm operands 2.219 + // are needed as well. This issue is tracked by a separate bug 8007037. 2.220 + int bss_idx = scratch_cp->invoke_dynamic_bootstrap_specifier_index(scratch_i); 2.221 + 2.222 + int ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i); 2.223 + int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, 2.224 + merge_cp_length_p, THREAD); 2.225 + if (new_ref_i != ref_i) { 2.226 + RC_TRACE(0x00080000, 2.227 + ("InvokeDynamic entry@%d name_and_type ref_index change: %d to %d", 2.228 + *merge_cp_length_p, ref_i, new_ref_i)); 2.229 + } 2.230 + 2.231 + (*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, bss_idx, new_ref_i); 2.232 + if (scratch_i != *merge_cp_length_p) { 2.233 + // The new entry in *merge_cp_p is at a different index than 2.234 + // the new entry in scratch_cp so we need to map the index values. 2.235 + map_index(scratch_cp, scratch_i, *merge_cp_length_p); 2.236 + } 2.237 + (*merge_cp_length_p)++; 2.238 + } break; 2.239 + 2.240 // At this stage, Class or UnresolvedClass could be here, but not 2.241 // ClassIndex 2.242 case JVM_CONSTANT_ClassIndex: // fall through 2.243 @@ -507,6 +456,35 @@ 2.244 } // end append_entry() 2.245 2.246 2.247 +int VM_RedefineClasses::find_or_append_indirect_entry(constantPoolHandle scratch_cp, 2.248 + int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) { 2.249 + 2.250 + int new_ref_i = ref_i; 2.251 + bool match = (ref_i < *merge_cp_length_p) && 2.252 + scratch_cp->compare_entry_to(ref_i, *merge_cp_p, ref_i, THREAD); 2.253 + 2.254 + if (!match) { 2.255 + // forward reference in *merge_cp_p or not a direct match 2.256 + int found_i = scratch_cp->find_matching_entry(ref_i, *merge_cp_p, THREAD); 2.257 + if (found_i != 0) { 2.258 + guarantee(found_i != ref_i, "compare_entry_to() and find_matching_entry() do not agree"); 2.259 + // Found a matching entry somewhere else in *merge_cp_p so just need a mapping entry. 2.260 + new_ref_i = found_i; 2.261 + map_index(scratch_cp, ref_i, found_i); 2.262 + } else { 2.263 + // no match found so we have to append this entry to *merge_cp_p 2.264 + append_entry(scratch_cp, ref_i, merge_cp_p, merge_cp_length_p, THREAD); 2.265 + // The above call to append_entry() can only append one entry 2.266 + // so the post call query of *merge_cp_length_p is only for 2.267 + // the sake of consistency. 2.268 + new_ref_i = *merge_cp_length_p - 1; 2.269 + } 2.270 + } 2.271 + 2.272 + return new_ref_i; 2.273 +} // end find_or_append_indirect_entry() 2.274 + 2.275 + 2.276 void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS) { 2.277 AnnotationArray* save; 2.278 2.279 @@ -1564,6 +1542,7 @@ 2.280 case Bytecodes::_getfield : // fall through 2.281 case Bytecodes::_getstatic : // fall through 2.282 case Bytecodes::_instanceof : // fall through 2.283 + case Bytecodes::_invokedynamic : // fall through 2.284 case Bytecodes::_invokeinterface: // fall through 2.285 case Bytecodes::_invokespecial : // fall through 2.286 case Bytecodes::_invokestatic : // fall through
3.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Feb 01 13:30:12 2013 -0500 3.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Feb 01 14:42:43 2013 -0800 3.3 @@ -421,10 +421,11 @@ 3.4 // and in all direct and indirect subclasses. 3.5 void increment_class_counter(InstanceKlass *ik, TRAPS); 3.6 3.7 - // Support for constant pool merging (these routines are in alpha 3.8 - // order): 3.9 + // Support for constant pool merging (these routines are in alpha order): 3.10 void append_entry(constantPoolHandle scratch_cp, int scratch_i, 3.11 constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS); 3.12 + int find_or_append_indirect_entry(constantPoolHandle scratch_cp, int scratch_i, 3.13 + constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS); 3.14 int find_new_index(int old_index); 3.15 bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1, 3.16 constantPoolHandle cp2, int index2);