comparison src/share/vm/interpreter/linkResolver.cpp @ 13055:fce21ac5968d

8027229: ICCE expected for >=2 maximally specific default methods. Summary: Need to process defaults for interfaces for invokespecial Reviewed-by: lfoltan, hseigel, coleenp, jrose
author acorn
date Wed, 13 Nov 2013 07:31:26 -0800
parents 662c154d2749
children 096c224171c4 22eaa15b7960
comparison
equal deleted inserted replaced
13054:19f8a5d7600b 13055:fce21ac5968d
150 kind = CallInfo::direct_call; 150 kind = CallInfo::direct_call;
151 } else if (!resolved_method_holder->is_interface()) { 151 } else if (!resolved_method_holder->is_interface()) {
152 // Could be an Object method inherited into an interface, but still a vtable call. 152 // Could be an Object method inherited into an interface, but still a vtable call.
153 kind = CallInfo::vtable_call; 153 kind = CallInfo::vtable_call;
154 } else if (!resolved_klass->is_interface()) { 154 } else if (!resolved_klass->is_interface()) {
155 // A miranda method. Compute the vtable index. 155 // A default or miranda method. Compute the vtable index.
156 ResourceMark rm; 156 ResourceMark rm;
157 klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable(); 157 klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable();
158 index = vt->index_of_miranda(resolved_method->name(), 158 index = LinkResolver::vtable_index_of_interface_method(resolved_klass,
159 resolved_method->signature()); 159 resolved_method);
160 assert(index >= 0 , "we should have valid vtable index at this point");
161
160 kind = CallInfo::vtable_call; 162 kind = CallInfo::vtable_call;
161 } else if (resolved_method->has_vtable_index()) { 163 } else if (resolved_method->has_vtable_index()) {
162 // Can occur if an interface redeclares a method of Object. 164 // Can occur if an interface redeclares a method of Object.
163 165
164 #ifdef ASSERT 166 #ifdef ASSERT
277 } 279 }
278 } 280 }
279 } 281 }
280 282
281 int LinkResolver::vtable_index_of_interface_method(KlassHandle klass, 283 int LinkResolver::vtable_index_of_interface_method(KlassHandle klass,
282 methodHandle resolved_method, TRAPS) { 284 methodHandle resolved_method) {
283 285
284 int vtable_index = Method::invalid_vtable_index; 286 int vtable_index = Method::invalid_vtable_index;
285 Symbol* name = resolved_method->name(); 287 Symbol* name = resolved_method->name();
286 Symbol* signature = resolved_method->signature(); 288 Symbol* signature = resolved_method->signature();
287 289
293 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); 295 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
294 } 296 }
295 } 297 }
296 if (vtable_index == Method::invalid_vtable_index) { 298 if (vtable_index == Method::invalid_vtable_index) {
297 // get vtable_index for miranda methods 299 // get vtable_index for miranda methods
298 ResourceMark rm(THREAD); 300 ResourceMark rm;
299 klassVtable *vt = InstanceKlass::cast(klass())->vtable(); 301 klassVtable *vt = InstanceKlass::cast(klass())->vtable();
300 vtable_index = vt->index_of_miranda(name, signature); 302 vtable_index = vt->index_of_miranda(name, signature);
301 } 303 }
302 return vtable_index; 304 return vtable_index;
303 } 305 }
689 resolved_method->signature()), 691 resolved_method->signature()),
690 resolved_method->method_holder()->internal_name() 692 resolved_method->method_holder()->internal_name()
691 ); 693 );
692 resolved_method->access_flags().print_on(tty); 694 resolved_method->access_flags().print_on(tty);
693 if (resolved_method->is_default_method()) { 695 if (resolved_method->is_default_method()) {
694 tty->print("default"); 696 tty->print("default ");
695 } 697 }
696 if (resolved_method->is_overpass()) { 698 if (resolved_method->is_overpass()) {
697 tty->print("overpass"); 699 tty->print("overpass");
698 } 700 }
699 tty->cr(); 701 tty->cr();
935 resolved_method->signature()), 937 resolved_method->signature()),
936 resolved_method->method_holder()->internal_name() 938 resolved_method->method_holder()->internal_name()
937 ); 939 );
938 resolved_method->access_flags().print_on(tty); 940 resolved_method->access_flags().print_on(tty);
939 if (resolved_method->is_default_method()) { 941 if (resolved_method->is_default_method()) {
940 tty->print("default"); 942 tty->print("default ");
941 } 943 }
942 if (resolved_method->is_overpass()) { 944 if (resolved_method->is_overpass()) {
943 tty->print("overpass"); 945 tty->print("overpass");
944 } 946 }
945 tty->cr(); 947 tty->cr();
1015 sel_method->signature()), 1017 sel_method->signature()),
1016 sel_method->method_holder()->internal_name() 1018 sel_method->method_holder()->internal_name()
1017 ); 1019 );
1018 sel_method->access_flags().print_on(tty); 1020 sel_method->access_flags().print_on(tty);
1019 if (sel_method->is_default_method()) { 1021 if (sel_method->is_default_method()) {
1020 tty->print("default"); 1022 tty->print("default ");
1021 } 1023 }
1022 if (sel_method->is_overpass()) { 1024 if (sel_method->is_overpass()) {
1023 tty->print("overpass"); 1025 tty->print("overpass");
1024 } 1026 }
1025 tty->cr(); 1027 tty->cr();
1079 resolved_method->signature()), 1081 resolved_method->signature()),
1080 resolved_method->method_holder()->internal_name() 1082 resolved_method->method_holder()->internal_name()
1081 ); 1083 );
1082 resolved_method->access_flags().print_on(tty); 1084 resolved_method->access_flags().print_on(tty);
1083 if (resolved_method->is_default_method()) { 1085 if (resolved_method->is_default_method()) {
1084 tty->print("default"); 1086 tty->print("default ");
1085 } 1087 }
1086 if (resolved_method->is_overpass()) { 1088 if (resolved_method->is_overpass()) {
1087 tty->print("overpass"); 1089 tty->print("overpass");
1088 } 1090 }
1089 tty->cr(); 1091 tty->cr();
1116 assert(resolved_method->method_holder()->is_linked(), "must be linked"); 1118 assert(resolved_method->method_holder()->is_linked(), "must be linked");
1117 1119
1118 // do lookup based on receiver klass using the vtable index 1120 // do lookup based on receiver klass using the vtable index
1119 if (resolved_method->method_holder()->is_interface()) { // miranda method 1121 if (resolved_method->method_holder()->is_interface()) { // miranda method
1120 vtable_index = vtable_index_of_interface_method(resolved_klass, 1122 vtable_index = vtable_index_of_interface_method(resolved_klass,
1121 resolved_method, CHECK); 1123 resolved_method);
1122 assert(vtable_index >= 0 , "we should have valid vtable index at this point"); 1124 assert(vtable_index >= 0 , "we should have valid vtable index at this point");
1123 1125
1124 InstanceKlass* inst = InstanceKlass::cast(recv_klass()); 1126 InstanceKlass* inst = InstanceKlass::cast(recv_klass());
1125 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); 1127 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
1126 } else { 1128 } else {
1173 selected_method->method_holder()->internal_name(), 1175 selected_method->method_holder()->internal_name(),
1174 vtable_index 1176 vtable_index
1175 ); 1177 );
1176 selected_method->access_flags().print_on(tty); 1178 selected_method->access_flags().print_on(tty);
1177 if (selected_method->is_default_method()) { 1179 if (selected_method->is_default_method()) {
1178 tty->print("default"); 1180 tty->print("default ");
1179 } 1181 }
1180 if (selected_method->is_overpass()) { 1182 if (selected_method->is_overpass()) {
1181 tty->print("overpass"); 1183 tty->print("overpass");
1182 } 1184 }
1183 tty->cr(); 1185 tty->cr();
1266 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1268 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1267 Method::name_and_sig_as_C_string(recv_klass(), 1269 Method::name_and_sig_as_C_string(recv_klass(),
1268 sel_method->name(), 1270 sel_method->name(),
1269 sel_method->signature())); 1271 sel_method->signature()));
1270 } 1272 }
1271 // setup result
1272 if (!resolved_method->has_itable_index()) {
1273 int vtable_index = resolved_method->vtable_index();
1274 assert(vtable_index == sel_method->vtable_index(), "sanity check");
1275 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
1276 return;
1277 }
1278 int itable_index = resolved_method()->itable_index();
1279 1273
1280 if (TraceItables && Verbose) { 1274 if (TraceItables && Verbose) {
1281 ResourceMark rm(THREAD); 1275 ResourceMark rm(THREAD);
1282 tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ", 1276 tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
1283 (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()), 1277 (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
1287 resolved_method->signature()), 1281 resolved_method->signature()),
1288 sel_method->method_holder()->internal_name() 1282 sel_method->method_holder()->internal_name()
1289 ); 1283 );
1290 sel_method->access_flags().print_on(tty); 1284 sel_method->access_flags().print_on(tty);
1291 if (sel_method->is_default_method()) { 1285 if (sel_method->is_default_method()) {
1292 tty->print("default"); 1286 tty->print("default ");
1293 } 1287 }
1294 if (sel_method->is_overpass()) { 1288 if (sel_method->is_overpass()) {
1295 tty->print("overpass"); 1289 tty->print("overpass");
1296 } 1290 }
1297 tty->cr(); 1291 tty->cr();
1298 } 1292 }
1299 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); 1293 // setup result
1294 if (!resolved_method->has_itable_index()) {
1295 int vtable_index = resolved_method->vtable_index();
1296 assert(vtable_index == sel_method->vtable_index(), "sanity check");
1297 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
1298 } else {
1299 int itable_index = resolved_method()->itable_index();
1300 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
1301 }
1300 } 1302 }
1301 1303
1302 1304
1303 methodHandle LinkResolver::linktime_resolve_interface_method_or_null( 1305 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
1304 KlassHandle resolved_klass, 1306 KlassHandle resolved_klass,