Mercurial > hg > graal-compiler
comparison src/share/vm/oops/constantPool.cpp @ 10408:836a62f43af9
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 19 Jun 2013 10:45:56 +0200 |
parents | 89e4d67fdd2a a1ebd310d5c1 |
children | 6b0fd0964b87 |
comparison
equal
deleted
inserted
replaced
10086:e0fb8a213650 | 10408:836a62f43af9 |
---|---|
38 #include "oops/objArrayKlass.hpp" | 38 #include "oops/objArrayKlass.hpp" |
39 #include "runtime/fieldType.hpp" | 39 #include "runtime/fieldType.hpp" |
40 #include "runtime/init.hpp" | 40 #include "runtime/init.hpp" |
41 #include "runtime/javaCalls.hpp" | 41 #include "runtime/javaCalls.hpp" |
42 #include "runtime/signature.hpp" | 42 #include "runtime/signature.hpp" |
43 #include "runtime/synchronizer.hpp" | |
43 #include "runtime/vframe.hpp" | 44 #include "runtime/vframe.hpp" |
44 | 45 |
45 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) { | 46 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) { |
46 // Tags are RW but comment below applies to tags also. | 47 // Tags are RW but comment below applies to tags also. |
47 Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL); | 48 Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL); |
52 // Allocate read-write but may be able to move to read-only at dumping time | 53 // Allocate read-write but may be able to move to read-only at dumping time |
53 // if all the klasses are resolved. The only other field that is writable is | 54 // if all the klasses are resolved. The only other field that is writable is |
54 // the resolved_references array, which is recreated at startup time. | 55 // the resolved_references array, which is recreated at startup time. |
55 // But that could be moved to InstanceKlass (although a pain to access from | 56 // But that could be moved to InstanceKlass (although a pain to access from |
56 // assembly code). Maybe it could be moved to the cpCache which is RW. | 57 // assembly code). Maybe it could be moved to the cpCache which is RW. |
57 return new (loader_data, size, false, THREAD) ConstantPool(tags); | 58 return new (loader_data, size, false, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags); |
58 } | 59 } |
59 | 60 |
60 ConstantPool::ConstantPool(Array<u1>* tags) { | 61 ConstantPool::ConstantPool(Array<u1>* tags) { |
61 set_length(tags->length()); | 62 set_length(tags->length()); |
62 set_tags(NULL); | 63 set_tags(NULL); |
67 set_pool_holder(NULL); | 68 set_pool_holder(NULL); |
68 set_flags(0); | 69 set_flags(0); |
69 | 70 |
70 // only set to non-zero if constant pool is merged by RedefineClasses | 71 // only set to non-zero if constant pool is merged by RedefineClasses |
71 set_version(0); | 72 set_version(0); |
72 set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock")); | |
73 | 73 |
74 // initialize tag array | 74 // initialize tag array |
75 int length = tags->length(); | 75 int length = tags->length(); |
76 for (int index = 0; index < length; index++) { | 76 for (int index = 0; index < length; index++) { |
77 tags->at_put(index, JVM_CONSTANT_Invalid); | 77 tags->at_put(index, JVM_CONSTANT_Invalid); |
93 } | 93 } |
94 | 94 |
95 void ConstantPool::release_C_heap_structures() { | 95 void ConstantPool::release_C_heap_structures() { |
96 // walk constant pool and decrement symbol reference counts | 96 // walk constant pool and decrement symbol reference counts |
97 unreference_symbols(); | 97 unreference_symbols(); |
98 | |
99 delete _lock; | |
100 set_lock(NULL); | |
101 } | 98 } |
102 | 99 |
103 objArrayOop ConstantPool::resolved_references() const { | 100 objArrayOop ConstantPool::resolved_references() const { |
104 return (objArrayOop)JNIHandles::resolve(_resolved_references); | 101 return (objArrayOop)JNIHandles::resolve(_resolved_references); |
105 } | 102 } |
152 Handle refs_handle (THREAD, (oop)stom); // must handleize. | 149 Handle refs_handle (THREAD, (oop)stom); // must handleize. |
153 | 150 |
154 ClassLoaderData* loader_data = pool_holder()->class_loader_data(); | 151 ClassLoaderData* loader_data = pool_holder()->class_loader_data(); |
155 set_resolved_references(loader_data->add_handle(refs_handle)); | 152 set_resolved_references(loader_data->add_handle(refs_handle)); |
156 } | 153 } |
157 | |
158 // Also need to recreate the mutex. Make sure this matches the constructor | |
159 set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock")); | |
160 } | 154 } |
161 } | 155 } |
162 | 156 |
163 void ConstantPool::remove_unshareable_info() { | 157 void ConstantPool::remove_unshareable_info() { |
164 // Resolved references are not in the shared archive. | 158 // Resolved references are not in the shared archive. |
165 // Save the length for restoration. It is not necessarily the same length | 159 // Save the length for restoration. It is not necessarily the same length |
166 // as reference_map.length() if invokedynamic is saved. | 160 // as reference_map.length() if invokedynamic is saved. |
167 set_resolved_reference_length( | 161 set_resolved_reference_length( |
168 resolved_references() != NULL ? resolved_references()->length() : 0); | 162 resolved_references() != NULL ? resolved_references()->length() : 0); |
169 set_resolved_references(NULL); | 163 set_resolved_references(NULL); |
170 set_lock(NULL); | 164 } |
165 | |
166 oop ConstantPool::lock() { | |
167 if (_pool_holder) { | |
168 // We re-use the _pool_holder's init_lock to reduce footprint. | |
169 // Notes on deadlocks: | |
170 // [1] This lock is a Java oop, so it can be recursively locked by | |
171 // the same thread without self-deadlocks. | |
172 // [2] Deadlock will happen if there is circular dependency between | |
173 // the <clinit> of two Java classes. However, in this case, | |
174 // the deadlock would have happened long before we reach | |
175 // ConstantPool::lock(), so reusing init_lock does not | |
176 // increase the possibility of deadlock. | |
177 return _pool_holder->init_lock(); | |
178 } else { | |
179 return NULL; | |
180 } | |
171 } | 181 } |
172 | 182 |
173 int ConstantPool::cp_to_object_index(int cp_index) { | 183 int ConstantPool::cp_to_object_index(int cp_index) { |
174 // this is harder don't do this so much. | 184 // this is harder don't do this so much. |
175 for (int i = 0; i< reference_map()->length(); i++) { | 185 for (int i = 0; i< reference_map()->length(); i++) { |
206 // until the loader_data is registered. | 216 // until the loader_data is registered. |
207 Handle mirror_handle; | 217 Handle mirror_handle; |
208 | 218 |
209 Symbol* name = NULL; | 219 Symbol* name = NULL; |
210 Handle loader; | 220 Handle loader; |
211 { MonitorLockerEx ml(this_oop->lock()); | 221 { |
222 oop cplock = this_oop->lock(); | |
223 ObjectLocker ol(cplock , THREAD, cplock != NULL); | |
212 | 224 |
213 if (this_oop->tag_at(which).is_unresolved_klass()) { | 225 if (this_oop->tag_at(which).is_unresolved_klass()) { |
214 if (this_oop->tag_at(which).is_unresolved_klass_in_error()) { | 226 if (this_oop->tag_at(which).is_unresolved_klass_in_error()) { |
215 in_error = true; | 227 in_error = true; |
216 } else { | 228 } else { |
253 ResourceMark rm; | 265 ResourceMark rm; |
254 Symbol* error = PENDING_EXCEPTION->klass()->name(); | 266 Symbol* error = PENDING_EXCEPTION->klass()->name(); |
255 | 267 |
256 bool throw_orig_error = false; | 268 bool throw_orig_error = false; |
257 { | 269 { |
258 MonitorLockerEx ml(this_oop->lock()); | 270 oop cplock = this_oop->lock(); |
271 ObjectLocker ol(cplock, THREAD, cplock != NULL); | |
259 | 272 |
260 // some other thread has beaten us and has resolved the class. | 273 // some other thread has beaten us and has resolved the class. |
261 if (this_oop->tag_at(which).is_klass()) { | 274 if (this_oop->tag_at(which).is_klass()) { |
262 CLEAR_PENDING_EXCEPTION; | 275 CLEAR_PENDING_EXCEPTION; |
263 entry = this_oop->resolved_klass_at(which); | 276 entry = this_oop->resolved_klass_at(which); |
321 InstanceKlass::cast(k())->external_name()); | 334 InstanceKlass::cast(k())->external_name()); |
322 } | 335 } |
323 } | 336 } |
324 return k(); | 337 return k(); |
325 } else { | 338 } else { |
326 MonitorLockerEx ml(this_oop->lock()); | 339 oop cplock = this_oop->lock(); |
340 ObjectLocker ol(cplock, THREAD, cplock != NULL); | |
327 // Only updated constant pool - if it is resolved. | 341 // Only updated constant pool - if it is resolved. |
328 do_resolve = this_oop->tag_at(which).is_unresolved_klass(); | 342 do_resolve = this_oop->tag_at(which).is_unresolved_klass(); |
329 if (do_resolve) { | 343 if (do_resolve) { |
330 ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data(); | 344 ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data(); |
331 this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM | 345 this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM |
617 // in the resolution error table, so that the same exception is thrown again. | 631 // in the resolution error table, so that the same exception is thrown again. |
618 void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which, | 632 void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which, |
619 int tag, TRAPS) { | 633 int tag, TRAPS) { |
620 ResourceMark rm; | 634 ResourceMark rm; |
621 Symbol* error = PENDING_EXCEPTION->klass()->name(); | 635 Symbol* error = PENDING_EXCEPTION->klass()->name(); |
622 MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. | 636 oop cplock = this_oop->lock(); |
637 ObjectLocker ol(cplock, THREAD, cplock != NULL); // lock cpool to change tag. | |
623 | 638 |
624 int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? | 639 int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? |
625 JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; | 640 JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; |
626 | 641 |
627 if (!PENDING_EXCEPTION-> | 642 if (!PENDING_EXCEPTION-> |
778 } | 793 } |
779 | 794 |
780 if (cache_index >= 0) { | 795 if (cache_index >= 0) { |
781 // Cache the oop here also. | 796 // Cache the oop here also. |
782 Handle result_handle(THREAD, result_oop); | 797 Handle result_handle(THREAD, result_oop); |
783 MonitorLockerEx ml(this_oop->lock()); // don't know if we really need this | 798 oop cplock = this_oop->lock(); |
799 ObjectLocker ol(cplock, THREAD, cplock != NULL); // don't know if we really need this | |
784 oop result = this_oop->resolved_references()->obj_at(cache_index); | 800 oop result = this_oop->resolved_references()->obj_at(cache_index); |
785 // Benign race condition: resolved_references may already be filled in while we were trying to lock. | 801 // Benign race condition: resolved_references may already be filled in while we were trying to lock. |
786 // The important thing here is that all threads pick up the same result. | 802 // The important thing here is that all threads pick up the same result. |
787 // It doesn't matter which racing thread wins, as long as only one | 803 // It doesn't matter which racing thread wins, as long as only one |
788 // result is used by all threads, and all future queries. | 804 // result is used by all threads, and all future queries. |
1041 } | 1057 } |
1042 } break; | 1058 } break; |
1043 | 1059 |
1044 case JVM_CONSTANT_InvokeDynamic: | 1060 case JVM_CONSTANT_InvokeDynamic: |
1045 { | 1061 { |
1046 int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1); | 1062 int k1 = invoke_dynamic_name_and_type_ref_index_at(index1); |
1047 int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2); | 1063 int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); |
1048 bool match = compare_entry_to(k1, cp2, k2, CHECK_false); | 1064 int i1 = invoke_dynamic_bootstrap_specifier_index(index1); |
1049 if (!match) return false; | 1065 int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2); |
1050 k1 = invoke_dynamic_name_and_type_ref_index_at(index1); | 1066 // separate statements and variables because CHECK_false is used |
1051 k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); | 1067 bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false); |
1052 match = compare_entry_to(k1, cp2, k2, CHECK_false); | 1068 bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false); |
1053 if (!match) return false; | 1069 return (match_entry && match_operand); |
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; | 1070 } break; |
1065 | 1071 |
1066 case JVM_CONSTANT_String: | 1072 case JVM_CONSTANT_String: |
1067 { | 1073 { |
1068 Symbol* s1 = unresolved_string_at(index1); | 1074 Symbol* s1 = unresolved_string_at(index1); |
1091 break; | 1097 break; |
1092 } | 1098 } |
1093 | 1099 |
1094 return false; | 1100 return false; |
1095 } // end compare_entry_to() | 1101 } // end compare_entry_to() |
1102 | |
1103 | |
1104 // Resize the operands array with delta_len and delta_size. | |
1105 // Used in RedefineClasses for CP merge. | |
1106 void ConstantPool::resize_operands(int delta_len, int delta_size, TRAPS) { | |
1107 int old_len = operand_array_length(operands()); | |
1108 int new_len = old_len + delta_len; | |
1109 int min_len = (delta_len > 0) ? old_len : new_len; | |
1110 | |
1111 int old_size = operands()->length(); | |
1112 int new_size = old_size + delta_size; | |
1113 int min_size = (delta_size > 0) ? old_size : new_size; | |
1114 | |
1115 ClassLoaderData* loader_data = pool_holder()->class_loader_data(); | |
1116 Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, new_size, CHECK); | |
1117 | |
1118 // Set index in the resized array for existing elements only | |
1119 for (int idx = 0; idx < min_len; idx++) { | |
1120 int offset = operand_offset_at(idx); // offset in original array | |
1121 operand_offset_at_put(new_ops, idx, offset + 2*delta_len); // offset in resized array | |
1122 } | |
1123 // Copy the bootstrap specifiers only | |
1124 Copy::conjoint_memory_atomic(operands()->adr_at(2*old_len), | |
1125 new_ops->adr_at(2*new_len), | |
1126 (min_size - 2*min_len) * sizeof(u2)); | |
1127 // Explicitly deallocate old operands array. | |
1128 // Note, it is not needed for 7u backport. | |
1129 if ( operands() != NULL) { // the safety check | |
1130 MetadataFactory::free_array<u2>(loader_data, operands()); | |
1131 } | |
1132 set_operands(new_ops); | |
1133 } // end resize_operands() | |
1134 | |
1135 | |
1136 // Extend the operands array with the length and size of the ext_cp operands. | |
1137 // Used in RedefineClasses for CP merge. | |
1138 void ConstantPool::extend_operands(constantPoolHandle ext_cp, TRAPS) { | |
1139 int delta_len = operand_array_length(ext_cp->operands()); | |
1140 if (delta_len == 0) { | |
1141 return; // nothing to do | |
1142 } | |
1143 int delta_size = ext_cp->operands()->length(); | |
1144 | |
1145 assert(delta_len > 0 && delta_size > 0, "extended operands array must be bigger"); | |
1146 | |
1147 if (operand_array_length(operands()) == 0) { | |
1148 ClassLoaderData* loader_data = pool_holder()->class_loader_data(); | |
1149 Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, delta_size, CHECK); | |
1150 // The first element index defines the offset of second part | |
1151 operand_offset_at_put(new_ops, 0, 2*delta_len); // offset in new array | |
1152 set_operands(new_ops); | |
1153 } else { | |
1154 resize_operands(delta_len, delta_size, CHECK); | |
1155 } | |
1156 | |
1157 } // end extend_operands() | |
1158 | |
1159 | |
1160 // Shrink the operands array to a smaller array with new_len length. | |
1161 // Used in RedefineClasses for CP merge. | |
1162 void ConstantPool::shrink_operands(int new_len, TRAPS) { | |
1163 int old_len = operand_array_length(operands()); | |
1164 if (new_len == old_len) { | |
1165 return; // nothing to do | |
1166 } | |
1167 assert(new_len < old_len, "shrunken operands array must be smaller"); | |
1168 | |
1169 int free_base = operand_next_offset_at(new_len - 1); | |
1170 int delta_len = new_len - old_len; | |
1171 int delta_size = 2*delta_len + free_base - operands()->length(); | |
1172 | |
1173 resize_operands(delta_len, delta_size, CHECK); | |
1174 | |
1175 } // end shrink_operands() | |
1096 | 1176 |
1097 | 1177 |
1098 void ConstantPool::copy_operands(constantPoolHandle from_cp, | 1178 void ConstantPool::copy_operands(constantPoolHandle from_cp, |
1099 constantPoolHandle to_cp, | 1179 constantPoolHandle to_cp, |
1100 TRAPS) { | 1180 TRAPS) { |
1355 | 1435 |
1356 return 0; // entry not found; return unused index zero (0) | 1436 return 0; // entry not found; return unused index zero (0) |
1357 } // end find_matching_entry() | 1437 } // end find_matching_entry() |
1358 | 1438 |
1359 | 1439 |
1440 // Compare this constant pool's bootstrap specifier at idx1 to the constant pool | |
1441 // cp2's bootstrap specifier at idx2. | |
1442 bool ConstantPool::compare_operand_to(int idx1, constantPoolHandle cp2, int idx2, TRAPS) { | |
1443 int k1 = operand_bootstrap_method_ref_index_at(idx1); | |
1444 int k2 = cp2->operand_bootstrap_method_ref_index_at(idx2); | |
1445 bool match = compare_entry_to(k1, cp2, k2, CHECK_false); | |
1446 | |
1447 if (!match) { | |
1448 return false; | |
1449 } | |
1450 int argc = operand_argument_count_at(idx1); | |
1451 if (argc == cp2->operand_argument_count_at(idx2)) { | |
1452 for (int j = 0; j < argc; j++) { | |
1453 k1 = operand_argument_index_at(idx1, j); | |
1454 k2 = cp2->operand_argument_index_at(idx2, j); | |
1455 match = compare_entry_to(k1, cp2, k2, CHECK_false); | |
1456 if (!match) { | |
1457 return false; | |
1458 } | |
1459 } | |
1460 return true; // got through loop; all elements equal | |
1461 } | |
1462 return false; | |
1463 } // end compare_operand_to() | |
1464 | |
1465 // Search constant pool search_cp for a bootstrap specifier that matches | |
1466 // this constant pool's bootstrap specifier at pattern_i index. | |
1467 // Return the index of a matching bootstrap specifier or (-1) if there is no match. | |
1468 int ConstantPool::find_matching_operand(int pattern_i, | |
1469 constantPoolHandle search_cp, int search_len, TRAPS) { | |
1470 for (int i = 0; i < search_len; i++) { | |
1471 bool found = compare_operand_to(pattern_i, search_cp, i, CHECK_(-1)); | |
1472 if (found) { | |
1473 return i; | |
1474 } | |
1475 } | |
1476 return -1; // bootstrap specifier not found; return unused index (-1) | |
1477 } // end find_matching_operand() | |
1478 | |
1479 | |
1360 #ifndef PRODUCT | 1480 #ifndef PRODUCT |
1361 | 1481 |
1362 const char* ConstantPool::printable_name_at(int which) { | 1482 const char* ConstantPool::printable_name_at(int which) { |
1363 | 1483 |
1364 constantTag tag = tag_at(which); | 1484 constantTag tag = tag_at(which); |