Mercurial > hg > graal-jvmci-8
comparison src/share/vm/oops/constantPool.cpp @ 12946:b8860472c377
8014910: deadlock between JVM/TI ClassPrepare event handler and CompilerThread
Summary: Revert changes in JDK-8008962
Reviewed-by: coleenp, sspitsyn
author | iklam |
---|---|
date | Tue, 22 Oct 2013 14:29:02 -0700 |
parents | 28ca974cc21a |
children | 096c224171c4 febc6428bc79 10c9507f544a |
comparison
equal
deleted
inserted
replaced
12944:1327b7f85503 | 12946:b8860472c377 |
---|---|
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" | |
44 #include "runtime/vframe.hpp" | 43 #include "runtime/vframe.hpp" |
45 | 44 |
46 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) { | 45 ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) { |
47 // Tags are RW but comment below applies to tags also. | 46 // Tags are RW but comment below applies to tags also. |
48 Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL); | 47 Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL); |
68 set_pool_holder(NULL); | 67 set_pool_holder(NULL); |
69 set_flags(0); | 68 set_flags(0); |
70 | 69 |
71 // only set to non-zero if constant pool is merged by RedefineClasses | 70 // only set to non-zero if constant pool is merged by RedefineClasses |
72 set_version(0); | 71 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); | |
98 } | 101 } |
99 | 102 |
100 objArrayOop ConstantPool::resolved_references() const { | 103 objArrayOop ConstantPool::resolved_references() const { |
101 return (objArrayOop)JNIHandles::resolve(_resolved_references); | 104 return (objArrayOop)JNIHandles::resolve(_resolved_references); |
102 } | 105 } |
149 Handle refs_handle (THREAD, (oop)stom); // must handleize. | 152 Handle refs_handle (THREAD, (oop)stom); // must handleize. |
150 | 153 |
151 ClassLoaderData* loader_data = pool_holder()->class_loader_data(); | 154 ClassLoaderData* loader_data = pool_holder()->class_loader_data(); |
152 set_resolved_references(loader_data->add_handle(refs_handle)); | 155 set_resolved_references(loader_data->add_handle(refs_handle)); |
153 } | 156 } |
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")); | |
154 } | 160 } |
155 } | 161 } |
156 | 162 |
157 void ConstantPool::remove_unshareable_info() { | 163 void ConstantPool::remove_unshareable_info() { |
158 // Resolved references are not in the shared archive. | 164 // Resolved references are not in the shared archive. |
159 // Save the length for restoration. It is not necessarily the same length | 165 // Save the length for restoration. It is not necessarily the same length |
160 // as reference_map.length() if invokedynamic is saved. | 166 // as reference_map.length() if invokedynamic is saved. |
161 set_resolved_reference_length( | 167 set_resolved_reference_length( |
162 resolved_references() != NULL ? resolved_references()->length() : 0); | 168 resolved_references() != NULL ? resolved_references()->length() : 0); |
163 set_resolved_references(NULL); | 169 set_resolved_references(NULL); |
164 } | 170 set_lock(NULL); |
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 } | |
181 } | 171 } |
182 | 172 |
183 int ConstantPool::cp_to_object_index(int cp_index) { | 173 int ConstantPool::cp_to_object_index(int cp_index) { |
184 // this is harder don't do this so much. | 174 // this is harder don't do this so much. |
185 int i = reference_map()->find(cp_index); | 175 int i = reference_map()->find(cp_index); |
209 // until the loader_data is registered. | 199 // until the loader_data is registered. |
210 Handle mirror_handle; | 200 Handle mirror_handle; |
211 | 201 |
212 Symbol* name = NULL; | 202 Symbol* name = NULL; |
213 Handle loader; | 203 Handle loader; |
214 { | 204 { MonitorLockerEx ml(this_oop->lock()); |
215 oop cplock = this_oop->lock(); | |
216 ObjectLocker ol(cplock , THREAD, cplock != NULL); | |
217 | 205 |
218 if (this_oop->tag_at(which).is_unresolved_klass()) { | 206 if (this_oop->tag_at(which).is_unresolved_klass()) { |
219 if (this_oop->tag_at(which).is_unresolved_klass_in_error()) { | 207 if (this_oop->tag_at(which).is_unresolved_klass_in_error()) { |
220 in_error = true; | 208 in_error = true; |
221 } else { | 209 } else { |
258 ResourceMark rm; | 246 ResourceMark rm; |
259 Symbol* error = PENDING_EXCEPTION->klass()->name(); | 247 Symbol* error = PENDING_EXCEPTION->klass()->name(); |
260 | 248 |
261 bool throw_orig_error = false; | 249 bool throw_orig_error = false; |
262 { | 250 { |
263 oop cplock = this_oop->lock(); | 251 MonitorLockerEx ml(this_oop->lock()); |
264 ObjectLocker ol(cplock, THREAD, cplock != NULL); | |
265 | 252 |
266 // some other thread has beaten us and has resolved the class. | 253 // some other thread has beaten us and has resolved the class. |
267 if (this_oop->tag_at(which).is_klass()) { | 254 if (this_oop->tag_at(which).is_klass()) { |
268 CLEAR_PENDING_EXCEPTION; | 255 CLEAR_PENDING_EXCEPTION; |
269 entry = this_oop->resolved_klass_at(which); | 256 entry = this_oop->resolved_klass_at(which); |
327 InstanceKlass::cast(k())->external_name()); | 314 InstanceKlass::cast(k())->external_name()); |
328 } | 315 } |
329 } | 316 } |
330 return k(); | 317 return k(); |
331 } else { | 318 } else { |
332 oop cplock = this_oop->lock(); | 319 MonitorLockerEx ml(this_oop->lock()); |
333 ObjectLocker ol(cplock, THREAD, cplock != NULL); | |
334 // Only updated constant pool - if it is resolved. | 320 // Only updated constant pool - if it is resolved. |
335 do_resolve = this_oop->tag_at(which).is_unresolved_klass(); | 321 do_resolve = this_oop->tag_at(which).is_unresolved_klass(); |
336 if (do_resolve) { | 322 if (do_resolve) { |
337 ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data(); | 323 ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data(); |
338 this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM | 324 this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM |
598 // in the resolution error table, so that the same exception is thrown again. | 584 // in the resolution error table, so that the same exception is thrown again. |
599 void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which, | 585 void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which, |
600 int tag, TRAPS) { | 586 int tag, TRAPS) { |
601 ResourceMark rm; | 587 ResourceMark rm; |
602 Symbol* error = PENDING_EXCEPTION->klass()->name(); | 588 Symbol* error = PENDING_EXCEPTION->klass()->name(); |
603 oop cplock = this_oop->lock(); | 589 MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. |
604 ObjectLocker ol(cplock, THREAD, cplock != NULL); // lock cpool to change tag. | |
605 | 590 |
606 int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? | 591 int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? |
607 JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; | 592 JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; |
608 | 593 |
609 if (!PENDING_EXCEPTION-> | 594 if (!PENDING_EXCEPTION-> |
760 } | 745 } |
761 | 746 |
762 if (cache_index >= 0) { | 747 if (cache_index >= 0) { |
763 // Cache the oop here also. | 748 // Cache the oop here also. |
764 Handle result_handle(THREAD, result_oop); | 749 Handle result_handle(THREAD, result_oop); |
765 oop cplock = this_oop->lock(); | 750 MonitorLockerEx ml(this_oop->lock()); // don't know if we really need this |
766 ObjectLocker ol(cplock, THREAD, cplock != NULL); // don't know if we really need this | |
767 oop result = this_oop->resolved_references()->obj_at(cache_index); | 751 oop result = this_oop->resolved_references()->obj_at(cache_index); |
768 // Benign race condition: resolved_references may already be filled in while we were trying to lock. | 752 // Benign race condition: resolved_references may already be filled in while we were trying to lock. |
769 // The important thing here is that all threads pick up the same result. | 753 // The important thing here is that all threads pick up the same result. |
770 // It doesn't matter which racing thread wins, as long as only one | 754 // It doesn't matter which racing thread wins, as long as only one |
771 // result is used by all threads, and all future queries. | 755 // result is used by all threads, and all future queries. |