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 } |
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); |