Mercurial > hg > truffle
comparison src/share/vm/interpreter/interpreterRuntime.cpp @ 1507:cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
Summary: split MethodHandle.invoke into invokeExact and invokeGeneric; also clean up JVM-to-Java interfaces
Reviewed-by: twisti
author | jrose |
---|---|
date | Sat, 01 May 2010 02:42:18 -0700 |
parents | 2338d41fbd81 |
children | c18cbe5936b8 ab102d5d923e |
comparison
equal
deleted
inserted
replaced
1506:2338d41fbd81 | 1507:cd5dbf694d45 |
---|---|
689 | 689 |
690 const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; | 690 const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; |
691 | 691 |
692 methodHandle caller_method(thread, method(thread)); | 692 methodHandle caller_method(thread, method(thread)); |
693 | 693 |
694 // first determine if there is a bootstrap method | 694 // first find the bootstrap method |
695 { | 695 KlassHandle caller_klass(thread, caller_method->method_holder()); |
696 KlassHandle caller_klass(thread, caller_method->method_holder()); | 696 Handle bootm = SystemDictionary::find_bootstrap_method(caller_klass, CHECK); |
697 Handle bootm = SystemDictionary::find_bootstrap_method(caller_klass, KlassHandle(), CHECK); | |
698 if (bootm.is_null()) { | |
699 // If there is no bootstrap method, throw IncompatibleClassChangeError. | |
700 // This is a valid generic error type for resolution (JLS 12.3.3). | |
701 char buf[200]; | |
702 jio_snprintf(buf, sizeof(buf), "Class %s has not declared a bootstrap method for invokedynamic", | |
703 (Klass::cast(caller_klass()))->external_name()); | |
704 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
705 } | |
706 } | |
707 | 697 |
708 constantPoolHandle pool(thread, caller_method->constants()); | 698 constantPoolHandle pool(thread, caller_method->constants()); |
709 pool->set_invokedynamic(); // mark header to flag active call sites | 699 pool->set_invokedynamic(); // mark header to flag active call sites |
710 | 700 |
711 int site_index = four_byte_index(thread); | 701 int caller_bci = 0; |
702 int site_index = 0; | |
703 { address caller_bcp = bcp(thread); | |
704 caller_bci = caller_method->bci_from(caller_bcp); | |
705 site_index = Bytes::get_native_u4(caller_bcp+1); | |
706 } | |
707 assert(site_index == four_byte_index(thread), ""); | |
708 assert(constantPoolCacheOopDesc::is_secondary_index(site_index), "proper format"); | |
712 // there is a second CPC entries that is of interest; it caches signature info: | 709 // there is a second CPC entries that is of interest; it caches signature info: |
713 int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index(); | 710 int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index(); |
714 | 711 |
715 // first resolve the signature to a MH.invoke methodOop | 712 // first resolve the signature to a MH.invoke methodOop |
716 if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) { | 713 if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) { |
730 } | 727 } |
731 | 728 |
732 // The method (f2 entry) of the main entry is the MH.invoke for the | 729 // The method (f2 entry) of the main entry is the MH.invoke for the |
733 // invokedynamic target call signature. | 730 // invokedynamic target call signature. |
734 intptr_t f2_value = pool->cache()->entry_at(main_index)->f2(); | 731 intptr_t f2_value = pool->cache()->entry_at(main_index)->f2(); |
735 methodHandle mh_invdyn(THREAD, (methodOop) f2_value); | 732 methodHandle signature_invoker(THREAD, (methodOop) f2_value); |
736 assert(mh_invdyn.not_null() && mh_invdyn->is_method() && mh_invdyn->is_method_handle_invoke(), | 733 assert(signature_invoker.not_null() && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), |
737 "correct result from LinkResolver::resolve_invokedynamic"); | 734 "correct result from LinkResolver::resolve_invokedynamic"); |
738 | 735 |
739 symbolHandle call_site_name(THREAD, pool->name_ref_at(site_index)); | 736 symbolHandle call_site_name(THREAD, pool->name_ref_at(site_index)); |
737 | |
738 Handle info; // NYI: Other metadata from a new kind of CP entry. (Annotations?) | |
739 | |
740 // this is the index which gets stored on the CallSite object (as "callerPosition"): | |
741 int call_site_position = constantPoolCacheOopDesc::decode_secondary_index(site_index); | |
742 | |
740 Handle call_site | 743 Handle call_site |
741 = SystemDictionary::make_dynamic_call_site(caller_method->method_holder(), | 744 = SystemDictionary::make_dynamic_call_site(bootm, |
742 caller_method->method_idnum(), | 745 // Callee information: |
743 caller_method->bci_from(bcp(thread)), | |
744 call_site_name, | 746 call_site_name, |
745 mh_invdyn, | 747 signature_invoker, |
748 info, | |
749 // Caller information: | |
750 caller_method, | |
751 caller_bci, | |
746 CHECK); | 752 CHECK); |
747 | 753 |
748 // In the secondary entry, the f1 field is the call site, and the f2 (index) | 754 // In the secondary entry, the f1 field is the call site, and the f2 (index) |
749 // field is some data about the invoke site. | 755 // field is some data about the invoke site. Currently, it is just the BCI. |
750 int extra_data = 0; | 756 // Later, it might be changed to help manage inlining dependencies. |
751 pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site(), extra_data); | 757 pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site, signature_invoker); |
752 } | 758 } |
753 IRT_END | 759 IRT_END |
754 | 760 |
755 | 761 |
756 //------------------------------------------------------------------------------------------------------------------------ | 762 //------------------------------------------------------------------------------------------------------------------------ |