src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/interpreter/linkResolver.cpp	Thu Mar 31 21:51:08 2016
--- new/src/share/vm/interpreter/linkResolver.cpp	Thu Mar 31 21:51:08 2016

*** 610,627 **** --- 610,626 ---- return methodHandle(THREAD, result); } } 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); } } // Check and print a loader constraint violation message for method or interface method void LinkResolver::check_method_loader_constraints(const LinkInfo& link_info,
*** 775,786 **** --- 774,784 ---- } st->cr(); #endif // PRODUCT } ! methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, Bytecodes::Code code, TRAPS) { bool nostatics, TRAPS) { KlassHandle resolved_klass = link_info.resolved_klass(); // check if klass is interface if (!resolved_klass->is_interface()) {
*** 822,840 **** --- 820,851 ---- CHECK_NULL); 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", Method::name_and_sig_as_C_string(resolved_klass(), resolved_method->name(), resolved_method->signature())); 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() ? "<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, resolved_method, true); }
*** 982,992 **** --- 993,1003 ---- KlassHandle resolved_klass = link_info.resolved_klass(); methodHandle resolved_method; 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"); // check if static if (!resolved_method->is_static()) {
*** 1025,1035 **** --- 1036,1046 ---- methodHandle resolved_method; 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 <init>, that it is found in same klass as static type if (resolved_method->name() == vmSymbols::object_initializer_name() && resolved_method->method_holder() != resolved_klass()) {
*** 1300,1310 **** --- 1311,1321 ---- } 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"); return resolved_method; }
*** 1319,1339 **** --- 1330,1339 ---- // check if receiver exists if (check_null_and_abstract && recv.is_null()) { 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); char buf[200]; jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",

src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File