diff -r d090627aedb8 -r 11431bbc9549 hotspot/src/share/vm/interpreter/interpreterRuntime.cpp --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Apr 19 14:37:11 2017 +0200 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Dec 01 14:21:31 2016 -0500 @@ -720,7 +720,8 @@ Thread* THREAD = thread; // extract receiver from the outgoing argument list if necessary Handle receiver(thread, NULL); - if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { + if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface || + bytecode == Bytecodes::_invokespecial) { ResourceMark rm(thread); methodHandle m (thread, method(thread)); Bytecode_invoke call(m, bci(thread)); @@ -783,16 +784,25 @@ int index = info.resolved_method()->itable_index(); assert(info.itable_index() == index, ""); } + } else if (bytecode == Bytecodes::_invokespecial) { + assert(info.call_kind() == CallInfo::direct_call, "must be direct call"); } else { assert(info.call_kind() == CallInfo::direct_call || info.call_kind() == CallInfo::vtable_call, ""); } #endif + // Get sender or sender's host_klass, and only set cpCache entry to resolved if + // it is not an interface. The receiver for invokespecial calls within interface + // methods must be checked for every call. + InstanceKlass* sender = pool->pool_holder(); + sender = sender->is_anonymous() ? sender->host_klass() : sender; + switch (info.call_kind()) { case CallInfo::direct_call: cp_cache_entry->set_direct_call( bytecode, - info.resolved_method()); + info.resolved_method(), + sender->is_interface()); break; case CallInfo::vtable_call: cp_cache_entry->set_vtable_call(