266 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, const CallInfo &call_info) {
267 set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
268 }
269
270 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, const CallInfo &call_info) {
271 set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
272 }
273
274 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
275 Bytecodes::Code invoke_code,
276 const CallInfo &call_info) {
277 // NOTE: This CPCE can be the subject of data races.
278 // There are three words to update: flags, refs[f2], f1 (in that order).
279 // Writers must store all other values before f1.
280 // Readers must test f1 first for non-null before reading other fields.
281 // Competing writers must acquire exclusive access via a lock.
282 // A losing writer waits on the lock until the winner writes f1 and leaves
283 // the lock, so that when the losing writer returns, he can use the linked
284 // cache entry.
285
286 objArrayHandle resolved_references = cpool->resolved_references();
287 // Use the resolved_references() lock for this cpCache entry.
288 // resolved_references are created for all classes with Invokedynamic, MethodHandle
289 // or MethodType constant pool cache entries.
290 assert(resolved_references() != NULL,
291 "a resolved_references array should have been created for this class");
292 ObjectLocker ol(resolved_references, Thread::current());
293 if (!is_f1_null()) {
294 return;
295 }
296
297 const methodHandle adapter = call_info.resolved_method();
298 const Handle appendix = call_info.resolved_appendix();
299 const Handle method_type = call_info.resolved_method_type();
300 const bool has_appendix = appendix.not_null();
301 const bool has_method_type = method_type.not_null();
302
303 // Write the flags.
304 set_method_flags(as_TosState(adapter->result_type()),
305 ((has_appendix ? 1 : 0) << has_appendix_shift ) |
306 ((has_method_type ? 1 : 0) << has_method_type_shift) |
|
266 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, const CallInfo &call_info) {
267 set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
268 }
269
270 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, const CallInfo &call_info) {
271 set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
272 }
273
274 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
275 Bytecodes::Code invoke_code,
276 const CallInfo &call_info) {
277 // NOTE: This CPCE can be the subject of data races.
278 // There are three words to update: flags, refs[f2], f1 (in that order).
279 // Writers must store all other values before f1.
280 // Readers must test f1 first for non-null before reading other fields.
281 // Competing writers must acquire exclusive access via a lock.
282 // A losing writer waits on the lock until the winner writes f1 and leaves
283 // the lock, so that when the losing writer returns, he can use the linked
284 // cache entry.
285
286 objArrayHandle resolved_references = objArrayHandle(objArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(cpool->resolved_references())));
287 // Use the resolved_references() lock for this cpCache entry.
288 // resolved_references are created for all classes with Invokedynamic, MethodHandle
289 // or MethodType constant pool cache entries.
290 assert(resolved_references() != NULL,
291 "a resolved_references array should have been created for this class");
292 ObjectLocker ol(resolved_references, Thread::current());
293 if (!is_f1_null()) {
294 return;
295 }
296
297 const methodHandle adapter = call_info.resolved_method();
298 const Handle appendix = call_info.resolved_appendix();
299 const Handle method_type = call_info.resolved_method_type();
300 const bool has_appendix = appendix.not_null();
301 const bool has_method_type = method_type.not_null();
302
303 // Write the flags.
304 set_method_flags(as_TosState(adapter->result_type()),
305 ((has_appendix ? 1 : 0) << has_appendix_shift ) |
306 ((has_method_type ? 1 : 0) << has_method_type_shift) |
|