Mercurial > hg > truffle
comparison src/share/vm/oops/instanceKlass.cpp @ 17889:386dd1c71858
8033150: invokestatic: IncompatibleClassChangeError trying to invoke static method from a parent in presence of conflicting defaults.
Summary: A static method should be preferred during method resolution over an overpass, search the current class as well as its superclasses.
Reviewed-by: acorn, coleenp, kamg
author | lfoltan |
---|---|
date | Mon, 14 Apr 2014 14:27:45 -0400 |
parents | 9428a0b94204 |
children | 78bbf4d43a14 |
comparison
equal
deleted
inserted
replaced
17887:cd3c534f8f4a | 17889:386dd1c71858 |
---|---|
1427 return -1; | 1427 return -1; |
1428 } | 1428 } |
1429 | 1429 |
1430 // find_method looks up the name/signature in the local methods array | 1430 // find_method looks up the name/signature in the local methods array |
1431 Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { | 1431 Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { |
1432 return InstanceKlass::find_method(methods(), name, signature); | 1432 return find_method_impl(name, signature, false); |
1433 } | |
1434 | |
1435 Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const { | |
1436 return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass); | |
1433 } | 1437 } |
1434 | 1438 |
1435 // find_instance_method looks up the name/signature in the local methods array | 1439 // find_instance_method looks up the name/signature in the local methods array |
1436 // and skips over static methods | 1440 // and skips over static methods |
1437 Method* InstanceKlass::find_instance_method( | 1441 Method* InstanceKlass::find_instance_method( |
1444 } | 1448 } |
1445 | 1449 |
1446 // find_method looks up the name/signature in the local methods array | 1450 // find_method looks up the name/signature in the local methods array |
1447 Method* InstanceKlass::find_method( | 1451 Method* InstanceKlass::find_method( |
1448 Array<Method*>* methods, Symbol* name, Symbol* signature) { | 1452 Array<Method*>* methods, Symbol* name, Symbol* signature) { |
1449 int hit = find_method_index(methods, name, signature); | 1453 return InstanceKlass::find_method_impl(methods, name, signature, false); |
1454 } | |
1455 | |
1456 Method* InstanceKlass::find_method_impl( | |
1457 Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass) { | |
1458 int hit = find_method_index(methods, name, signature, skipping_overpass); | |
1450 return hit >= 0 ? methods->at(hit): NULL; | 1459 return hit >= 0 ? methods->at(hit): NULL; |
1451 } | 1460 } |
1452 | 1461 |
1453 // Used directly for default_methods to find the index into the | 1462 // Used directly for default_methods to find the index into the |
1454 // default_vtable_indices, and indirectly by find_method | 1463 // default_vtable_indices, and indirectly by find_method |
1455 // find_method_index looks in the local methods array to return the index | 1464 // find_method_index looks in the local methods array to return the index |
1456 // of the matching name/signature | 1465 // of the matching name/signature. If, overpass methods are being ignored, |
1466 // the search continues to find a potential non-overpass match. This capability | |
1467 // is important during method resolution to prefer a static method, for example, | |
1468 // over an overpass method. | |
1457 int InstanceKlass::find_method_index( | 1469 int InstanceKlass::find_method_index( |
1458 Array<Method*>* methods, Symbol* name, Symbol* signature) { | 1470 Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass) { |
1459 int hit = binary_search(methods, name); | 1471 int hit = binary_search(methods, name); |
1460 if (hit != -1) { | 1472 if (hit != -1) { |
1461 Method* m = methods->at(hit); | 1473 Method* m = methods->at(hit); |
1462 // Do linear search to find matching signature. First, quick check | 1474 // Do linear search to find matching signature. First, quick check |
1463 // for common case | 1475 // for common case, ignoring overpasses if requested. |
1464 if (m->signature() == signature) return hit; | 1476 if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return hit; |
1477 | |
1465 // search downwards through overloaded methods | 1478 // search downwards through overloaded methods |
1466 int i; | 1479 int i; |
1467 for (i = hit - 1; i >= 0; --i) { | 1480 for (i = hit - 1; i >= 0; --i) { |
1468 Method* m = methods->at(i); | 1481 Method* m = methods->at(i); |
1469 assert(m->is_method(), "must be method"); | 1482 assert(m->is_method(), "must be method"); |
1470 if (m->name() != name) break; | 1483 if (m->name() != name) break; |
1471 if (m->signature() == signature) return i; | 1484 if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return i; |
1472 } | 1485 } |
1473 // search upwards | 1486 // search upwards |
1474 for (i = hit + 1; i < methods->length(); ++i) { | 1487 for (i = hit + 1; i < methods->length(); ++i) { |
1475 Method* m = methods->at(i); | 1488 Method* m = methods->at(i); |
1476 assert(m->is_method(), "must be method"); | 1489 assert(m->is_method(), "must be method"); |
1477 if (m->name() != name) break; | 1490 if (m->name() != name) break; |
1478 if (m->signature() == signature) return i; | 1491 if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return i; |
1479 } | 1492 } |
1480 // not found | 1493 // not found |
1481 #ifdef ASSERT | 1494 #ifdef ASSERT |
1482 int index = linear_search(methods, name, signature); | 1495 int index = skipping_overpass ? -1 : linear_search(methods, name, signature); |
1483 assert(index == -1, err_msg("binary search should have found entry %d", index)); | 1496 assert(index == -1, err_msg("binary search should have found entry %d", index)); |
1484 #endif | 1497 #endif |
1485 } | 1498 } |
1486 return -1; | 1499 return -1; |
1487 } | 1500 } |
1503 return -1; | 1516 return -1; |
1504 } | 1517 } |
1505 | 1518 |
1506 // uncached_lookup_method searches both the local class methods array and all | 1519 // uncached_lookup_method searches both the local class methods array and all |
1507 // superclasses methods arrays, skipping any overpass methods in superclasses. | 1520 // superclasses methods arrays, skipping any overpass methods in superclasses. |
1508 Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { | 1521 Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const { |
1522 MethodLookupMode lookup_mode = mode; | |
1509 Klass* klass = const_cast<InstanceKlass*>(this); | 1523 Klass* klass = const_cast<InstanceKlass*>(this); |
1510 bool dont_ignore_overpasses = true; // For the class being searched, find its overpasses. | |
1511 while (klass != NULL) { | 1524 while (klass != NULL) { |
1512 Method* method = InstanceKlass::cast(klass)->find_method(name, signature); | 1525 Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, (lookup_mode == skip_overpass)); |
1513 if ((method != NULL) && (dont_ignore_overpasses || !method->is_overpass())) { | 1526 if (method != NULL) { |
1514 return method; | 1527 return method; |
1515 } | 1528 } |
1516 klass = InstanceKlass::cast(klass)->super(); | 1529 klass = InstanceKlass::cast(klass)->super(); |
1517 dont_ignore_overpasses = false; // Ignore overpass methods in all superclasses. | 1530 lookup_mode = skip_overpass; // Always ignore overpass methods in superclasses |
1518 } | 1531 } |
1519 return NULL; | 1532 return NULL; |
1520 } | 1533 } |
1521 | 1534 |
1522 // lookup a method in the default methods list then in all transitive interfaces | 1535 // lookup a method in the default methods list then in all transitive interfaces |
1527 if (default_methods() != NULL) { | 1540 if (default_methods() != NULL) { |
1528 m = find_method(default_methods(), name, signature); | 1541 m = find_method(default_methods(), name, signature); |
1529 } | 1542 } |
1530 // Look up interfaces | 1543 // Look up interfaces |
1531 if (m == NULL) { | 1544 if (m == NULL) { |
1532 m = lookup_method_in_all_interfaces(name, signature, false); | 1545 m = lookup_method_in_all_interfaces(name, signature, normal); |
1533 } | 1546 } |
1534 return m; | 1547 return m; |
1535 } | 1548 } |
1536 | 1549 |
1537 // lookup a method in all the interfaces that this class implements | 1550 // lookup a method in all the interfaces that this class implements |
1538 // Do NOT return private or static methods, new in JDK8 which are not externally visible | 1551 // Do NOT return private or static methods, new in JDK8 which are not externally visible |
1539 // They should only be found in the initial InterfaceMethodRef | 1552 // They should only be found in the initial InterfaceMethodRef |
1540 Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, | 1553 Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, |
1541 Symbol* signature, | 1554 Symbol* signature, |
1542 bool skip_default_methods) const { | 1555 MethodLookupMode mode) const { |
1543 Array<Klass*>* all_ifs = transitive_interfaces(); | 1556 Array<Klass*>* all_ifs = transitive_interfaces(); |
1544 int num_ifs = all_ifs->length(); | 1557 int num_ifs = all_ifs->length(); |
1545 InstanceKlass *ik = NULL; | 1558 InstanceKlass *ik = NULL; |
1546 for (int i = 0; i < num_ifs; i++) { | 1559 for (int i = 0; i < num_ifs; i++) { |
1547 ik = InstanceKlass::cast(all_ifs->at(i)); | 1560 ik = InstanceKlass::cast(all_ifs->at(i)); |
1548 Method* m = ik->lookup_method(name, signature); | 1561 Method* m = ik->lookup_method(name, signature); |
1549 if (m != NULL && m->is_public() && !m->is_static() && | 1562 if (m != NULL && m->is_public() && !m->is_static() && |
1550 (!skip_default_methods || !m->is_default_method())) { | 1563 ((mode != skip_defaults) || !m->is_default_method())) { |
1551 return m; | 1564 return m; |
1552 } | 1565 } |
1553 } | 1566 } |
1554 return NULL; | 1567 return NULL; |
1555 } | 1568 } |