241 method()->size_of_parameters()); |
241 method()->size_of_parameters()); |
242 set_bytecode_1(Bytecodes::_invokeinterface); |
242 set_bytecode_1(Bytecodes::_invokeinterface); |
243 } |
243 } |
244 |
244 |
245 |
245 |
246 void ConstantPoolCacheEntry::set_method_handle(methodHandle adapter, Handle appendix, |
246 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, |
|
247 methodHandle adapter, Handle appendix, |
247 objArrayHandle resolved_references) { |
248 objArrayHandle resolved_references) { |
248 set_method_handle_common(Bytecodes::_invokehandle, adapter, appendix, resolved_references); |
249 set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, resolved_references); |
249 } |
250 } |
250 |
251 |
251 void ConstantPoolCacheEntry::set_dynamic_call(methodHandle adapter, Handle appendix, |
252 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, |
|
253 methodHandle adapter, Handle appendix, |
252 objArrayHandle resolved_references) { |
254 objArrayHandle resolved_references) { |
253 set_method_handle_common(Bytecodes::_invokedynamic, adapter, appendix, resolved_references); |
255 set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, resolved_references); |
254 } |
256 } |
255 |
257 |
256 void ConstantPoolCacheEntry::set_method_handle_common(Bytecodes::Code invoke_code, |
258 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool, |
|
259 Bytecodes::Code invoke_code, |
257 methodHandle adapter, |
260 methodHandle adapter, |
258 Handle appendix, |
261 Handle appendix, |
259 objArrayHandle resolved_references) { |
262 objArrayHandle resolved_references) { |
260 // NOTE: This CPCE can be the subject of data races. |
263 // NOTE: This CPCE can be the subject of data races. |
261 // There are three words to update: flags, refs[f2], f1 (in that order). |
264 // There are three words to update: flags, refs[f2], f1 (in that order). |
262 // Writers must store all other values before f1. |
265 // Writers must store all other values before f1. |
263 // Readers must test f1 first for non-null before reading other fields. |
266 // Readers must test f1 first for non-null before reading other fields. |
264 // Competing writers must acquire exclusive access on the first |
267 // Competing writers must acquire exclusive access via a lock. |
265 // write, to flags, using a compare/exchange. |
268 // A losing writer waits on the lock until the winner writes f1 and leaves |
266 // A losing writer to flags must spin until the winner writes f1, |
269 // the lock, so that when the losing writer returns, he can use the linked |
267 // so that when he returns, he can use the linked cache entry. |
270 // cache entry. |
|
271 |
|
272 MonitorLockerEx ml(cpool->lock()); |
|
273 if (!is_f1_null()) { |
|
274 return; |
|
275 } |
268 |
276 |
269 bool has_appendix = appendix.not_null(); |
277 bool has_appendix = appendix.not_null(); |
270 |
278 |
271 // Write the flags. |
279 // Write the flags. |
272 bool owner = |
280 set_method_flags(as_TosState(adapter->result_type()), |
273 init_method_flags_atomic(as_TosState(adapter->result_type()), |
|
274 ((has_appendix ? 1 : 0) << has_appendix_shift) | |
281 ((has_appendix ? 1 : 0) << has_appendix_shift) | |
275 ( 1 << is_final_shift), |
282 ( 1 << is_final_shift), |
276 adapter->size_of_parameters()); |
283 adapter->size_of_parameters()); |
277 if (!owner) { |
|
278 // Somebody else is working on the same CPCE. Let them proceed. |
|
279 while (is_f1_null()) { |
|
280 // Pause momentarily on a low-level lock, to allow racing thread to win. |
|
281 MutexLockerEx mu(Patching_lock, Mutex::_no_safepoint_check_flag); |
|
282 os::yield(); |
|
283 } |
|
284 return; |
|
285 } |
|
286 |
284 |
287 if (TraceInvokeDynamic) { |
285 if (TraceInvokeDynamic) { |
288 tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method="PTR_FORMAT" ", |
286 tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method="PTR_FORMAT" ", |
289 invoke_code, |
287 invoke_code, |
290 (intptr_t)appendix(), (has_appendix ? "" : " (unused)"), |
288 (intptr_t)appendix(), (has_appendix ? "" : " (unused)"), |