Mercurial > hg > graal-jvmci-8
comparison src/share/vm/oops/constantPool.cpp @ 10151:15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
Summary: References from operands to CP entries and back must be correct after CP merge
Reviewed-by: coleenp, twisti
Contributed-by: serguei.spitsyn@oracle.com
author | sspitsyn |
---|---|
date | Thu, 25 Apr 2013 03:58:53 -0700 |
parents | cc32ccaaf47f |
children | c115fac239eb |
comparison
equal
deleted
inserted
replaced
10150:d66a24adbe3f | 10151:15a99ca4ee34 |
---|---|
1041 } | 1041 } |
1042 } break; | 1042 } break; |
1043 | 1043 |
1044 case JVM_CONSTANT_InvokeDynamic: | 1044 case JVM_CONSTANT_InvokeDynamic: |
1045 { | 1045 { |
1046 int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1); | 1046 int k1 = invoke_dynamic_name_and_type_ref_index_at(index1); |
1047 int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2); | 1047 int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); |
1048 bool match = compare_entry_to(k1, cp2, k2, CHECK_false); | 1048 int i1 = invoke_dynamic_bootstrap_specifier_index(index1); |
1049 if (!match) return false; | 1049 int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2); |
1050 k1 = invoke_dynamic_name_and_type_ref_index_at(index1); | 1050 bool match = compare_entry_to(k1, cp2, k2, CHECK_false) && |
1051 k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); | 1051 compare_operand_to(i1, cp2, i2, CHECK_false); |
1052 match = compare_entry_to(k1, cp2, k2, CHECK_false); | 1052 return match; |
1053 if (!match) return false; | |
1054 int argc = invoke_dynamic_argument_count_at(index1); | |
1055 if (argc == cp2->invoke_dynamic_argument_count_at(index2)) { | |
1056 for (int j = 0; j < argc; j++) { | |
1057 k1 = invoke_dynamic_argument_index_at(index1, j); | |
1058 k2 = cp2->invoke_dynamic_argument_index_at(index2, j); | |
1059 match = compare_entry_to(k1, cp2, k2, CHECK_false); | |
1060 if (!match) return false; | |
1061 } | |
1062 return true; // got through loop; all elements equal | |
1063 } | |
1064 } break; | 1053 } break; |
1065 | 1054 |
1066 case JVM_CONSTANT_String: | 1055 case JVM_CONSTANT_String: |
1067 { | 1056 { |
1068 Symbol* s1 = unresolved_string_at(index1); | 1057 Symbol* s1 = unresolved_string_at(index1); |
1091 break; | 1080 break; |
1092 } | 1081 } |
1093 | 1082 |
1094 return false; | 1083 return false; |
1095 } // end compare_entry_to() | 1084 } // end compare_entry_to() |
1085 | |
1086 | |
1087 // Resize the operands array with delta_len and delta_size. | |
1088 // Used in RedefineClasses for CP merge. | |
1089 void ConstantPool::resize_operands(int delta_len, int delta_size, TRAPS) { | |
1090 int old_len = operand_array_length(operands()); | |
1091 int new_len = old_len + delta_len; | |
1092 int min_len = (delta_len > 0) ? old_len : new_len; | |
1093 | |
1094 int old_size = operands()->length(); | |
1095 int new_size = old_size + delta_size; | |
1096 int min_size = (delta_size > 0) ? old_size : new_size; | |
1097 | |
1098 ClassLoaderData* loader_data = pool_holder()->class_loader_data(); | |
1099 Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, new_size, CHECK); | |
1100 | |
1101 // Set index in the resized array for existing elements only | |
1102 for (int idx = 0; idx < min_len; idx++) { | |
1103 int offset = operand_offset_at(idx); // offset in original array | |
1104 operand_offset_at_put(new_ops, idx, offset + 2*delta_len); // offset in resized array | |
1105 } | |
1106 // Copy the bootstrap specifiers only | |
1107 Copy::conjoint_memory_atomic(operands()->adr_at(2*old_len), | |
1108 new_ops->adr_at(2*new_len), | |
1109 (min_size - 2*min_len) * sizeof(u2)); | |
1110 // Explicitly deallocate old operands array. | |
1111 // Note, it is not needed for 7u backport. | |
1112 if ( operands() != NULL) { // the safety check | |
1113 MetadataFactory::free_array<u2>(loader_data, operands()); | |
1114 } | |
1115 set_operands(new_ops); | |
1116 } // end resize_operands() | |
1117 | |
1118 | |
1119 // Extend the operands array with the length and size of the ext_cp operands. | |
1120 // Used in RedefineClasses for CP merge. | |
1121 void ConstantPool::extend_operands(constantPoolHandle ext_cp, TRAPS) { | |
1122 int delta_len = operand_array_length(ext_cp->operands()); | |
1123 if (delta_len == 0) { | |
1124 return; // nothing to do | |
1125 } | |
1126 int delta_size = ext_cp->operands()->length(); | |
1127 | |
1128 assert(delta_len > 0 && delta_size > 0, "extended operands array must be bigger"); | |
1129 | |
1130 if (operand_array_length(operands()) == 0) { | |
1131 ClassLoaderData* loader_data = pool_holder()->class_loader_data(); | |
1132 Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, delta_size, CHECK); | |
1133 // The first element index defines the offset of second part | |
1134 operand_offset_at_put(new_ops, 0, 2*delta_len); // offset in new array | |
1135 set_operands(new_ops); | |
1136 } else { | |
1137 resize_operands(delta_len, delta_size, CHECK); | |
1138 } | |
1139 | |
1140 } // end extend_operands() | |
1141 | |
1142 | |
1143 // Shrink the operands array to a smaller array with new_len length. | |
1144 // Used in RedefineClasses for CP merge. | |
1145 void ConstantPool::shrink_operands(int new_len, TRAPS) { | |
1146 int old_len = operand_array_length(operands()); | |
1147 if (new_len == old_len) { | |
1148 return; // nothing to do | |
1149 } | |
1150 assert(new_len < old_len, "shrunken operands array must be smaller"); | |
1151 | |
1152 int free_base = operand_next_offset_at(new_len - 1); | |
1153 int delta_len = new_len - old_len; | |
1154 int delta_size = 2*delta_len + free_base - operands()->length(); | |
1155 | |
1156 resize_operands(delta_len, delta_size, CHECK); | |
1157 | |
1158 } // end shrink_operands() | |
1096 | 1159 |
1097 | 1160 |
1098 void ConstantPool::copy_operands(constantPoolHandle from_cp, | 1161 void ConstantPool::copy_operands(constantPoolHandle from_cp, |
1099 constantPoolHandle to_cp, | 1162 constantPoolHandle to_cp, |
1100 TRAPS) { | 1163 TRAPS) { |
1355 | 1418 |
1356 return 0; // entry not found; return unused index zero (0) | 1419 return 0; // entry not found; return unused index zero (0) |
1357 } // end find_matching_entry() | 1420 } // end find_matching_entry() |
1358 | 1421 |
1359 | 1422 |
1423 // Compare this constant pool's bootstrap specifier at idx1 to the constant pool | |
1424 // cp2's bootstrap specifier at idx2. | |
1425 bool ConstantPool::compare_operand_to(int idx1, constantPoolHandle cp2, int idx2, TRAPS) { | |
1426 int k1 = operand_bootstrap_method_ref_index_at(idx1); | |
1427 int k2 = cp2->operand_bootstrap_method_ref_index_at(idx2); | |
1428 bool match = compare_entry_to(k1, cp2, k2, CHECK_false); | |
1429 | |
1430 if (!match) { | |
1431 return false; | |
1432 } | |
1433 int argc = operand_argument_count_at(idx1); | |
1434 if (argc == cp2->operand_argument_count_at(idx2)) { | |
1435 for (int j = 0; j < argc; j++) { | |
1436 k1 = operand_argument_index_at(idx1, j); | |
1437 k2 = cp2->operand_argument_index_at(idx2, j); | |
1438 match = compare_entry_to(k1, cp2, k2, CHECK_false); | |
1439 if (!match) { | |
1440 return false; | |
1441 } | |
1442 } | |
1443 return true; // got through loop; all elements equal | |
1444 } | |
1445 return false; | |
1446 } // end compare_operand_to() | |
1447 | |
1448 // Search constant pool search_cp for a bootstrap specifier that matches | |
1449 // this constant pool's bootstrap specifier at pattern_i index. | |
1450 // Return the index of a matching bootstrap specifier or (-1) if there is no match. | |
1451 int ConstantPool::find_matching_operand(int pattern_i, | |
1452 constantPoolHandle search_cp, int search_len, TRAPS) { | |
1453 for (int i = 0; i < search_len; i++) { | |
1454 bool found = compare_operand_to(pattern_i, search_cp, i, CHECK_(-1)); | |
1455 if (found) { | |
1456 return i; | |
1457 } | |
1458 } | |
1459 return -1; // bootstrap specifier not found; return unused index (-1) | |
1460 } // end find_matching_operand() | |
1461 | |
1462 | |
1360 #ifndef PRODUCT | 1463 #ifndef PRODUCT |
1361 | 1464 |
1362 const char* ConstantPool::printable_name_at(int which) { | 1465 const char* ConstantPool::printable_name_at(int which) { |
1363 | 1466 |
1364 constantTag tag = tag_at(which); | 1467 constantTag tag = tag_at(which); |