# HG changeset patch # User hseigel # Date 1501595265 14400 # Node ID a21a0e7df91dfd4fd8c2e79eb26342a3e0fc1fb2 # Parent dabc0ba4b1a6a46e63568e3ca0ff1ab21ad99294 8180711: Better invokespecial checks Reviewed-by: acorn, ahgross, rhalade Contributed-by: harold.seigel@oracle.com diff -r dabc0ba4b1a6 -r a21a0e7df91d src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Wed Aug 30 15:42:01 2017 +0300 +++ b/src/share/vm/interpreter/linkResolver.cpp Tue Aug 01 09:47:45 2017 -0400 @@ -342,6 +342,42 @@ } +void LinkResolver::check_method_loader_constraints(methodHandle& resolved_method, + KlassHandle resolved_klass, + Symbol* method_name, + Symbol* method_signature, + KlassHandle current_klass, + const char* method_type, TRAPS) { + Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); + Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); + { + ResourceMark rm(THREAD); + char* failed_type_name = + SystemDictionary::check_signature_loaders(method_signature, loader, + class_loader, true, CHECK); + if (failed_type_name != NULL) { + const char* msg = "loader constraint violation: when resolving %s" + " \"%s\" the class loader (instance of %s) of the current class, %s," + " and the class loader (instance of %s) for the method's defining class, %s, have" + " different Class objects for the type %s used in the signature"; + char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + method_name, method_signature); + const char* loader1 = SystemDictionary::loader_name(loader()); + char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); + const char* loader2 = SystemDictionary::loader_name(class_loader()); + char* target = instanceKlass::cast(resolved_method->method_holder()) + ->name()->as_C_string(); + size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + + strlen(current) + strlen(loader2) + strlen(target) + + strlen(failed_type_name) + strlen(method_type) + 1; + char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); + jio_snprintf(buf, buflen, msg, method_type, sig, loader1, current, loader2, + target, failed_type_name); + THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); + } + } +} + void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { @@ -397,32 +433,8 @@ CHECK); // check loader constraints - Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); - Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); - { - ResourceMark rm(THREAD); - char* failed_type_name = - SystemDictionary::check_signature_loaders(method_signature, loader, - class_loader, true, CHECK); - if (failed_type_name != NULL) { - const char* msg = "loader constraint violation: when resolving method" - " \"%s\" the class loader (instance of %s) of the current class, %s," - " and the class loader (instance of %s) for resolved class, %s, have" - " different Class objects for the type %s used in the signature"; - char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); - const char* loader1 = SystemDictionary::loader_name(loader()); - char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); - const char* loader2 = SystemDictionary::loader_name(class_loader()); - char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string(); - size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + - strlen(current) + strlen(loader2) + strlen(resolved) + - strlen(failed_type_name); - char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); - jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, - resolved, failed_type_name); - THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); - } - } + check_method_loader_constraints(resolved_method, resolved_klass, method_name, + method_signature, current_klass, "method", CHECK); } } @@ -459,34 +471,8 @@ } if (check_access) { - HandleMark hm(THREAD); - Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); - Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); - { - ResourceMark rm(THREAD); - char* failed_type_name = - SystemDictionary::check_signature_loaders(method_signature, loader, - class_loader, true, CHECK); - if (failed_type_name != NULL) { - const char* msg = "loader constraint violation: when resolving " - "interface method \"%s\" the class loader (instance of %s) of the " - "current class, %s, and the class loader (instance of %s) for " - "resolved class, %s, have different Class objects for the type %s " - "used in the signature"; - char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); - const char* loader1 = SystemDictionary::loader_name(loader()); - char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); - const char* loader2 = SystemDictionary::loader_name(class_loader()); - char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string(); - size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + - strlen(current) + strlen(loader2) + strlen(resolved) + - strlen(failed_type_name); - char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); - jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, - resolved, failed_type_name); - THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); - } - } + check_method_loader_constraints(resolved_method, resolved_klass, method_name, + method_signature, current_klass, "interface method", CHECK); } } @@ -738,6 +724,10 @@ methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), resolved_method->name(), resolved_method->signature())); + } else if (sel_method() != resolved_method()) { + check_method_loader_constraints(sel_method, resolved_klass, + sel_method->name(), sel_method->signature(), + current_klass, "method", CHECK); } } } diff -r dabc0ba4b1a6 -r a21a0e7df91d src/share/vm/interpreter/linkResolver.hpp --- a/src/share/vm/interpreter/linkResolver.hpp Wed Aug 30 15:42:01 2017 +0300 +++ b/src/share/vm/interpreter/linkResolver.hpp Tue Aug 01 09:47:45 2017 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -121,6 +121,9 @@ static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void check_method_loader_constraints(methodHandle& resolved_method, KlassHandle resolved_klass, + Symbol* method_name, Symbol* method_signature, + KlassHandle current_klass, const char* method_type, TRAPS); static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);