< prev index next >

src/hotspot/share/oops/cpCache.cpp

Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP


 364     // Before we got here, another thread got a LinkageError exception during
 365     // resolution.  Ignore our success and throw their exception.
 366     ConstantPoolCache* cpCache = cpool->cache();
 367     int index = -1;
 368     for (int i = 0; i < cpCache->length(); i++) {
 369       if (cpCache->entry_at(i) == this) {
 370         index = i;
 371         break;
 372       }
 373     }
 374     guarantee(index >= 0, "Didn't find cpCache entry!");
 375     int encoded_index = ResolutionErrorTable::encode_cpcache_index(
 376                           ConstantPool::encode_invokedynamic_index(index));
 377     Thread* THREAD = Thread::current();
 378     ConstantPool::throw_resolution_error(cpool, encoded_index, THREAD);
 379     return;
 380   }
 381 
 382   const methodHandle adapter = call_info.resolved_method();
 383   const Handle appendix      = call_info.resolved_appendix();
 384   const Handle method_type   = call_info.resolved_method_type();
 385   const bool has_appendix    = appendix.not_null();
 386   const bool has_method_type = method_type.not_null();

 387 
 388   // Write the flags.
 389   set_method_flags(as_TosState(adapter->result_type()),
 390                    ((has_appendix    ? 1 : 0) << has_appendix_shift   ) |
 391                    ((has_method_type ? 1 : 0) << has_method_type_shift) |
 392                    (                   1      << is_final_shift       ),
 393                    adapter->size_of_parameters());
 394 
 395   if (TraceInvokeDynamic) {
 396     ttyLocker ttyl;
 397     tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method_type=" PTR_FORMAT "%s method=" PTR_FORMAT " ",
 398                   invoke_code,
 399                   p2i(appendix()),    (has_appendix    ? "" : " (unused)"),
 400                   p2i(method_type()), (has_method_type ? "" : " (unused)"),
 401                   p2i(adapter()));
 402     adapter->print();
 403     if (has_appendix)  appendix()->print();
 404   }
 405 
 406   // Method handle invokes and invokedynamic sites use both cp cache words.
 407   // refs[f2], if not null, contains a value passed as a trailing argument to the adapter.
 408   // In the general case, this could be the call site's MethodType,
 409   // for use with java.lang.Invokers.checkExactType, or else a CallSite object.
 410   // f1 contains the adapter method which manages the actual call.
 411   // In the general case, this is a compiled LambdaForm.
 412   // (The Java code is free to optimize these calls by binding other
 413   // sorts of methods and appendices to call sites.)
 414   // JVM-level linking is via f1, as if for invokespecial, and signatures are erased.
 415   // The appendix argument (if any) is added to the signature, and is counted in the parameter_size bits.
 416   // Even with the appendix, the method will never take more than 255 parameter slots.
 417   //
 418   // This means that given a call site like (List)mh.invoke("foo"),
 419   // the f1 method has signature '(Ljl/Object;Ljl/invoke/MethodType;)Ljl/Object;',
 420   // not '(Ljava/lang/String;)Ljava/util/List;'.
 421   // The fact that String and List are involved is encoded in the MethodType in refs[f2].
 422   // This allows us to create fewer Methods, while keeping type safety.
 423   //
 424 
 425   // Store appendix, if any.
 426   if (has_appendix) {
 427     const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
 428     assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
 429     assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
 430     resolved_references->obj_at_put(appendix_index, appendix());
 431   }
 432 
 433   // Store MethodType, if any.
 434   if (has_method_type) {
 435     const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
 436     assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
 437     assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
 438     resolved_references->obj_at_put(method_type_index, method_type());
 439   }
 440 
 441   release_set_f1(adapter());  // This must be the last one to set (see NOTE above)!
 442 
 443   // The interpreter assembly code does not check byte_2,
 444   // but it is used by is_resolved, method_if_resolved, etc.
 445   set_bytecode_1(invoke_code);
 446   NOT_PRODUCT(verify(tty));
 447   if (TraceInvokeDynamic) {
 448     ttyLocker ttyl;
 449     this->print(tty, 0);
 450   }



 451 }
 452 
 453 bool ConstantPoolCacheEntry::save_and_throw_indy_exc(
 454   const constantPoolHandle& cpool, int cpool_index, int index, constantTag tag, TRAPS) {
 455 
 456   assert(HAS_PENDING_EXCEPTION, "No exception got thrown!");
 457   assert(PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass()),
 458          "No LinkageError exception");
 459 
 460   // Use the resolved_references() lock for this cpCache entry.
 461   // resolved_references are created for all classes with Invokedynamic, MethodHandle
 462   // or MethodType constant pool cache entries.
 463   objArrayHandle resolved_references(Thread::current(), cpool->resolved_references());
 464   assert(resolved_references() != NULL,
 465          "a resolved_references array should have been created for this class");
 466   ObjectLocker ol(resolved_references, THREAD);
 467 
 468   // if f1 is not null or the indy_resolution_failed flag is set then another
 469   // thread either succeeded in resolving the method or got a LinkageError
 470   // exception, before this thread was able to record its failure.  So, clear


 516         return m;
 517       } else {
 518         int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index());
 519         if (cpool->tag_at(holder_index).is_klass()) {
 520           Klass* klass = cpool->resolved_klass_at(holder_index);
 521           return klass->method_at_vtable(f2_as_index());
 522         }
 523       }
 524       break;
 525     default:
 526       break;
 527     }
 528   }
 529   return NULL;
 530 }
 531 
 532 
 533 oop ConstantPoolCacheEntry::appendix_if_resolved(const constantPoolHandle& cpool) {
 534   if (!has_appendix())
 535     return NULL;
 536   const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
 537   objArrayOop resolved_references = cpool->resolved_references();
 538   return resolved_references->obj_at(ref_index);
 539 }
 540 
 541 
 542 oop ConstantPoolCacheEntry::method_type_if_resolved(const constantPoolHandle& cpool) {
 543   if (!has_method_type())
 544     return NULL;
 545   const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
 546   objArrayOop resolved_references = cpool->resolved_references();
 547   return resolved_references->obj_at(ref_index);
 548 }
 549 
 550 
 551 #if INCLUDE_JVMTI
 552 
 553 void log_adjust(const char* entry_type, Method* old_method, Method* new_method, bool* trace_name_printed) {
 554   if (log_is_enabled(Info, redefine, class, update)) {
 555     ResourceMark rm;
 556     if (!(*trace_name_printed)) {
 557       log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
 558       *trace_name_printed = true;
 559     }
 560     log_debug(redefine, class, update, constantpool)
 561           ("cpc %s entry update: %s(%s)", entry_type, new_method->name()->as_C_string(), new_method->signature()->as_C_string());
 562   }
 563 }
 564 
 565 // RedefineClasses() API support:


 652 void ConstantPoolCacheEntry::verify(outputStream* st) const {
 653   // not implemented yet
 654 }
 655 
 656 // Implementation of ConstantPoolCache
 657 
 658 ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
 659                                      const intStack& index_map,
 660                                      const intStack& invokedynamic_index_map,
 661                                      const intStack& invokedynamic_map, TRAPS) {
 662 
 663   const int length = index_map.length() + invokedynamic_index_map.length();
 664   int size = ConstantPoolCache::size(length);
 665 
 666   return new (loader_data, size, MetaspaceObj::ConstantPoolCacheType, THREAD)
 667     ConstantPoolCache(length, index_map, invokedynamic_index_map, invokedynamic_map);
 668 }
 669 
 670 void ConstantPoolCache::initialize(const intArray& inverse_index_map,
 671                                    const intArray& invokedynamic_inverse_index_map,
 672                                    const intArray& invokedynamic_references_map) {
 673   for (int i = 0; i < inverse_index_map.length(); i++) {
 674     ConstantPoolCacheEntry* e = entry_at(i);
 675     int original_index = inverse_index_map.at(i);
 676     e->initialize_entry(original_index);
 677     assert(entry_at(i) == e, "sanity");
 678   }
 679 
 680   // Append invokedynamic entries at the end
 681   int invokedynamic_offset = inverse_index_map.length();
 682   for (int i = 0; i < invokedynamic_inverse_index_map.length(); i++) {
 683     int offset = i + invokedynamic_offset;
 684     ConstantPoolCacheEntry* e = entry_at(offset);
 685     int original_index = invokedynamic_inverse_index_map.at(i);
 686     e->initialize_entry(original_index);
 687     assert(entry_at(offset) == e, "sanity");
 688   }
 689 
 690   for (int ref = 0; ref < invokedynamic_references_map.length(); ref++) {
 691     const int cpci = invokedynamic_references_map.at(ref);
 692     if (cpci >= 0) {
 693 #ifdef ASSERT
 694       // invokedynamic and invokehandle have more entries; check if they
 695       // all point to the same constant pool cache entry.
 696       for (int entry = 1; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
 697         const int cpci_next = invokedynamic_references_map.at(ref + entry);
 698         assert(cpci == cpci_next, "%d == %d", cpci, cpci_next);
 699       }
 700 #endif
 701       entry_at(cpci)->initialize_resolved_reference_index(ref);
 702       ref += ConstantPoolCacheEntry::_indy_resolved_references_entries - 1;  // skip extra entries
 703     }
 704   }
 705 }
 706 
 707 void ConstantPoolCache::verify_just_initialized() {
 708   DEBUG_ONLY(walk_entries_for_initialization(/*check_only = */ true));
 709 }
 710 
 711 void ConstantPoolCache::remove_unshareable_info() {
 712   walk_entries_for_initialization(/*check_only = */ false);
 713 }
 714 
 715 void ConstantPoolCache::walk_entries_for_initialization(bool check_only) {
 716   assert(DumpSharedSpaces, "sanity");
 717   // When dumping the archive, we want to clean up the ConstantPoolCache
 718   // to remove any effect of linking due to the execution of Java code --
 719   // each ConstantPoolCacheEntry will have the same contents as if
 720   // ConstantPoolCache::initialize has just returned:
 721   //
 722   // - We keep the ConstantPoolCache::constant_pool_index() bits for all entries.




 364     // Before we got here, another thread got a LinkageError exception during
 365     // resolution.  Ignore our success and throw their exception.
 366     ConstantPoolCache* cpCache = cpool->cache();
 367     int index = -1;
 368     for (int i = 0; i < cpCache->length(); i++) {
 369       if (cpCache->entry_at(i) == this) {
 370         index = i;
 371         break;
 372       }
 373     }
 374     guarantee(index >= 0, "Didn't find cpCache entry!");
 375     int encoded_index = ResolutionErrorTable::encode_cpcache_index(
 376                           ConstantPool::encode_invokedynamic_index(index));
 377     Thread* THREAD = Thread::current();
 378     ConstantPool::throw_resolution_error(cpool, encoded_index, THREAD);
 379     return;
 380   }
 381 
 382   const methodHandle adapter = call_info.resolved_method();
 383   const Handle appendix      = call_info.resolved_appendix();

 384   const bool has_appendix    = appendix.not_null();
 385   const bool has_local_sig   = call_info.has_local_signature();
 386   assert(has_local_sig, "MHs and indy are always sig-poly");
 387 
 388   // Write the flags.
 389   set_method_flags(as_TosState(adapter->result_type()),
 390                    ((has_appendix    ? 1 : 0) << has_appendix_shift        ) |
 391                    ((has_local_sig   ? 1 : 0) << has_local_signature_shift ) |
 392                    (                   1      << is_final_shift            ),
 393                    adapter->size_of_parameters());
 394 
 395   if (TraceInvokeDynamic) {
 396     ttyLocker ttyl;
 397     tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method=" PTR_FORMAT "%s ",
 398                   invoke_code,
 399                   p2i(appendix()),    (has_appendix    ? "" : " (unused)"),
 400                   p2i(adapter()),     (has_local_sig   ? " (local signature)" : ""));

 401     adapter->print();
 402     if (has_appendix)  appendix()->print();
 403   }
 404 
 405   // Method handle invokes and invokedynamic sites use both cp cache words.
 406   // refs[f2], if not null, contains a value passed as a trailing argument to the adapter.
 407   // In the general case, this could be the call site's MethodType,
 408   // for use with java.lang.Invokers.checkExactType, or else a CallSite object.
 409   // f1 contains the adapter method which manages the actual call.
 410   // In the general case, this is a compiled LambdaForm.
 411   // (The Java code is free to optimize these calls by binding other
 412   // sorts of methods and appendices to call sites.)
 413   // JVM-level linking is via f1, as if for invokespecial, and signatures are erased.
 414   // The appendix argument (if any) is added to the signature, and is counted in the parameter_size bits.
 415   // Even with the appendix, the method will never take more than 255 parameter slots.
 416   //
 417   // This means that given a call site like (List)mh.invoke("foo"),
 418   // the f1 method has signature '(Ljl/Object;Ljl/invoke/MethodType;)Ljl/Object;',
 419   // not '(Ljava/lang/String;)Ljava/util/List;'.
 420   // The fact that String and List are involved is encoded in the MethodType in refs[f2].
 421   // This allows us to create fewer Methods, while keeping type safety.
 422   //
 423 
 424   // Store appendix, if any.
 425   if (has_appendix) {
 426     const int appendix_index = f2_as_index();
 427     assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
 428     assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
 429     resolved_references->obj_at_put(appendix_index, appendix());
 430   }
 431 








 432   release_set_f1(adapter());  // This must be the last one to set (see NOTE above)!
 433 
 434   // The interpreter assembly code does not check byte_2,
 435   // but it is used by is_resolved, method_if_resolved, etc.
 436   set_bytecode_1(invoke_code);
 437   NOT_PRODUCT(verify(tty));
 438   if (TraceInvokeDynamic) {
 439     ttyLocker ttyl;
 440     this->print(tty, 0);
 441   }
 442 
 443   assert(has_appendix == this->has_appendix(), "proper storage of appendix flag");
 444   assert(has_local_sig == this->has_local_signature(), "proper storage of signature flag");
 445 }
 446 
 447 bool ConstantPoolCacheEntry::save_and_throw_indy_exc(
 448   const constantPoolHandle& cpool, int cpool_index, int index, constantTag tag, TRAPS) {
 449 
 450   assert(HAS_PENDING_EXCEPTION, "No exception got thrown!");
 451   assert(PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass()),
 452          "No LinkageError exception");
 453 
 454   // Use the resolved_references() lock for this cpCache entry.
 455   // resolved_references are created for all classes with Invokedynamic, MethodHandle
 456   // or MethodType constant pool cache entries.
 457   objArrayHandle resolved_references(Thread::current(), cpool->resolved_references());
 458   assert(resolved_references() != NULL,
 459          "a resolved_references array should have been created for this class");
 460   ObjectLocker ol(resolved_references, THREAD);
 461 
 462   // if f1 is not null or the indy_resolution_failed flag is set then another
 463   // thread either succeeded in resolving the method or got a LinkageError
 464   // exception, before this thread was able to record its failure.  So, clear


 510         return m;
 511       } else {
 512         int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index());
 513         if (cpool->tag_at(holder_index).is_klass()) {
 514           Klass* klass = cpool->resolved_klass_at(holder_index);
 515           return klass->method_at_vtable(f2_as_index());
 516         }
 517       }
 518       break;
 519     default:
 520       break;
 521     }
 522   }
 523   return NULL;
 524 }
 525 
 526 
 527 oop ConstantPoolCacheEntry::appendix_if_resolved(const constantPoolHandle& cpool) {
 528   if (!has_appendix())
 529     return NULL;
 530   const int ref_index = f2_as_index();









 531   objArrayOop resolved_references = cpool->resolved_references();
 532   return resolved_references->obj_at(ref_index);
 533 }
 534 
 535 
 536 #if INCLUDE_JVMTI
 537 
 538 void log_adjust(const char* entry_type, Method* old_method, Method* new_method, bool* trace_name_printed) {
 539   if (log_is_enabled(Info, redefine, class, update)) {
 540     ResourceMark rm;
 541     if (!(*trace_name_printed)) {
 542       log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
 543       *trace_name_printed = true;
 544     }
 545     log_debug(redefine, class, update, constantpool)
 546           ("cpc %s entry update: %s(%s)", entry_type, new_method->name()->as_C_string(), new_method->signature()->as_C_string());
 547   }
 548 }
 549 
 550 // RedefineClasses() API support:


 637 void ConstantPoolCacheEntry::verify(outputStream* st) const {
 638   // not implemented yet
 639 }
 640 
 641 // Implementation of ConstantPoolCache
 642 
 643 ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
 644                                      const intStack& index_map,
 645                                      const intStack& invokedynamic_index_map,
 646                                      const intStack& invokedynamic_map, TRAPS) {
 647 
 648   const int length = index_map.length() + invokedynamic_index_map.length();
 649   int size = ConstantPoolCache::size(length);
 650 
 651   return new (loader_data, size, MetaspaceObj::ConstantPoolCacheType, THREAD)
 652     ConstantPoolCache(length, index_map, invokedynamic_index_map, invokedynamic_map);
 653 }
 654 
 655 void ConstantPoolCache::initialize(const intArray& inverse_index_map,
 656                                    const intArray& invokedynamic_inverse_index_map,
 657                                    const intArray& appendix_references_map) {
 658   for (int i = 0; i < inverse_index_map.length(); i++) {
 659     ConstantPoolCacheEntry* e = entry_at(i);
 660     int original_index = inverse_index_map.at(i);
 661     e->initialize_entry(original_index);
 662     assert(entry_at(i) == e, "sanity");
 663   }
 664 
 665   // Append invokedynamic entries at the end
 666   int invokedynamic_offset = inverse_index_map.length();
 667   for (int i = 0; i < invokedynamic_inverse_index_map.length(); i++) {
 668     int offset = i + invokedynamic_offset;
 669     ConstantPoolCacheEntry* e = entry_at(offset);
 670     int original_index = invokedynamic_inverse_index_map.at(i);
 671     e->initialize_entry(original_index);
 672     assert(entry_at(offset) == e, "sanity");
 673   }
 674 
 675   for (int ref = 0; ref < appendix_references_map.length(); ref++) {
 676     const int cpci = appendix_references_map.at(ref);
 677     if (cpci >= 0) {








 678       entry_at(cpci)->initialize_resolved_reference_index(ref);

 679     }
 680   }
 681 }
 682 
 683 void ConstantPoolCache::verify_just_initialized() {
 684   DEBUG_ONLY(walk_entries_for_initialization(/*check_only = */ true));
 685 }
 686 
 687 void ConstantPoolCache::remove_unshareable_info() {
 688   walk_entries_for_initialization(/*check_only = */ false);
 689 }
 690 
 691 void ConstantPoolCache::walk_entries_for_initialization(bool check_only) {
 692   assert(DumpSharedSpaces, "sanity");
 693   // When dumping the archive, we want to clean up the ConstantPoolCache
 694   // to remove any effect of linking due to the execution of Java code --
 695   // each ConstantPoolCacheEntry will have the same contents as if
 696   // ConstantPoolCache::initialize has just returned:
 697   //
 698   // - We keep the ConstantPoolCache::constant_pool_index() bits for all entries.


< prev index next >