23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/defaultMethods.hpp" |
26 #include "classfile/defaultMethods.hpp" |
27 #include "classfile/javaClasses.hpp" |
27 #include "classfile/javaClasses.hpp" |
|
28 #include "classfile/resolutionErrors.hpp" |
28 #include "classfile/symbolTable.hpp" |
29 #include "classfile/symbolTable.hpp" |
29 #include "classfile/systemDictionary.hpp" |
30 #include "classfile/systemDictionary.hpp" |
30 #include "classfile/vmSymbols.hpp" |
31 #include "classfile/vmSymbols.hpp" |
31 #include "compiler/compileBroker.hpp" |
32 #include "compiler/compileBroker.hpp" |
32 #include "gc/shared/collectedHeap.inline.hpp" |
33 #include "gc/shared/collectedHeap.inline.hpp" |
1694 |
1695 |
1695 // Resolve the bootstrap specifier (BSM + optional arguments). |
1696 // Resolve the bootstrap specifier (BSM + optional arguments). |
1696 Handle bootstrap_specifier; |
1697 Handle bootstrap_specifier; |
1697 // Check if CallSite has been bound already: |
1698 // Check if CallSite has been bound already: |
1698 ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index); |
1699 ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index); |
|
1700 int pool_index = cpce->constant_pool_index(); |
|
1701 |
1699 if (cpce->is_f1_null()) { |
1702 if (cpce->is_f1_null()) { |
1700 int pool_index = cpce->constant_pool_index(); |
1703 if (cpce->indy_resolution_failed()) { |
|
1704 ConstantPool::throw_resolution_error(pool, |
|
1705 ResolutionErrorTable::encode_cpcache_index(index), |
|
1706 CHECK); |
|
1707 } |
|
1708 |
|
1709 // The initial step in Call Site Specifier Resolution is to resolve the symbolic |
|
1710 // reference to a method handle which will be the bootstrap method for a dynamic |
|
1711 // call site. If resolution for the java.lang.invoke.MethodHandle for the bootstrap |
|
1712 // method fails, then a MethodHandleInError is stored at the corresponding bootstrap |
|
1713 // method's CP index for the CONSTANT_MethodHandle_info. So, there is no need to |
|
1714 // set the indy_rf flag since any subsequent invokedynamic instruction which shares |
|
1715 // this bootstrap method will encounter the resolution of MethodHandleInError. |
1701 oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, THREAD); |
1716 oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, THREAD); |
1702 wrap_invokedynamic_exception(CHECK); |
1717 wrap_invokedynamic_exception(CHECK); |
1703 assert(bsm_info != NULL, ""); |
1718 assert(bsm_info != NULL, ""); |
1704 // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic. |
1719 // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic. |
1705 bootstrap_specifier = Handle(THREAD, bsm_info); |
1720 bootstrap_specifier = Handle(THREAD, bsm_info); |
1720 method_name->as_C_string(), method_signature->as_C_string(), |
1735 method_name->as_C_string(), method_signature->as_C_string(), |
1721 current_klass->name()->as_C_string()); |
1736 current_klass->name()->as_C_string()); |
1722 tty->print(" BSM info: "); bootstrap_specifier->print(); |
1737 tty->print(" BSM info: "); bootstrap_specifier->print(); |
1723 } |
1738 } |
1724 |
1739 |
1725 resolve_dynamic_call(result, bootstrap_specifier, method_name, method_signature, current_klass, CHECK); |
1740 resolve_dynamic_call(result, bootstrap_specifier, method_name, |
|
1741 method_signature, current_klass, THREAD); |
|
1742 if (HAS_PENDING_EXCEPTION && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { |
|
1743 int encoded_index = ResolutionErrorTable::encode_cpcache_index(index); |
|
1744 bool recorded_res_status = cpce->save_and_throw_indy_exc(pool, pool_index, |
|
1745 encoded_index, |
|
1746 pool()->tag_at(pool_index), |
|
1747 CHECK); |
|
1748 if (!recorded_res_status) { |
|
1749 // Another thread got here just before we did. So, either use the method |
|
1750 // that it resolved or throw the LinkageError exception that it threw. |
|
1751 if (!cpce->is_f1_null()) { |
|
1752 methodHandle method( THREAD, cpce->f1_as_method()); |
|
1753 Handle appendix( THREAD, cpce->appendix_if_resolved(pool)); |
|
1754 Handle method_type(THREAD, cpce->method_type_if_resolved(pool)); |
|
1755 result.set_handle(method, appendix, method_type, THREAD); |
|
1756 wrap_invokedynamic_exception(CHECK); |
|
1757 } else { |
|
1758 assert(cpce->indy_resolution_failed(), "Resolution failure flag not set"); |
|
1759 ConstantPool::throw_resolution_error(pool, encoded_index, CHECK); |
|
1760 } |
|
1761 return; |
|
1762 } |
|
1763 assert(cpce->indy_resolution_failed(), "Resolution failure flag wasn't set"); |
|
1764 } |
1726 } |
1765 } |
1727 |
1766 |
1728 void LinkResolver::resolve_dynamic_call(CallInfo& result, |
1767 void LinkResolver::resolve_dynamic_call(CallInfo& result, |
1729 Handle bootstrap_specifier, |
1768 Handle bootstrap_specifier, |
1730 Symbol* method_name, Symbol* method_signature, |
1769 Symbol* method_name, Symbol* method_signature, |