1326 Klass* recv_klass,
1327 bool check_null_and_abstract,
1328 TRAPS) {
1329
1330 // setup default return values
1331 int vtable_index = Method::invalid_vtable_index;
1332 methodHandle selected_method;
1333
1334 // runtime method resolution
1335 if (check_null_and_abstract && recv.is_null()) { // check if receiver exists
1336 THROW(vmSymbols::java_lang_NullPointerException());
1337 }
1338
1339 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
1340 // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
1341 // a missing receiver might result in a bogus lookup.
1342 assert(resolved_method->method_holder()->is_linked(), "must be linked");
1343
1344 // do lookup based on receiver klass using the vtable index
1345 if (resolved_method->method_holder()->is_interface()) { // default or miranda method
1346 vtable_index = vtable_index_of_interface_method(resolved_klass,
1347 resolved_method);
1348 assert(vtable_index >= 0 , "we should have valid vtable index at this point");
1349
1350 selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
1351 } else {
1352 // at this point we are sure that resolved_method is virtual and not
1353 // a default or miranda method; therefore, it must have a valid vtable index.
1354 assert(!resolved_method->has_itable_index(), "");
1355 vtable_index = resolved_method->vtable_index();
1356 // We could get a negative vtable_index for final methods,
1357 // because as an optimization they are they are never put in the vtable,
1358 // unless they override an existing method.
1359 // If we do get a negative, it means the resolved method is the the selected
1360 // method, and it can never be changed by an override.
1361 if (vtable_index == Method::nonvirtual_vtable_index) {
1362 assert(resolved_method->can_be_statically_bound(), "cannot override this method");
1363 selected_method = resolved_method;
1364 } else {
1365 selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
1366 }
1367 }
1368
1369 // check if method exists
1370 if (selected_method.is_null()) {
1371 ResourceMark rm(THREAD);
1372 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1373 Method::name_and_sig_as_C_string(resolved_klass,
1374 resolved_method->name(),
1375 resolved_method->signature()));
1376 }
1377
1378 // check if abstract
1379 if (check_null_and_abstract && selected_method->is_abstract()) {
1380 ResourceMark rm(THREAD);
1381 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1382 Method::name_and_sig_as_C_string(resolved_klass,
1383 selected_method->name(),
1384 selected_method->signature()));
1385 }
1386
1387 if (log_develop_is_enabled(Trace, vtables)) {
1388 trace_method_resolution("invokevirtual selected method: receiver-class:",
1389 recv_klass, resolved_klass, selected_method,
1390 false, vtable_index);
1391 }
1392 // setup result
1393 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1394 }
1395
1396 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, Klass* recv_klass,
1397 const LinkInfo& link_info,
1398 bool check_null_and_abstract, TRAPS) {
1399 // throws linktime exceptions
1400 methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK);
1401 runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(),
1402 recv, recv_klass, check_null_and_abstract, CHECK);
1403 }
1404
1420 Klass* recv_klass,
1421 bool check_null_and_abstract, TRAPS) {
1422 // check if receiver exists
1423 if (check_null_and_abstract && recv.is_null()) {
1424 THROW(vmSymbols::java_lang_NullPointerException());
1425 }
1426
1427 // check if receiver klass implements the resolved interface
1428 if (!recv_klass->is_subtype_of(resolved_klass)) {
1429 ResourceMark rm(THREAD);
1430 char buf[200];
1431 jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
1432 recv_klass->external_name(),
1433 resolved_klass->external_name());
1434 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1435 }
1436
1437 // do lookup based on receiver klass
1438 // This search must match the linktime preparation search for itable initialization
1439 // to correctly enforce loader constraints for interface method inheritance
1440 methodHandle sel_method = lookup_instance_method_in_klasses(recv_klass,
1441 resolved_method->name(),
1442 resolved_method->signature(), CHECK);
1443 if (sel_method.is_null() && !check_null_and_abstract) {
1444 // In theory this is a harmless placeholder value, but
1445 // in practice leaving in null affects the nsk default method tests.
1446 // This needs further study.
1447 sel_method = resolved_method;
1448 }
1449 // check if method exists
1450 if (sel_method.is_null()) {
1451 ResourceMark rm(THREAD);
1452 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1453 Method::name_and_sig_as_C_string(recv_klass,
1454 resolved_method->name(),
1455 resolved_method->signature()));
1456 }
1457 // check access
1458 // Throw Illegal Access Error if sel_method is not public.
1459 if (!sel_method->is_public()) {
1460 ResourceMark rm(THREAD);
1461 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
1462 Method::name_and_sig_as_C_string(recv_klass,
1463 sel_method->name(),
1464 sel_method->signature()));
1465 }
1466 // check if abstract
1467 if (check_null_and_abstract && sel_method->is_abstract()) {
1468 ResourceMark rm(THREAD);
1469 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1470 Method::name_and_sig_as_C_string(recv_klass,
1471 sel_method->name(),
1472 sel_method->signature()));
1473 }
1474
1475 if (log_develop_is_enabled(Trace, itables)) {
1476 trace_method_resolution("invokeinterface selected method: receiver-class:",
1477 recv_klass, resolved_klass, sel_method, true);
1478 }
1479 // setup result
1480 if (!resolved_method->has_itable_index()) {
1481 int vtable_index = resolved_method->vtable_index();
1482 assert(vtable_index == sel_method->vtable_index(), "sanity check");
1483 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
1484 } else {
1485 int itable_index = resolved_method()->itable_index();
1486 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
1487 }
1488 }
1489
1490
1491 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
1492 const LinkInfo& link_info) {
1493 EXCEPTION_MARK;
1494 methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD);
1495 if (HAS_PENDING_EXCEPTION) {
1496 CLEAR_PENDING_EXCEPTION;
1497 return methodHandle();
1498 } else {
1499 return method_result;
1500 }
1501 }
1502
1503 methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
1504 const LinkInfo& link_info) {
1505 EXCEPTION_MARK;
1506 methodHandle method_result = linktime_resolve_virtual_method(link_info, THREAD);
1755 int pool_index,
1756 Handle bootstrap_specifier,
1757 Symbol* method_name, Symbol* method_signature,
1758 Klass* current_klass,
1759 TRAPS) {
1760 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
1761 // The appendix argument is likely to be a freshly-created CallSite.
1762 Handle resolved_appendix;
1763 Handle resolved_method_type;
1764 methodHandle resolved_method =
1765 SystemDictionary::find_dynamic_call_site_invoker(current_klass,
1766 pool_index,
1767 bootstrap_specifier,
1768 method_name, method_signature,
1769 &resolved_appendix,
1770 &resolved_method_type,
1771 THREAD);
1772 Exceptions::wrap_dynamic_exception(CHECK);
1773 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
1774 Exceptions::wrap_dynamic_exception(CHECK);
1775 }
|
1326 Klass* recv_klass,
1327 bool check_null_and_abstract,
1328 TRAPS) {
1329
1330 // setup default return values
1331 int vtable_index = Method::invalid_vtable_index;
1332 methodHandle selected_method;
1333
1334 // runtime method resolution
1335 if (check_null_and_abstract && recv.is_null()) { // check if receiver exists
1336 THROW(vmSymbols::java_lang_NullPointerException());
1337 }
1338
1339 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
1340 // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
1341 // a missing receiver might result in a bogus lookup.
1342 assert(resolved_method->method_holder()->is_linked(), "must be linked");
1343
1344 // do lookup based on receiver klass using the vtable index
1345 if (resolved_method->method_holder()->is_interface()) { // default or miranda method
1346 vtable_index = vtable_index_of_interface_method(resolved_klass, resolved_method);
1347 assert(vtable_index >= 0 , "we should have valid vtable index at this point");
1348
1349 selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
1350 } else {
1351 // at this point we are sure that resolved_method is virtual and not
1352 // a default or miranda method; therefore, it must have a valid vtable index.
1353 assert(!resolved_method->has_itable_index(), "");
1354 vtable_index = resolved_method->vtable_index();
1355 // We could get a negative vtable_index for final methods,
1356 // because as an optimization they are never put in the vtable,
1357 // unless they override an existing method.
1358 // If we do get a negative, it means the resolved method is the the selected
1359 // method, and it can never be changed by an override.
1360 if (vtable_index == Method::nonvirtual_vtable_index) {
1361 assert(resolved_method->can_be_statically_bound(), "cannot override this method");
1362 selected_method = resolved_method;
1363 } else {
1364 selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
1365 }
1366 }
1367
1368 // check if method exists
1369 if (selected_method.is_null()) {
1370 throw_abstract_method_error(resolved_method, recv_klass, CHECK);
1371 }
1372
1373 // check if abstract
1374 if (check_null_and_abstract && selected_method->is_abstract()) {
1375 // Pass arguments for generating a verbose error message.
1376 throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK);
1377 }
1378
1379 if (log_develop_is_enabled(Trace, vtables)) {
1380 trace_method_resolution("invokevirtual selected method: receiver-class:",
1381 recv_klass, resolved_klass, selected_method,
1382 false, vtable_index);
1383 }
1384 // setup result
1385 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1386 }
1387
1388 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, Klass* recv_klass,
1389 const LinkInfo& link_info,
1390 bool check_null_and_abstract, TRAPS) {
1391 // throws linktime exceptions
1392 methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK);
1393 runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(),
1394 recv, recv_klass, check_null_and_abstract, CHECK);
1395 }
1396
1412 Klass* recv_klass,
1413 bool check_null_and_abstract, TRAPS) {
1414 // check if receiver exists
1415 if (check_null_and_abstract && recv.is_null()) {
1416 THROW(vmSymbols::java_lang_NullPointerException());
1417 }
1418
1419 // check if receiver klass implements the resolved interface
1420 if (!recv_klass->is_subtype_of(resolved_klass)) {
1421 ResourceMark rm(THREAD);
1422 char buf[200];
1423 jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
1424 recv_klass->external_name(),
1425 resolved_klass->external_name());
1426 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1427 }
1428
1429 // do lookup based on receiver klass
1430 // This search must match the linktime preparation search for itable initialization
1431 // to correctly enforce loader constraints for interface method inheritance
1432 methodHandle selected_method = lookup_instance_method_in_klasses(recv_klass,
1433 resolved_method->name(),
1434 resolved_method->signature(), CHECK);
1435 if (selected_method.is_null() && !check_null_and_abstract) {
1436 // In theory this is a harmless placeholder value, but
1437 // in practice leaving in null affects the nsk default method tests.
1438 // This needs further study.
1439 selected_method = resolved_method;
1440 }
1441 // check if method exists
1442 if (selected_method.is_null()) {
1443 // Pass arguments for generating a verbose error message.
1444 throw_abstract_method_error(resolved_method, recv_klass, CHECK);
1445 }
1446 // check access
1447 // Throw Illegal Access Error if selected_method is not public.
1448 if (!selected_method->is_public()) {
1449 ResourceMark rm(THREAD);
1450 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
1451 Method::name_and_sig_as_C_string(recv_klass,
1452 selected_method->name(),
1453 selected_method->signature()));
1454 }
1455 // check if abstract
1456 if (check_null_and_abstract && selected_method->is_abstract()) {
1457 throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK);
1458 }
1459
1460 if (log_develop_is_enabled(Trace, itables)) {
1461 trace_method_resolution("invokeinterface selected method: receiver-class:",
1462 recv_klass, resolved_klass, selected_method, true);
1463 }
1464 // setup result
1465 if (!resolved_method->has_itable_index()) {
1466 int vtable_index = resolved_method->vtable_index();
1467 assert(vtable_index == selected_method->vtable_index(), "sanity check");
1468 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1469 } else {
1470 int itable_index = resolved_method()->itable_index();
1471 result.set_interface(resolved_klass, recv_klass, resolved_method, selected_method, itable_index, CHECK);
1472 }
1473 }
1474
1475
1476 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
1477 const LinkInfo& link_info) {
1478 EXCEPTION_MARK;
1479 methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD);
1480 if (HAS_PENDING_EXCEPTION) {
1481 CLEAR_PENDING_EXCEPTION;
1482 return methodHandle();
1483 } else {
1484 return method_result;
1485 }
1486 }
1487
1488 methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
1489 const LinkInfo& link_info) {
1490 EXCEPTION_MARK;
1491 methodHandle method_result = linktime_resolve_virtual_method(link_info, THREAD);
1740 int pool_index,
1741 Handle bootstrap_specifier,
1742 Symbol* method_name, Symbol* method_signature,
1743 Klass* current_klass,
1744 TRAPS) {
1745 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
1746 // The appendix argument is likely to be a freshly-created CallSite.
1747 Handle resolved_appendix;
1748 Handle resolved_method_type;
1749 methodHandle resolved_method =
1750 SystemDictionary::find_dynamic_call_site_invoker(current_klass,
1751 pool_index,
1752 bootstrap_specifier,
1753 method_name, method_signature,
1754 &resolved_appendix,
1755 &resolved_method_type,
1756 THREAD);
1757 Exceptions::wrap_dynamic_exception(CHECK);
1758 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
1759 Exceptions::wrap_dynamic_exception(CHECK);
1760 }
1761
1762 // Selected method is abstract.
1763 void LinkResolver::throw_abstract_method_error(const methodHandle& resolved_method,
1764 const methodHandle& selected_method,
1765 Klass *recv_klass, TRAPS) {
1766 Klass *resolved_klass = resolved_method->method_holder();
1767 ResourceMark rm;
1768 stringStream ss;
1769
1770 if (recv_klass != NULL) {
1771 ss.print("Receiver class %s does not define or inherit an "
1772 "implementation of the",
1773 recv_klass->external_name());
1774 } else {
1775 ss.print("Missing implementation of");
1776 }
1777
1778 assert(resolved_method.not_null(), "Sanity");
1779 ss.print(" resolved method %s%s%s%s of %s %s.",
1780 resolved_method->is_abstract() ? "abstract " : "",
1781 resolved_method->is_private() ? "private " : "",
1782 resolved_method->name()->as_C_string(),
1783 resolved_method->signature()->as_C_string(),
1784 resolved_klass->external_kind(),
1785 resolved_klass->external_name());
1786
1787 if (selected_method.not_null() && !(resolved_method == selected_method)) {
1788 ss.print(" Selected method is %s%s%s.",
1789 selected_method->is_abstract() ? "abstract " : "",
1790 selected_method->is_private() ? "private " : "",
1791 selected_method->name_and_sig_as_C_string());
1792 }
1793
1794 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), ss.as_string());
1795 }
|