Mercurial > hg > truffle
comparison src/share/vm/oops/klassVtable.cpp @ 21829:02e2c04a3289
8065366: Better private method resolution
Reviewed-by: hseigel, lfoltan, coleenp, ahgross
author | acorn |
---|---|
date | Thu, 18 Dec 2014 17:59:15 -0800 |
parents | f73af4455d7d |
children | 12dcf5ba8b34 |
comparison
equal
deleted
inserted
replaced
21828:7622232b7efa | 21829:02e2c04a3289 |
---|---|
399 if (super_method->name() == name && super_method->signature() == signature) { | 399 if (super_method->name() == name && super_method->signature() == signature) { |
400 | 400 |
401 // get super_klass for method_holder for the found method | 401 // get super_klass for method_holder for the found method |
402 InstanceKlass* super_klass = super_method->method_holder(); | 402 InstanceKlass* super_klass = super_method->method_holder(); |
403 | 403 |
404 if (is_default | 404 // private methods are also never overridden |
405 if (!super_method->is_private() && | |
406 (is_default | |
405 || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) | 407 || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) |
406 || ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) | 408 || ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) |
407 && ((super_klass = find_transitive_override(super_klass, | 409 && ((super_klass = find_transitive_override(super_klass, |
408 target_method, i, target_loader, | 410 target_method, i, target_loader, |
409 target_classname, THREAD)) | 411 target_classname, THREAD)) |
410 != (InstanceKlass*)NULL)))) | 412 != (InstanceKlass*)NULL))))) |
411 { | 413 { |
412 // Package private methods always need a new entry to root their own | 414 // Package private methods always need a new entry to root their own |
413 // overriding. They may also override other methods. | 415 // overriding. They may also override other methods. |
414 if (!target_method()->is_package_private()) { | 416 if (!target_method()->is_package_private()) { |
415 allocate_new = false; | 417 allocate_new = false; |
687 } | 689 } |
688 | 690 |
689 // check if a method is a miranda method, given a class's methods table, | 691 // check if a method is a miranda method, given a class's methods table, |
690 // its default_method table and its super | 692 // its default_method table and its super |
691 // Miranda methods are calculated twice: | 693 // Miranda methods are calculated twice: |
692 // first: before vtable size calculation: including abstract and default | 694 // first: before vtable size calculation: including abstract and superinterface default |
695 // We include potential default methods to give them space in the vtable. | |
696 // During the first run, the default_methods list is empty | |
693 // This is seen by default method creation | 697 // This is seen by default method creation |
694 // Second: recalculated during vtable initialization: only abstract | 698 // Second: recalculated during vtable initialization: only include abstract methods. |
699 // During the second run, default_methods is set up, so concrete methods from | |
700 // superinterfaces with matching names/signatures to default_methods are already | |
701 // in the default_methods list and do not need to be appended to the vtable | |
702 // as mirandas | |
695 // This is seen by link resolution and selection. | 703 // This is seen by link resolution and selection. |
696 // "miranda" means not static, not defined by this class. | 704 // "miranda" means not static, not defined by this class. |
697 // private methods in interfaces do not belong in the miranda list. | 705 // private methods in interfaces do not belong in the miranda list. |
698 // the caller must make sure that the method belongs to an interface implemented by the class | 706 // the caller must make sure that the method belongs to an interface implemented by the class |
699 // Miranda methods only include public interface instance methods | 707 // Miranda methods only include public interface instance methods |
704 if (m->is_static() || m->is_private() || m->is_overpass()) { | 712 if (m->is_static() || m->is_private() || m->is_overpass()) { |
705 return false; | 713 return false; |
706 } | 714 } |
707 Symbol* name = m->name(); | 715 Symbol* name = m->name(); |
708 Symbol* signature = m->signature(); | 716 Symbol* signature = m->signature(); |
709 | 717 Method* mo; |
710 if (InstanceKlass::find_instance_method(class_methods, name, signature) == NULL) { | 718 |
719 if ((mo = InstanceKlass::find_instance_method(class_methods, name, signature)) == NULL) { | |
711 // did not find it in the method table of the current class | 720 // did not find it in the method table of the current class |
712 if ((default_methods == NULL) || | 721 if ((default_methods == NULL) || |
713 InstanceKlass::find_method(default_methods, name, signature) == NULL) { | 722 InstanceKlass::find_method(default_methods, name, signature) == NULL) { |
714 if (super == NULL) { | 723 if (super == NULL) { |
715 // super doesn't exist | 724 // super doesn't exist |
716 return true; | 725 return true; |
717 } | 726 } |
718 | 727 |
719 Method* mo = InstanceKlass::cast(super)->lookup_method(name, signature); | 728 mo = InstanceKlass::cast(super)->lookup_method(name, signature); |
720 while (mo != NULL && mo->access_flags().is_static() | 729 while (mo != NULL && mo->access_flags().is_static() |
721 && mo->method_holder() != NULL | 730 && mo->method_holder() != NULL |
722 && mo->method_holder()->super() != NULL) | 731 && mo->method_holder()->super() != NULL) |
723 { | 732 { |
724 mo = mo->method_holder()->super()->uncached_lookup_method(name, signature, Klass::normal); | 733 mo = mo->method_holder()->super()->uncached_lookup_method(name, signature, Klass::normal); |
725 } | 734 } |
726 if (mo == NULL || mo->access_flags().is_private() ) { | 735 if (mo == NULL || mo->access_flags().is_private() ) { |
727 // super class hierarchy does not implement it or protection is different | 736 // super class hierarchy does not implement it or protection is different |
728 return true; | 737 return true; |
729 } | 738 } |
739 } | |
740 } else { | |
741 // if the local class has a private method, the miranda will not | |
742 // override it, so a vtable slot is needed | |
743 if (mo->access_flags().is_private()) { | |
744 | |
745 // Second round, weed out any superinterface methods that turned | |
746 // into default methods, i.e. were concrete not abstract in the end | |
747 if ((default_methods == NULL) || | |
748 InstanceKlass::find_method(default_methods, name, signature) == NULL) { | |
749 return true; | |
750 } | |
730 } | 751 } |
731 } | 752 } |
732 | 753 |
733 return false; | 754 return false; |
734 } | 755 } |