src/hotspot/share/interpreter/linkResolver.cpp
changeset 49368 2ed1c37df3a5
parent 49359 59f6547e151f
child 49449 ef5d5d343e2a
equal deleted inserted replaced
49366:f95ef5511e1f 49368:2ed1c37df3a5
  1342   // a missing receiver might result in a bogus lookup.
  1342   // a missing receiver might result in a bogus lookup.
  1343   assert(resolved_method->method_holder()->is_linked(), "must be linked");
  1343   assert(resolved_method->method_holder()->is_linked(), "must be linked");
  1344 
  1344 
  1345   // do lookup based on receiver klass using the vtable index
  1345   // do lookup based on receiver klass using the vtable index
  1346   if (resolved_method->method_holder()->is_interface()) { // default or miranda method
  1346   if (resolved_method->method_holder()->is_interface()) { // default or miranda method
  1347     vtable_index = vtable_index_of_interface_method(resolved_klass,
  1347     vtable_index = vtable_index_of_interface_method(resolved_klass, resolved_method);
  1348                            resolved_method);
       
  1349     assert(vtable_index >= 0 , "we should have valid vtable index at this point");
  1348     assert(vtable_index >= 0 , "we should have valid vtable index at this point");
  1350 
  1349 
  1351     selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
  1350     selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
  1352   } else {
  1351   } else {
  1353     // at this point we are sure that resolved_method is virtual and not
  1352     // at this point we are sure that resolved_method is virtual and not
  1354     // a default or miranda method; therefore, it must have a valid vtable index.
  1353     // a default or miranda method; therefore, it must have a valid vtable index.
  1355     assert(!resolved_method->has_itable_index(), "");
  1354     assert(!resolved_method->has_itable_index(), "");
  1356     vtable_index = resolved_method->vtable_index();
  1355     vtable_index = resolved_method->vtable_index();
  1357     // We could get a negative vtable_index for final methods,
  1356     // We could get a negative vtable_index for final methods,
  1358     // because as an optimization they are they are never put in the vtable,
  1357     // because as an optimization they are never put in the vtable,
  1359     // unless they override an existing method.
  1358     // unless they override an existing method.
  1360     // If we do get a negative, it means the resolved method is the the selected
  1359     // If we do get a negative, it means the resolved method is the the selected
  1361     // method, and it can never be changed by an override.
  1360     // method, and it can never be changed by an override.
  1362     if (vtable_index == Method::nonvirtual_vtable_index) {
  1361     if (vtable_index == Method::nonvirtual_vtable_index) {
  1363       assert(resolved_method->can_be_statically_bound(), "cannot override this method");
  1362       assert(resolved_method->can_be_statically_bound(), "cannot override this method");
  1367     }
  1366     }
  1368   }
  1367   }
  1369 
  1368 
  1370   // check if method exists
  1369   // check if method exists
  1371   if (selected_method.is_null()) {
  1370   if (selected_method.is_null()) {
  1372     ResourceMark rm(THREAD);
  1371     throw_abstract_method_error(resolved_method, recv_klass, CHECK);
  1373     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
       
  1374               Method::name_and_sig_as_C_string(resolved_klass,
       
  1375                                                resolved_method->name(),
       
  1376                                                resolved_method->signature()));
       
  1377   }
  1372   }
  1378 
  1373 
  1379   // check if abstract
  1374   // check if abstract
  1380   if (check_null_and_abstract && selected_method->is_abstract()) {
  1375   if (check_null_and_abstract && selected_method->is_abstract()) {
  1381     ResourceMark rm(THREAD);
  1376     // Pass arguments for generating a verbose error message.
  1382     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
  1377     throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK);
  1383               Method::name_and_sig_as_C_string(resolved_klass,
       
  1384                                                selected_method->name(),
       
  1385                                                selected_method->signature()));
       
  1386   }
  1378   }
  1387 
  1379 
  1388   if (log_develop_is_enabled(Trace, vtables)) {
  1380   if (log_develop_is_enabled(Trace, vtables)) {
  1389     trace_method_resolution("invokevirtual selected method: receiver-class:",
  1381     trace_method_resolution("invokevirtual selected method: receiver-class:",
  1390                             recv_klass, resolved_klass, selected_method,
  1382                             recv_klass, resolved_klass, selected_method,
  1436   }
  1428   }
  1437 
  1429 
  1438   // do lookup based on receiver klass
  1430   // do lookup based on receiver klass
  1439   // This search must match the linktime preparation search for itable initialization
  1431   // This search must match the linktime preparation search for itable initialization
  1440   // to correctly enforce loader constraints for interface method inheritance
  1432   // to correctly enforce loader constraints for interface method inheritance
  1441   methodHandle sel_method = lookup_instance_method_in_klasses(recv_klass,
  1433   methodHandle selected_method = lookup_instance_method_in_klasses(recv_klass,
  1442                                                   resolved_method->name(),
  1434                                                   resolved_method->name(),
  1443                                                   resolved_method->signature(), CHECK);
  1435                                                   resolved_method->signature(), CHECK);
  1444   if (sel_method.is_null() && !check_null_and_abstract) {
  1436   if (selected_method.is_null() && !check_null_and_abstract) {
  1445     // In theory this is a harmless placeholder value, but
  1437     // In theory this is a harmless placeholder value, but
  1446     // in practice leaving in null affects the nsk default method tests.
  1438     // in practice leaving in null affects the nsk default method tests.
  1447     // This needs further study.
  1439     // This needs further study.
  1448     sel_method = resolved_method;
  1440     selected_method = resolved_method;
  1449   }
  1441   }
  1450   // check if method exists
  1442   // check if method exists
  1451   if (sel_method.is_null()) {
  1443   if (selected_method.is_null()) {
  1452     ResourceMark rm(THREAD);
  1444     // Pass arguments for generating a verbose error message.
  1453     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
  1445     throw_abstract_method_error(resolved_method, recv_klass, CHECK);
  1454                    Method::name_and_sig_as_C_string(recv_klass,
       
  1455                                                     resolved_method->name(),
       
  1456                                                     resolved_method->signature()));
       
  1457   }
  1446   }
  1458   // check access
  1447   // check access
  1459   // Throw Illegal Access Error if sel_method is not public.
  1448   // Throw Illegal Access Error if selected_method is not public.
  1460   if (!sel_method->is_public()) {
  1449   if (!selected_method->is_public()) {
  1461     ResourceMark rm(THREAD);
  1450     ResourceMark rm(THREAD);
  1462     THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
  1451     THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
  1463               Method::name_and_sig_as_C_string(recv_klass,
  1452               Method::name_and_sig_as_C_string(recv_klass,
  1464                                                sel_method->name(),
  1453                                                selected_method->name(),
  1465                                                sel_method->signature()));
  1454                                                selected_method->signature()));
  1466   }
  1455   }
  1467   // check if abstract
  1456   // check if abstract
  1468   if (check_null_and_abstract && sel_method->is_abstract()) {
  1457   if (check_null_and_abstract && selected_method->is_abstract()) {
  1469     ResourceMark rm(THREAD);
  1458     throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK);
  1470     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
       
  1471               Method::name_and_sig_as_C_string(recv_klass,
       
  1472                                                sel_method->name(),
       
  1473                                                sel_method->signature()));
       
  1474   }
  1459   }
  1475 
  1460 
  1476   if (log_develop_is_enabled(Trace, itables)) {
  1461   if (log_develop_is_enabled(Trace, itables)) {
  1477     trace_method_resolution("invokeinterface selected method: receiver-class:",
  1462     trace_method_resolution("invokeinterface selected method: receiver-class:",
  1478                             recv_klass, resolved_klass, sel_method, true);
  1463                             recv_klass, resolved_klass, selected_method, true);
  1479   }
  1464   }
  1480   // setup result
  1465   // setup result
  1481   if (!resolved_method->has_itable_index()) {
  1466   if (!resolved_method->has_itable_index()) {
  1482     int vtable_index = resolved_method->vtable_index();
  1467     int vtable_index = resolved_method->vtable_index();
  1483     assert(vtable_index == sel_method->vtable_index(), "sanity check");
  1468     assert(vtable_index == selected_method->vtable_index(), "sanity check");
  1484     result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
  1469     result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
  1485   } else {
  1470   } else {
  1486     int itable_index = resolved_method()->itable_index();
  1471     int itable_index = resolved_method()->itable_index();
  1487     result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
  1472     result.set_interface(resolved_klass, recv_klass, resolved_method, selected_method, itable_index, CHECK);
  1488   }
  1473   }
  1489 }
  1474 }
  1490 
  1475 
  1491 
  1476 
  1492 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
  1477 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
  1772                                                      THREAD);
  1757                                                      THREAD);
  1773   Exceptions::wrap_dynamic_exception(CHECK);
  1758   Exceptions::wrap_dynamic_exception(CHECK);
  1774   result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
  1759   result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
  1775   Exceptions::wrap_dynamic_exception(CHECK);
  1760   Exceptions::wrap_dynamic_exception(CHECK);
  1776 }
  1761 }
       
  1762 
       
  1763 // Selected method is abstract.
       
  1764 void LinkResolver::throw_abstract_method_error(const methodHandle& resolved_method,
       
  1765                                                const methodHandle& selected_method,
       
  1766                                                Klass *recv_klass, TRAPS) {
       
  1767   Klass *resolved_klass = resolved_method->method_holder();
       
  1768   ResourceMark rm(THREAD);
       
  1769   stringStream ss;
       
  1770 
       
  1771   if (recv_klass != NULL) {
       
  1772     ss.print("Receiver class %s does not define or inherit an "
       
  1773              "implementation of the",
       
  1774              recv_klass->external_name());
       
  1775   } else {
       
  1776     ss.print("Missing implementation of");
       
  1777   }
       
  1778 
       
  1779   assert(resolved_method.not_null(), "Sanity");
       
  1780   ss.print(" resolved method %s%s%s%s of %s %s.",
       
  1781            resolved_method->is_abstract() ? "abstract " : "",
       
  1782            resolved_method->is_private()  ? "private "  : "",
       
  1783            resolved_method->name()->as_C_string(),
       
  1784            resolved_method->signature()->as_C_string(),
       
  1785            resolved_klass->external_kind(),
       
  1786            resolved_klass->external_name());
       
  1787 
       
  1788   if (selected_method.not_null() && !(resolved_method == selected_method)) {
       
  1789     ss.print(" Selected method is %s%s%s.",
       
  1790              selected_method->is_abstract() ? "abstract " : "",
       
  1791              selected_method->is_private()  ? "private "  : "",
       
  1792              selected_method->name_and_sig_as_C_string());
       
  1793   }
       
  1794 
       
  1795   THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), ss.as_string());
       
  1796 }