comparison src/share/vm/interpreter/linkResolver.cpp @ 12823:ac9cb1d5a202

8009130: Lambda: Fix access controls, loader constraints. Summary: New default methods list with inherited superinterface methods Reviewed-by: minqi, sspitsyn, coleenp
author acorn
date Mon, 07 Oct 2013 12:20:28 -0400
parents 36b97be47bde
children 2f8728d92483 8df6f123d35e
comparison
equal deleted inserted replaced
12822:cc4f5f8d885e 12823:ac9cb1d5a202
1 /* 1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 * 4 *
4 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
219 //------------------------------------------------------------------------------------------------------------------------ 220 //------------------------------------------------------------------------------------------------------------------------
220 // Method resolution 221 // Method resolution
221 // 222 //
222 // According to JVM spec. $5.4.3c & $5.4.3d 223 // According to JVM spec. $5.4.3c & $5.4.3d
223 224
225 // Look up method in klasses, including static methods
226 // Then look up local default methods
224 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 227 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
225 Method* result_oop = klass->uncached_lookup_method(name, signature); 228 Method* result_oop = klass->uncached_lookup_method(name, signature);
229 if (result_oop == NULL) {
230 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
231 if (default_methods != NULL) {
232 result_oop = InstanceKlass::find_method(default_methods, name, signature);
233 }
234 }
235
226 if (EnableInvokeDynamic && result_oop != NULL) { 236 if (EnableInvokeDynamic && result_oop != NULL) {
227 vmIntrinsics::ID iid = result_oop->intrinsic_id(); 237 vmIntrinsics::ID iid = result_oop->intrinsic_id();
228 if (MethodHandles::is_signature_polymorphic(iid)) { 238 if (MethodHandles::is_signature_polymorphic(iid)) {
229 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method. 239 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method.
230 return; 240 return;
232 } 242 }
233 result = methodHandle(THREAD, result_oop); 243 result = methodHandle(THREAD, result_oop);
234 } 244 }
235 245
236 // returns first instance method 246 // returns first instance method
247 // Looks up method in classes, then looks up local default methods
237 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 248 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
238 Method* result_oop = klass->uncached_lookup_method(name, signature); 249 Method* result_oop = klass->uncached_lookup_method(name, signature);
239 result = methodHandle(THREAD, result_oop); 250 result = methodHandle(THREAD, result_oop);
240 while (!result.is_null() && result->is_static()) { 251 while (!result.is_null() && result->is_static()) {
241 klass = KlassHandle(THREAD, result->method_holder()->super()); 252 klass = KlassHandle(THREAD, result->method_holder()->super());
242 result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature)); 253 result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature));
243 } 254 }
244 } 255
245 256 if (result.is_null()) {
246 257 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
247 int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 258 if (default_methods != NULL) {
248 ResourceMark rm(THREAD); 259 result = methodHandle(InstanceKlass::find_method(default_methods, name, signature));
249 klassVtable *vt = InstanceKlass::cast(klass())->vtable(); 260 assert(result.is_null() || !result->is_static(), "static defaults not allowed");
250 return vt->index_of_miranda(name, signature); 261 }
262 }
263 }
264
265 int LinkResolver::vtable_index_of_interface_method(KlassHandle klass,
266 methodHandle resolved_method, TRAPS) {
267
268 int vtable_index = Method::invalid_vtable_index;
269 Symbol* name = resolved_method->name();
270 Symbol* signature = resolved_method->signature();
271
272 // First check in default method array
273 if (!resolved_method->is_abstract() &&
274 (InstanceKlass::cast(klass())->default_methods() != NULL)) {
275 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature);
276 if (index >= 0 ) {
277 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
278 }
279 }
280 if (vtable_index == Method::invalid_vtable_index) {
281 // get vtable_index for miranda methods
282 ResourceMark rm(THREAD);
283 klassVtable *vt = InstanceKlass::cast(klass())->vtable();
284 vtable_index = vt->index_of_miranda(name, signature);
285 }
286 return vtable_index;
251 } 287 }
252 288
253 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 289 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
254 InstanceKlass *ik = InstanceKlass::cast(klass()); 290 InstanceKlass *ik = InstanceKlass::cast(klass());
255 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature)); 291 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature));
623 resolved_method->name(), 659 resolved_method->name(),
624 resolved_method->signature()), 660 resolved_method->signature()),
625 resolved_method->method_holder()->internal_name() 661 resolved_method->method_holder()->internal_name()
626 ); 662 );
627 resolved_method->access_flags().print_on(tty); 663 resolved_method->access_flags().print_on(tty);
664 if (resolved_method->is_default_method()) {
665 tty->print("default");
666 }
667 if (resolved_method->is_overpass()) {
668 tty->print("overpass");
669 }
628 tty->cr(); 670 tty->cr();
629 } 671 }
630 } 672 }
631 673
632 //------------------------------------------------------------------------------------------------------------------------ 674 //------------------------------------------------------------------------------------------------------------------------
851 Method::name_and_sig_as_C_string(resolved_klass(), 893 Method::name_and_sig_as_C_string(resolved_klass(),
852 resolved_method->name(), 894 resolved_method->name(),
853 resolved_method->signature())); 895 resolved_method->signature()));
854 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 896 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
855 } 897 }
898
856 if (TraceItables && Verbose) { 899 if (TraceItables && Verbose) {
857 ResourceMark rm(THREAD); 900 ResourceMark rm(THREAD);
858 tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", 901 tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
859 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), 902 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
860 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), 903 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
862 resolved_method->name(), 905 resolved_method->name(),
863 resolved_method->signature()), 906 resolved_method->signature()),
864 resolved_method->method_holder()->internal_name() 907 resolved_method->method_holder()->internal_name()
865 ); 908 );
866 resolved_method->access_flags().print_on(tty); 909 resolved_method->access_flags().print_on(tty);
867 if (resolved_method->method_holder()->is_interface() && 910 if (resolved_method->is_default_method()) {
868 !resolved_method->is_abstract()) {
869 tty->print("default"); 911 tty->print("default");
870 } 912 }
871 if (resolved_method->is_overpass()) { 913 if (resolved_method->is_overpass()) {
872 tty->print("overpass"); 914 tty->print("overpass");
873 } 915 }
943 sel_method->name(), 985 sel_method->name(),
944 sel_method->signature()), 986 sel_method->signature()),
945 sel_method->method_holder()->internal_name() 987 sel_method->method_holder()->internal_name()
946 ); 988 );
947 sel_method->access_flags().print_on(tty); 989 sel_method->access_flags().print_on(tty);
948 if (sel_method->method_holder()->is_interface() && 990 if (sel_method->is_default_method()) {
949 !sel_method->is_abstract()) {
950 tty->print("default"); 991 tty->print("default");
992 }
993 if (sel_method->is_overpass()) {
994 tty->print("overpass");
951 } 995 }
952 tty->cr(); 996 tty->cr();
953 } 997 }
954 998
955 // setup result 999 // setup result
994 resolved_method->name(), 1038 resolved_method->name(),
995 resolved_method->signature())); 1039 resolved_method->signature()));
996 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 1040 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
997 } 1041 }
998 1042
999 if (PrintVtables && Verbose) { 1043 if (PrintVtables && Verbose) {
1000 ResourceMark rm(THREAD); 1044 ResourceMark rm(THREAD);
1001 tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", 1045 tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
1002 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), 1046 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
1003 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), 1047 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
1004 Method::name_and_sig_as_C_string(resolved_klass(), 1048 Method::name_and_sig_as_C_string(resolved_klass(),
1005 resolved_method->name(), 1049 resolved_method->name(),
1006 resolved_method->signature()), 1050 resolved_method->signature()),
1007 resolved_method->method_holder()->internal_name() 1051 resolved_method->method_holder()->internal_name()
1008 ); 1052 );
1009 resolved_method->access_flags().print_on(tty); 1053 resolved_method->access_flags().print_on(tty);
1010 if (resolved_method->method_holder()->is_interface() && 1054 if (resolved_method->is_default_method()) {
1011 !resolved_method->is_abstract()) { 1055 tty->print("default");
1012 tty->print("default"); 1056 }
1013 } 1057 if (resolved_method->is_overpass()) {
1014 if (resolved_method->is_overpass()) { 1058 tty->print("overpass");
1015 tty->print("overpass"); 1059 }
1016 } 1060 tty->cr();
1017 tty->cr(); 1061 }
1018 }
1019 } 1062 }
1020 1063
1021 // throws runtime exceptions 1064 // throws runtime exceptions
1022 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, 1065 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
1023 methodHandle resolved_method, 1066 methodHandle resolved_method,
1043 // a missing receiver might result in a bogus lookup. 1086 // a missing receiver might result in a bogus lookup.
1044 assert(resolved_method->method_holder()->is_linked(), "must be linked"); 1087 assert(resolved_method->method_holder()->is_linked(), "must be linked");
1045 1088
1046 // do lookup based on receiver klass using the vtable index 1089 // do lookup based on receiver klass using the vtable index
1047 if (resolved_method->method_holder()->is_interface()) { // miranda method 1090 if (resolved_method->method_holder()->is_interface()) { // miranda method
1048 vtable_index = vtable_index_of_miranda_method(resolved_klass, 1091 vtable_index = vtable_index_of_interface_method(resolved_klass,
1049 resolved_method->name(), 1092 resolved_method, CHECK);
1050 resolved_method->signature(), CHECK);
1051
1052 assert(vtable_index >= 0 , "we should have valid vtable index at this point"); 1093 assert(vtable_index >= 0 , "we should have valid vtable index at this point");
1053 1094
1054 InstanceKlass* inst = InstanceKlass::cast(recv_klass()); 1095 InstanceKlass* inst = InstanceKlass::cast(recv_klass());
1055 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); 1096 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
1056 } else { 1097 } else {
1102 resolved_method->signature()), 1143 resolved_method->signature()),
1103 selected_method->method_holder()->internal_name(), 1144 selected_method->method_holder()->internal_name(),
1104 vtable_index 1145 vtable_index
1105 ); 1146 );
1106 selected_method->access_flags().print_on(tty); 1147 selected_method->access_flags().print_on(tty);
1107 if (selected_method->method_holder()->is_interface() && 1148 if (selected_method->is_default_method()) {
1108 !selected_method->is_abstract()) {
1109 tty->print("default"); 1149 tty->print("default");
1110 } 1150 }
1111 if (resolved_method->is_overpass()) { 1151 if (selected_method->is_overpass()) {
1112 tty->print("overpass"); 1152 tty->print("overpass");
1113 } 1153 }
1114 tty->cr(); 1154 tty->cr();
1115 } 1155 }
1116 // setup result 1156 // setup result
1189 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), 1229 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
1190 Method::name_and_sig_as_C_string(recv_klass(), 1230 Method::name_and_sig_as_C_string(recv_klass(),
1191 sel_method->name(), 1231 sel_method->name(),
1192 sel_method->signature())); 1232 sel_method->signature()));
1193 } 1233 }
1194
1195 // check if abstract 1234 // check if abstract
1196 if (check_null_and_abstract && sel_method->is_abstract()) { 1235 if (check_null_and_abstract && sel_method->is_abstract()) {
1197 ResourceMark rm(THREAD); 1236 ResourceMark rm(THREAD);
1198 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1237 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1199 Method::name_and_sig_as_C_string(recv_klass(), 1238 Method::name_and_sig_as_C_string(recv_klass(),
1218 resolved_method->name(), 1257 resolved_method->name(),
1219 resolved_method->signature()), 1258 resolved_method->signature()),
1220 sel_method->method_holder()->internal_name() 1259 sel_method->method_holder()->internal_name()
1221 ); 1260 );
1222 sel_method->access_flags().print_on(tty); 1261 sel_method->access_flags().print_on(tty);
1223 if (sel_method->method_holder()->is_interface() && 1262 if (sel_method->is_default_method()) {
1224 !sel_method->is_abstract()) {
1225 tty->print("default"); 1263 tty->print("default");
1226 } 1264 }
1227 if (resolved_method->is_overpass()) { 1265 if (sel_method->is_overpass()) {
1228 tty->print("overpass"); 1266 tty->print("overpass");
1229 } 1267 }
1230 tty->cr(); 1268 tty->cr();
1231 } 1269 }
1232 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); 1270 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);