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