--- old/src/share/vm/interpreter/linkResolver.cpp 2016-03-31 21:51:08.000000000 -0700 +++ new/src/share/vm/interpreter/linkResolver.cpp 2016-03-31 21:51:08.000000000 -0700 @@ -612,14 +612,13 @@ } if (code == Bytecodes::_invokeinterface) { - return resolve_interface_method(link_info, true, THREAD); + return resolve_interface_method(link_info, code, THREAD); } else if (code == Bytecodes::_invokevirtual) { return resolve_method(link_info, /*require_methodref*/true, THREAD); } else if (!resolved_klass->is_interface()) { return resolve_method(link_info, /*require_methodref*/false, THREAD); } else { - bool nostatics = (code == Bytecodes::_invokestatic) ? false : true; - return resolve_interface_method(link_info, nostatics, THREAD); + return resolve_interface_method(link_info, code, THREAD); } } @@ -777,8 +776,7 @@ #endif // PRODUCT } -methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, - bool nostatics, TRAPS) { +methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, Bytecodes::Code code, TRAPS) { KlassHandle resolved_klass = link_info.resolved_klass(); @@ -824,7 +822,7 @@ check_method_loader_constraints(link_info, resolved_method, "interface method", CHECK_NULL); } - if (nostatics && resolved_method->is_static()) { + if (code != Bytecodes::_invokestatic && resolved_method->is_static()) { ResourceMark rm(THREAD); char buf[200]; jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", @@ -833,6 +831,19 @@ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } + if (code == Bytecodes::_invokeinterface && resolved_method->is_private()) { + ResourceMark rm(THREAD); + char buf[200]; + + KlassHandle current_klass = link_info.current_klass(); + jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s, caller-class:%s", + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + (current_klass.is_null() ? "" : current_klass->internal_name())); + THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + if (log_develop_is_enabled(Trace, itables)) { trace_method_resolution("invokeinterface resolved method: caller-class", link_info.current_klass(), resolved_klass, @@ -984,7 +995,7 @@ if (!resolved_klass->is_interface()) { resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL); } else { - resolved_method = resolve_interface_method(link_info, /*nostatics*/false, CHECK_NULL); + resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); } assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); @@ -1027,7 +1038,7 @@ if (!resolved_klass->is_interface()) { resolved_method = resolve_method(link_info, /*require_methodref*/false, CHECK_NULL); } else { - resolved_method = resolve_interface_method(link_info, /*nostatics*/true, CHECK_NULL); + resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); } // check if method name is , that it is found in same klass as static type @@ -1302,7 +1313,7 @@ methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info, TRAPS) { // normal interface method resolution - methodHandle resolved_method = resolve_interface_method(link_info, true, CHECK_NULL); + methodHandle resolved_method = resolve_interface_method(link_info, Bytecodes::_invokeinterface, CHECK_NULL); assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); @@ -1321,17 +1332,6 @@ THROW(vmSymbols::java_lang_NullPointerException()); } - // check if private interface method - if (resolved_klass->is_interface() && resolved_method->is_private()) { - ResourceMark rm(THREAD); - char buf[200]; - jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s", - Method::name_and_sig_as_C_string(resolved_klass(), - resolved_method->name(), - resolved_method->signature())); - THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); - } - // check if receiver klass implements the resolved interface if (!recv_klass->is_subtype_of(resolved_klass())) { ResourceMark rm(THREAD); --- old/src/share/vm/interpreter/linkResolver.hpp 2016-03-31 21:51:09.000000000 -0700 +++ new/src/share/vm/interpreter/linkResolver.hpp 2016-03-31 21:51:09.000000000 -0700 @@ -192,7 +192,7 @@ KlassHandle current_klass, KlassHandle sel_klass, TRAPS); - static methodHandle resolve_interface_method(const LinkInfo& link_info, bool nostatics, TRAPS); + static methodHandle resolve_interface_method(const LinkInfo& link_info, Bytecodes::Code code, TRAPS); static methodHandle resolve_method (const LinkInfo& link_info, bool require_methodref, TRAPS); static methodHandle linktime_resolve_static_method (const LinkInfo& link_info, TRAPS);