--- old/src/share/vm/interpreter/linkResolver.cpp 2016-01-28 18:05:59.350667154 -0800 +++ new/src/share/vm/interpreter/linkResolver.cpp 2016-01-28 18:05:59.183658821 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -248,6 +248,7 @@ // Get name, signature, and static klass _name = pool->name_ref_at(index); _signature = pool->signature_ref_at(index); + _tag = pool->tag_ref_at(index); _current_klass = KlassHandle(THREAD, pool->pool_holder()); // Coming from the constant pool always checks access @@ -684,6 +685,15 @@ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } + // check tag at call is method + if (!link_info.tag().is_invalid() && !link_info.tag().is_method()) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Resolving to non regular method %s", link_info.method_string()); + THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + + // 2. lookup method in resolved klass and its super klasses methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL); @@ -773,6 +783,14 @@ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } + // check tag at call is an interface method + if (!link_info.tag().is_invalid() && !link_info.tag().is_interface_method()) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Resolving to non interface method %s", link_info.method_string()); + THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + // lookup method in this interface or its super, java.lang.Object // JDK8: also look for static methods methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL); @@ -950,7 +968,8 @@ resolved_klass->initialize(CHECK); // Use updated LinkInfo (to reresolve with resolved_klass as method_holder?) LinkInfo new_info(resolved_klass, link_info.name(), link_info.signature(), - link_info.current_klass(), link_info.check_access()); + link_info.current_klass(), + link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check); resolved_method = linktime_resolve_static_method(new_info, CHECK); } @@ -1491,7 +1510,7 @@ KlassHandle defc = attached_method->method_holder(); Symbol* name = attached_method->name(); Symbol* type = attached_method->signature(); - LinkInfo link_info(defc, name, type, KlassHandle(), /*check_access=*/false); + LinkInfo link_info(defc, name, type, KlassHandle(), LinkInfo::skip_access_check); switch(byte) { case Bytecodes::_invokevirtual: resolve_virtual_call(result, recv, recv->klass(), link_info,