1379 return -1; |
1379 return -1; |
1380 } |
1380 } |
1381 |
1381 |
1382 // find_method looks up the name/signature in the local methods array |
1382 // find_method looks up the name/signature in the local methods array |
1383 Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { |
1383 Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { |
1384 return find_method_impl(name, signature, find_overpass, find_static); |
1384 return find_method_impl(name, signature, find_overpass, find_static, find_private); |
1385 } |
1385 } |
1386 |
1386 |
1387 Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, |
1387 Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, |
1388 OverpassLookupMode overpass_mode, StaticLookupMode static_mode) const { |
1388 OverpassLookupMode overpass_mode, |
1389 return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode); |
1389 StaticLookupMode static_mode, |
|
1390 PrivateLookupMode private_mode) const { |
|
1391 return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode); |
1390 } |
1392 } |
1391 |
1393 |
1392 // find_instance_method looks up the name/signature in the local methods array |
1394 // find_instance_method looks up the name/signature in the local methods array |
1393 // and skips over static methods |
1395 // and skips over static methods |
1394 Method* InstanceKlass::find_instance_method( |
1396 Method* InstanceKlass::find_instance_method( |
1395 Array<Method*>* methods, Symbol* name, Symbol* signature) { |
1397 Array<Method*>* methods, Symbol* name, Symbol* signature) { |
1396 Method* meth = InstanceKlass::find_method_impl(methods, name, signature, |
1398 Method* meth = InstanceKlass::find_method_impl(methods, name, signature, |
1397 find_overpass, skip_static); |
1399 find_overpass, skip_static, find_private); |
1398 assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics"); |
1400 assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics"); |
1399 return meth; |
1401 return meth; |
1400 } |
1402 } |
1401 |
1403 |
1402 // find_instance_method looks up the name/signature in the local methods array |
1404 // find_instance_method looks up the name/signature in the local methods array |
1403 // and skips over static methods |
1405 // and skips over static methods |
1404 Method* InstanceKlass::find_instance_method(Symbol* name, Symbol* signature) { |
1406 Method* InstanceKlass::find_instance_method(Symbol* name, Symbol* signature) { |
1405 return InstanceKlass::find_instance_method(methods(), name, signature); |
1407 return InstanceKlass::find_instance_method(methods(), name, signature); |
1406 } |
1408 } |
1407 |
1409 |
|
1410 // Find looks up the name/signature in the local methods array |
|
1411 // and filters on the overpass, static and private flags |
|
1412 // This returns the first one found |
|
1413 // note that the local methods array can have up to one overpass, one static |
|
1414 // and one instance (private or not) with the same name/signature |
|
1415 Method* InstanceKlass::find_local_method(Symbol* name, Symbol* signature, |
|
1416 OverpassLookupMode overpass_mode, |
|
1417 StaticLookupMode static_mode, |
|
1418 PrivateLookupMode private_mode) const { |
|
1419 return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode); |
|
1420 } |
|
1421 |
|
1422 // Find looks up the name/signature in the local methods array |
|
1423 // and filters on the overpass, static and private flags |
|
1424 // This returns the first one found |
|
1425 // note that the local methods array can have up to one overpass, one static |
|
1426 // and one instance (private or not) with the same name/signature |
|
1427 Method* InstanceKlass::find_local_method(Array<Method*>* methods, |
|
1428 Symbol* name, Symbol* signature, |
|
1429 OverpassLookupMode overpass_mode, |
|
1430 StaticLookupMode static_mode, |
|
1431 PrivateLookupMode private_mode) { |
|
1432 return InstanceKlass::find_method_impl(methods, name, signature, overpass_mode, static_mode, private_mode); |
|
1433 } |
|
1434 |
|
1435 |
1408 // find_method looks up the name/signature in the local methods array |
1436 // find_method looks up the name/signature in the local methods array |
1409 Method* InstanceKlass::find_method( |
1437 Method* InstanceKlass::find_method( |
1410 Array<Method*>* methods, Symbol* name, Symbol* signature) { |
1438 Array<Method*>* methods, Symbol* name, Symbol* signature) { |
1411 return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static); |
1439 return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static, find_private); |
1412 } |
1440 } |
1413 |
1441 |
1414 Method* InstanceKlass::find_method_impl( |
1442 Method* InstanceKlass::find_method_impl( |
1415 Array<Method*>* methods, Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode, StaticLookupMode static_mode) { |
1443 Array<Method*>* methods, Symbol* name, Symbol* signature, |
1416 int hit = find_method_index(methods, name, signature, overpass_mode, static_mode); |
1444 OverpassLookupMode overpass_mode, StaticLookupMode static_mode, |
|
1445 PrivateLookupMode private_mode) { |
|
1446 int hit = find_method_index(methods, name, signature, overpass_mode, static_mode, private_mode); |
1417 return hit >= 0 ? methods->at(hit): NULL; |
1447 return hit >= 0 ? methods->at(hit): NULL; |
1418 } |
1448 } |
1419 |
1449 |
1420 bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static) { |
1450 bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private) { |
1421 return (m->signature() == signature) && |
1451 return ((m->signature() == signature) && |
1422 (!skipping_overpass || !m->is_overpass()) && |
1452 (!skipping_overpass || !m->is_overpass()) && |
1423 (!skipping_static || !m->is_static()); |
1453 (!skipping_static || !m->is_static()) && |
|
1454 (!skipping_private || !m->is_private())); |
1424 } |
1455 } |
1425 |
1456 |
1426 // Used directly for default_methods to find the index into the |
1457 // Used directly for default_methods to find the index into the |
1427 // default_vtable_indices, and indirectly by find_method |
1458 // default_vtable_indices, and indirectly by find_method |
1428 // find_method_index looks in the local methods array to return the index |
1459 // find_method_index looks in the local methods array to return the index |
1429 // of the matching name/signature. If, overpass methods are being ignored, |
1460 // of the matching name/signature. If, overpass methods are being ignored, |
1430 // the search continues to find a potential non-overpass match. This capability |
1461 // the search continues to find a potential non-overpass match. This capability |
1431 // is important during method resolution to prefer a static method, for example, |
1462 // is important during method resolution to prefer a static method, for example, |
1432 // over an overpass method. |
1463 // over an overpass method. |
|
1464 // There is the possibility in any _method's array to have the same name/signature |
|
1465 // for a static method, an overpass method and a local instance method |
|
1466 // To correctly catch a given method, the search criteria may need |
|
1467 // to explicitly skip the other two. For local instance methods, it |
|
1468 // is often necessary to skip private methods |
1433 int InstanceKlass::find_method_index( |
1469 int InstanceKlass::find_method_index( |
1434 Array<Method*>* methods, Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode, StaticLookupMode static_mode) { |
1470 Array<Method*>* methods, Symbol* name, Symbol* signature, |
|
1471 OverpassLookupMode overpass_mode, StaticLookupMode static_mode, |
|
1472 PrivateLookupMode private_mode) { |
1435 bool skipping_overpass = (overpass_mode == skip_overpass); |
1473 bool skipping_overpass = (overpass_mode == skip_overpass); |
1436 bool skipping_static = (static_mode == skip_static); |
1474 bool skipping_static = (static_mode == skip_static); |
|
1475 bool skipping_private = (private_mode == skip_private); |
1437 int hit = binary_search(methods, name); |
1476 int hit = binary_search(methods, name); |
1438 if (hit != -1) { |
1477 if (hit != -1) { |
1439 Method* m = methods->at(hit); |
1478 Method* m = methods->at(hit); |
1440 |
1479 |
1441 // Do linear search to find matching signature. First, quick check |
1480 // Do linear search to find matching signature. First, quick check |
1442 // for common case, ignoring overpasses if requested. |
1481 // for common case, ignoring overpasses if requested. |
1443 if (method_matches(m, signature, skipping_overpass, skipping_static)) return hit; |
1482 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return hit; |
1444 |
1483 |
1445 // search downwards through overloaded methods |
1484 // search downwards through overloaded methods |
1446 int i; |
1485 int i; |
1447 for (i = hit - 1; i >= 0; --i) { |
1486 for (i = hit - 1; i >= 0; --i) { |
1448 Method* m = methods->at(i); |
1487 Method* m = methods->at(i); |
1449 assert(m->is_method(), "must be method"); |
1488 assert(m->is_method(), "must be method"); |
1450 if (m->name() != name) break; |
1489 if (m->name() != name) break; |
1451 if (method_matches(m, signature, skipping_overpass, skipping_static)) return i; |
1490 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i; |
1452 } |
1491 } |
1453 // search upwards |
1492 // search upwards |
1454 for (i = hit + 1; i < methods->length(); ++i) { |
1493 for (i = hit + 1; i < methods->length(); ++i) { |
1455 Method* m = methods->at(i); |
1494 Method* m = methods->at(i); |
1456 assert(m->is_method(), "must be method"); |
1495 assert(m->is_method(), "must be method"); |
1457 if (m->name() != name) break; |
1496 if (m->name() != name) break; |
1458 if (method_matches(m, signature, skipping_overpass, skipping_static)) return i; |
1497 if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i; |
1459 } |
1498 } |
1460 // not found |
1499 // not found |
1461 #ifdef ASSERT |
1500 #ifdef ASSERT |
1462 int index = (skipping_overpass || skipping_static) ? -1 : linear_search(methods, name, signature); |
1501 int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature); |
1463 assert(index == -1, err_msg("binary search should have found entry %d", index)); |
1502 assert(index == -1, err_msg("binary search should have found entry %d", index)); |
1464 #endif |
1503 #endif |
1465 } |
1504 } |
1466 return -1; |
1505 return -1; |
1467 } |
1506 } |