249 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, const CallInfo &call_info) {
250 set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
251 }
252
253 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, const CallInfo &call_info) {
254 set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
255 }
256
257 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
258 Bytecodes::Code invoke_code,
259 const CallInfo &call_info) {
260 // NOTE: This CPCE can be the subject of data races.
261 // There are three words to update: flags, refs[f2], f1 (in that order).
262 // Writers must store all other values before f1.
263 // Readers must test f1 first for non-null before reading other fields.
264 // Competing writers must acquire exclusive access via a lock.
265 // A losing writer waits on the lock until the winner writes f1 and leaves
266 // the lock, so that when the losing writer returns, he can use the linked
267 // cache entry.
268
269 MonitorLockerEx ml(cpool->lock());
270 if (!is_f1_null()) {
271 return;
272 }
273
274 const methodHandle adapter = call_info.resolved_method();
275 const Handle appendix = call_info.resolved_appendix();
276 const Handle method_type = call_info.resolved_method_type();
277 const bool has_appendix = appendix.not_null();
278 const bool has_method_type = method_type.not_null();
279
280 // Write the flags.
281 set_method_flags(as_TosState(adapter->result_type()),
282 ((has_appendix ? 1 : 0) << has_appendix_shift ) |
283 ((has_method_type ? 1 : 0) << has_method_type_shift) |
284 ( 1 << is_final_shift ),
285 adapter->size_of_parameters());
286
287 if (TraceInvokeDynamic) {
288 tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
289 invoke_code,
|
249 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, const CallInfo &call_info) {
250 set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
251 }
252
253 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, const CallInfo &call_info) {
254 set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
255 }
256
257 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
258 Bytecodes::Code invoke_code,
259 const CallInfo &call_info) {
260 // NOTE: This CPCE can be the subject of data races.
261 // There are three words to update: flags, refs[f2], f1 (in that order).
262 // Writers must store all other values before f1.
263 // Readers must test f1 first for non-null before reading other fields.
264 // Competing writers must acquire exclusive access via a lock.
265 // A losing writer waits on the lock until the winner writes f1 and leaves
266 // the lock, so that when the losing writer returns, he can use the linked
267 // cache entry.
268
269 oop cplock = cpool->lock();
270 ObjectLocker ol(cplock, Thread::current(), cplock != NULL);
271 if (!is_f1_null()) {
272 return;
273 }
274
275 const methodHandle adapter = call_info.resolved_method();
276 const Handle appendix = call_info.resolved_appendix();
277 const Handle method_type = call_info.resolved_method_type();
278 const bool has_appendix = appendix.not_null();
279 const bool has_method_type = method_type.not_null();
280
281 // Write the flags.
282 set_method_flags(as_TosState(adapter->result_type()),
283 ((has_appendix ? 1 : 0) << has_appendix_shift ) |
284 ((has_method_type ? 1 : 0) << has_method_type_shift) |
285 ( 1 << is_final_shift ),
286 adapter->size_of_parameters());
287
288 if (TraceInvokeDynamic) {
289 tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
290 invoke_code,
|