718 |
718 |
719 void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) { |
719 void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) { |
720 Thread* THREAD = thread; |
720 Thread* THREAD = thread; |
721 // extract receiver from the outgoing argument list if necessary |
721 // extract receiver from the outgoing argument list if necessary |
722 Handle receiver(thread, NULL); |
722 Handle receiver(thread, NULL); |
723 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { |
723 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface || |
|
724 bytecode == Bytecodes::_invokespecial) { |
724 ResourceMark rm(thread); |
725 ResourceMark rm(thread); |
725 methodHandle m (thread, method(thread)); |
726 methodHandle m (thread, method(thread)); |
726 Bytecode_invoke call(m, bci(thread)); |
727 Bytecode_invoke call(m, bci(thread)); |
727 Symbol* signature = call.signature(); |
728 Symbol* signature = call.signature(); |
728 receiver = Handle(thread, |
729 receiver = Handle(thread, |
781 // Setup itable entry |
782 // Setup itable entry |
782 assert(info.call_kind() == CallInfo::itable_call, ""); |
783 assert(info.call_kind() == CallInfo::itable_call, ""); |
783 int index = info.resolved_method()->itable_index(); |
784 int index = info.resolved_method()->itable_index(); |
784 assert(info.itable_index() == index, ""); |
785 assert(info.itable_index() == index, ""); |
785 } |
786 } |
|
787 } else if (bytecode == Bytecodes::_invokespecial) { |
|
788 assert(info.call_kind() == CallInfo::direct_call, "must be direct call"); |
786 } else { |
789 } else { |
787 assert(info.call_kind() == CallInfo::direct_call || |
790 assert(info.call_kind() == CallInfo::direct_call || |
788 info.call_kind() == CallInfo::vtable_call, ""); |
791 info.call_kind() == CallInfo::vtable_call, ""); |
789 } |
792 } |
790 #endif |
793 #endif |
|
794 // Get sender or sender's host_klass, and only set cpCache entry to resolved if |
|
795 // it is not an interface. The receiver for invokespecial calls within interface |
|
796 // methods must be checked for every call. |
|
797 InstanceKlass* sender = pool->pool_holder(); |
|
798 sender = sender->is_anonymous() ? sender->host_klass() : sender; |
|
799 |
791 switch (info.call_kind()) { |
800 switch (info.call_kind()) { |
792 case CallInfo::direct_call: |
801 case CallInfo::direct_call: |
793 cp_cache_entry->set_direct_call( |
802 cp_cache_entry->set_direct_call( |
794 bytecode, |
803 bytecode, |
795 info.resolved_method()); |
804 info.resolved_method(), |
|
805 sender->is_interface()); |
796 break; |
806 break; |
797 case CallInfo::vtable_call: |
807 case CallInfo::vtable_call: |
798 cp_cache_entry->set_vtable_call( |
808 cp_cache_entry->set_vtable_call( |
799 bytecode, |
809 bytecode, |
800 info.resolved_method(), |
810 info.resolved_method(), |