Tue, 01 Aug 2017 09:47:45 -0400
8180711: Better invokespecial checks
Reviewed-by: acorn, ahgross, rhalade
Contributed-by: harold.seigel@oracle.com
src/share/vm/interpreter/linkResolver.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/interpreter/linkResolver.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/interpreter/linkResolver.cpp Wed Jul 26 22:52:34 2017 -0700 1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp Tue Aug 01 09:47:45 2017 -0400 1.3 @@ -540,6 +540,42 @@ 1.4 } 1.5 } 1.6 1.7 +void LinkResolver::check_method_loader_constraints(methodHandle& resolved_method, 1.8 + KlassHandle resolved_klass, 1.9 + Symbol* method_name, 1.10 + Symbol* method_signature, 1.11 + KlassHandle current_klass, 1.12 + const char* method_type, TRAPS) { 1.13 + Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); 1.14 + Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); 1.15 + { 1.16 + ResourceMark rm(THREAD); 1.17 + Symbol* failed_type_symbol = 1.18 + SystemDictionary::check_signature_loaders(method_signature, loader, 1.19 + class_loader, true, CHECK); 1.20 + if (failed_type_symbol != NULL) { 1.21 + const char* msg = "loader constraint violation: when resolving %s" 1.22 + " \"%s\" the class loader (instance of %s) of the current class, %s," 1.23 + " and the class loader (instance of %s) for the method's defining class, %s, have" 1.24 + " different Class objects for the type %s used in the signature"; 1.25 + char* sig = Method::name_and_sig_as_C_string(resolved_klass(), method_name, method_signature); 1.26 + const char* loader1 = SystemDictionary::loader_name(loader()); 1.27 + char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); 1.28 + const char* loader2 = SystemDictionary::loader_name(class_loader()); 1.29 + char* target = InstanceKlass::cast(resolved_method->method_holder()) 1.30 + ->name()->as_C_string(); 1.31 + char* failed_type_name = failed_type_symbol->as_C_string(); 1.32 + size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + 1.33 + strlen(current) + strlen(loader2) + strlen(target) + 1.34 + strlen(failed_type_name) + strlen(method_type) + 1; 1.35 + char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); 1.36 + jio_snprintf(buf, buflen, msg, method_type, sig, loader1, current, loader2, 1.37 + target, failed_type_name); 1.38 + THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); 1.39 + } 1.40 + } 1.41 +} 1.42 + 1.43 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, 1.44 Symbol* method_name, Symbol* method_signature, 1.45 KlassHandle current_klass, bool check_access, 1.46 @@ -596,34 +632,8 @@ 1.47 CHECK); 1.48 1.49 // check loader constraints 1.50 - Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); 1.51 - Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); 1.52 - { 1.53 - ResourceMark rm(THREAD); 1.54 - Symbol* failed_type_symbol = 1.55 - SystemDictionary::check_signature_loaders(method_signature, loader, 1.56 - class_loader, true, CHECK); 1.57 - if (failed_type_symbol != NULL) { 1.58 - const char* msg = "loader constraint violation: when resolving method" 1.59 - " \"%s\" the class loader (instance of %s) of the current class, %s," 1.60 - " and the class loader (instance of %s) for the method's defining class, %s, have" 1.61 - " different Class objects for the type %s used in the signature"; 1.62 - char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature); 1.63 - const char* loader1 = SystemDictionary::loader_name(loader()); 1.64 - char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); 1.65 - const char* loader2 = SystemDictionary::loader_name(class_loader()); 1.66 - char* target = InstanceKlass::cast(resolved_method->method_holder()) 1.67 - ->name()->as_C_string(); 1.68 - char* failed_type_name = failed_type_symbol->as_C_string(); 1.69 - size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + 1.70 - strlen(current) + strlen(loader2) + strlen(target) + 1.71 - strlen(failed_type_name) + 1; 1.72 - char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); 1.73 - jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, 1.74 - target, failed_type_name); 1.75 - THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); 1.76 - } 1.77 - } 1.78 + check_method_loader_constraints(resolved_method, resolved_klass, method_name, 1.79 + method_signature, current_klass, "method", CHECK); 1.80 } 1.81 } 1.82 1.83 @@ -672,36 +682,8 @@ 1.84 resolved_method, 1.85 CHECK); 1.86 1.87 - HandleMark hm(THREAD); 1.88 - Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); 1.89 - Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); 1.90 - { 1.91 - ResourceMark rm(THREAD); 1.92 - Symbol* failed_type_symbol = 1.93 - SystemDictionary::check_signature_loaders(method_signature, loader, 1.94 - class_loader, true, CHECK); 1.95 - if (failed_type_symbol != NULL) { 1.96 - const char* msg = "loader constraint violation: when resolving " 1.97 - "interface method \"%s\" the class loader (instance of %s) of the " 1.98 - "current class, %s, and the class loader (instance of %s) for " 1.99 - "the method's defining class, %s, have different Class objects for the type %s " 1.100 - "used in the signature"; 1.101 - char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature); 1.102 - const char* loader1 = SystemDictionary::loader_name(loader()); 1.103 - char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); 1.104 - const char* loader2 = SystemDictionary::loader_name(class_loader()); 1.105 - char* target = InstanceKlass::cast(resolved_method->method_holder()) 1.106 - ->name()->as_C_string(); 1.107 - char* failed_type_name = failed_type_symbol->as_C_string(); 1.108 - size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + 1.109 - strlen(current) + strlen(loader2) + strlen(target) + 1.110 - strlen(failed_type_name) + 1; 1.111 - char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); 1.112 - jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, 1.113 - target, failed_type_name); 1.114 - THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); 1.115 - } 1.116 - } 1.117 + check_method_loader_constraints(resolved_method, resolved_klass, method_name, 1.118 + method_signature, current_klass, "interface method", CHECK); 1.119 } 1.120 1.121 if (nostatics && resolved_method->is_static()) { 1.122 @@ -1051,6 +1033,10 @@ 1.123 Method::name_and_sig_as_C_string(resolved_klass(), 1.124 resolved_method->name(), 1.125 resolved_method->signature())); 1.126 + } else if (sel_method() != resolved_method()) { 1.127 + check_method_loader_constraints(sel_method, resolved_klass, 1.128 + sel_method->name(), sel_method->signature(), 1.129 + current_klass, "method", CHECK); 1.130 } 1.131 } 1.132
2.1 --- a/src/share/vm/interpreter/linkResolver.hpp Wed Jul 26 22:52:34 2017 -0700 2.2 +++ b/src/share/vm/interpreter/linkResolver.hpp Tue Aug 01 09:47:45 2017 -0400 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -135,6 +135,9 @@ 2.11 static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); 2.12 2.13 static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool nostatics, TRAPS); 2.14 + static void check_method_loader_constraints(methodHandle& resolved_method, KlassHandle resolved_klass, 2.15 + Symbol* method_name, Symbol* method_signature, 2.16 + KlassHandle current_klass, const char* method_type, TRAPS); 2.17 static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool require_methodref, TRAPS); 2.18 2.19 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);