688 IRT_END |
688 IRT_END |
689 |
689 |
690 IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) { |
690 IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) { |
691 // extract receiver from the outgoing argument list if necessary |
691 // extract receiver from the outgoing argument list if necessary |
692 Handle receiver(thread, NULL); |
692 Handle receiver(thread, NULL); |
693 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { |
693 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface || |
|
694 bytecode == Bytecodes::_invokespecial) { |
694 ResourceMark rm(thread); |
695 ResourceMark rm(thread); |
695 methodHandle m (thread, method(thread)); |
696 methodHandle m (thread, method(thread)); |
696 Bytecode_invoke call(m, bci(thread)); |
697 Bytecode_invoke call(m, bci(thread)); |
697 Symbol* signature = call.signature(); |
698 Symbol* signature = call.signature(); |
698 receiver = Handle(thread, |
699 receiver = Handle(thread, |
754 // Setup itable entry |
755 // Setup itable entry |
755 assert(info.call_kind() == CallInfo::itable_call, ""); |
756 assert(info.call_kind() == CallInfo::itable_call, ""); |
756 int index = info.resolved_method()->itable_index(); |
757 int index = info.resolved_method()->itable_index(); |
757 assert(info.itable_index() == index, ""); |
758 assert(info.itable_index() == index, ""); |
758 } |
759 } |
|
760 } else if (bytecode == Bytecodes::_invokespecial) { |
|
761 assert(info.call_kind() == CallInfo::direct_call, "must be direct call"); |
759 } else { |
762 } else { |
760 assert(info.call_kind() == CallInfo::direct_call || |
763 assert(info.call_kind() == CallInfo::direct_call || |
761 info.call_kind() == CallInfo::vtable_call, ""); |
764 info.call_kind() == CallInfo::vtable_call, ""); |
762 } |
765 } |
763 #endif |
766 #endif |
|
767 // Get sender or sender's host_klass, and only set cpCache entry to resolved if |
|
768 // it is not an interface. The receiver for invokespecial calls within interface |
|
769 // methods must be checked for every call. |
|
770 InstanceKlass* sender = pool->pool_holder(); |
|
771 sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender; |
|
772 |
764 switch (info.call_kind()) { |
773 switch (info.call_kind()) { |
765 case CallInfo::direct_call: |
774 case CallInfo::direct_call: |
766 cache_entry(thread)->set_direct_call( |
775 cache_entry(thread)->set_direct_call( |
767 bytecode, |
776 bytecode, |
768 info.resolved_method()); |
777 info.resolved_method(), |
|
778 sender->is_interface()); |
769 break; |
779 break; |
770 case CallInfo::vtable_call: |
780 case CallInfo::vtable_call: |
771 cache_entry(thread)->set_vtable_call( |
781 cache_entry(thread)->set_vtable_call( |
772 bytecode, |
782 bytecode, |
773 info.resolved_method(), |
783 info.resolved_method(), |