src/share/vm/oops/cpCache.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8066171 Sdiff src/share/vm/oops

src/share/vm/oops/cpCache.cpp

Print this page




 270 void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, const CallInfo &call_info) {
 271   set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
 272 }
 273 
 274 void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, const CallInfo &call_info) {
 275   set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
 276 }
 277 
 278 void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
 279                                                       Bytecodes::Code invoke_code,
 280                                                       const CallInfo &call_info) {
 281   // NOTE: This CPCE can be the subject of data races.
 282   // There are three words to update: flags, refs[f2], f1 (in that order).
 283   // Writers must store all other values before f1.
 284   // Readers must test f1 first for non-null before reading other fields.
 285   // Competing writers must acquire exclusive access via a lock.
 286   // A losing writer waits on the lock until the winner writes f1 and leaves
 287   // the lock, so that when the losing writer returns, he can use the linked
 288   // cache entry.
 289 
 290   // Use the lock from the metaspace for this, which cannot stop for safepoint.
 291   Mutex* metaspace_lock = cpool->pool_holder()->class_loader_data()->metaspace_lock();
 292   MutexLockerEx ml(metaspace_lock,  Mutex::_no_safepoint_check_flag);




 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) |
 307                    (                   1      << is_final_shift       ),
 308                    adapter->size_of_parameters());
 309 
 310   if (TraceInvokeDynamic) {
 311     tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
 312                   invoke_code,


 319 
 320   // Method handle invokes and invokedynamic sites use both cp cache words.
 321   // refs[f2], if not null, contains a value passed as a trailing argument to the adapter.
 322   // In the general case, this could be the call site's MethodType,
 323   // for use with java.lang.Invokers.checkExactType, or else a CallSite object.
 324   // f1 contains the adapter method which manages the actual call.
 325   // In the general case, this is a compiled LambdaForm.
 326   // (The Java code is free to optimize these calls by binding other
 327   // sorts of methods and appendices to call sites.)
 328   // JVM-level linking is via f1, as if for invokespecial, and signatures are erased.
 329   // The appendix argument (if any) is added to the signature, and is counted in the parameter_size bits.
 330   // Even with the appendix, the method will never take more than 255 parameter slots.
 331   //
 332   // This means that given a call site like (List)mh.invoke("foo"),
 333   // the f1 method has signature '(Ljl/Object;Ljl/invoke/MethodType;)Ljl/Object;',
 334   // not '(Ljava/lang/String;)Ljava/util/List;'.
 335   // The fact that String and List are involved is encoded in the MethodType in refs[f2].
 336   // This allows us to create fewer Methods, while keeping type safety.
 337   //
 338 
 339   objArrayHandle resolved_references = cpool->resolved_references();
 340   // Store appendix, if any.
 341   if (has_appendix) {
 342     const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
 343     assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
 344     assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
 345     resolved_references->obj_at_put(appendix_index, appendix());
 346   }
 347 
 348   // Store MethodType, if any.
 349   if (has_method_type) {
 350     const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
 351     assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
 352     assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
 353     resolved_references->obj_at_put(method_type_index, method_type());
 354   }
 355 
 356   release_set_f1(adapter());  // This must be the last one to set (see NOTE above)!
 357 
 358   // The interpreter assembly code does not check byte_2,
 359   // but it is used by is_resolved, method_if_resolved, etc.




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


 323 
 324   // Method handle invokes and invokedynamic sites use both cp cache words.
 325   // refs[f2], if not null, contains a value passed as a trailing argument to the adapter.
 326   // In the general case, this could be the call site's MethodType,
 327   // for use with java.lang.Invokers.checkExactType, or else a CallSite object.
 328   // f1 contains the adapter method which manages the actual call.
 329   // In the general case, this is a compiled LambdaForm.
 330   // (The Java code is free to optimize these calls by binding other
 331   // sorts of methods and appendices to call sites.)
 332   // JVM-level linking is via f1, as if for invokespecial, and signatures are erased.
 333   // The appendix argument (if any) is added to the signature, and is counted in the parameter_size bits.
 334   // Even with the appendix, the method will never take more than 255 parameter slots.
 335   //
 336   // This means that given a call site like (List)mh.invoke("foo"),
 337   // the f1 method has signature '(Ljl/Object;Ljl/invoke/MethodType;)Ljl/Object;',
 338   // not '(Ljava/lang/String;)Ljava/util/List;'.
 339   // The fact that String and List are involved is encoded in the MethodType in refs[f2].
 340   // This allows us to create fewer Methods, while keeping type safety.
 341   //
 342 

 343   // Store appendix, if any.
 344   if (has_appendix) {
 345     const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
 346     assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
 347     assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
 348     resolved_references->obj_at_put(appendix_index, appendix());
 349   }
 350 
 351   // Store MethodType, if any.
 352   if (has_method_type) {
 353     const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
 354     assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
 355     assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
 356     resolved_references->obj_at_put(method_type_index, method_type());
 357   }
 358 
 359   release_set_f1(adapter());  // This must be the last one to set (see NOTE above)!
 360 
 361   // The interpreter assembly code does not check byte_2,
 362   // but it is used by is_resolved, method_if_resolved, etc.


src/share/vm/oops/cpCache.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File