Mercurial > hg > truffle
comparison src/share/vm/classfile/defaultMethods.cpp @ 12823:ac9cb1d5a202
8009130: Lambda: Fix access controls, loader constraints.
Summary: New default methods list with inherited superinterface methods
Reviewed-by: minqi, sspitsyn, coleenp
author | acorn |
---|---|
date | Mon, 07 Oct 2013 12:20:28 -0400 |
parents | 268e7a2178d7 |
children | f50418dfb1b7 |
comparison
equal
deleted
inserted
replaced
12822:cc4f5f8d885e | 12823:ac9cb1d5a202 |
---|---|
343 guarantee(index != NULL && *index >= 0 && *index < _members.length(), "bad index"); | 343 guarantee(index != NULL && *index >= 0 && *index < _members.length(), "bad index"); |
344 _members.at(*index).second = DISQUALIFIED; | 344 _members.at(*index).second = DISQUALIFIED; |
345 } | 345 } |
346 | 346 |
347 Symbol* generate_no_defaults_message(TRAPS) const; | 347 Symbol* generate_no_defaults_message(TRAPS) const; |
348 Symbol* generate_abstract_method_message(Method* method, TRAPS) const; | |
349 Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const; | 348 Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const; |
350 | 349 |
351 public: | 350 public: |
352 | 351 |
353 MethodFamily() | 352 MethodFamily() |
402 | 401 |
403 if (qualified_methods.length() == 0) { | 402 if (qualified_methods.length() == 0) { |
404 _exception_message = generate_no_defaults_message(CHECK); | 403 _exception_message = generate_no_defaults_message(CHECK); |
405 _exception_name = vmSymbols::java_lang_AbstractMethodError(); | 404 _exception_name = vmSymbols::java_lang_AbstractMethodError(); |
406 } else if (qualified_methods.length() == 1) { | 405 } else if (qualified_methods.length() == 1) { |
406 // leave abstract methods alone, they will be found via normal search path | |
407 Method* method = qualified_methods.at(0); | 407 Method* method = qualified_methods.at(0); |
408 if (method->is_abstract()) { | 408 if (!method->is_abstract()) { |
409 _exception_message = generate_abstract_method_message(method, CHECK); | |
410 _exception_name = vmSymbols::java_lang_AbstractMethodError(); | |
411 } else { | |
412 _selected_target = qualified_methods.at(0); | 409 _selected_target = qualified_methods.at(0); |
413 } | 410 } |
414 } else { | 411 } else { |
415 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); | 412 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); |
416 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); | 413 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); |
417 } | 414 if (TraceDefaultMethods) { |
418 | 415 _exception_message->print_value_on(tty); |
419 assert((has_target() ^ throws_exception()) == 1, | 416 tty->print_cr(""); |
420 "One and only one must be true"); | 417 } |
418 } | |
421 } | 419 } |
422 | 420 |
423 bool contains_signature(Symbol* query) { | 421 bool contains_signature(Symbol* query) { |
424 for (int i = 0; i < _members.length(); ++i) { | 422 for (int i = 0; i < _members.length(); ++i) { |
425 if (query == _members.at(i).first->signature()) { | 423 if (query == _members.at(i).first->signature()) { |
471 #endif // ndef PRODUCT | 469 #endif // ndef PRODUCT |
472 }; | 470 }; |
473 | 471 |
474 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const { | 472 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const { |
475 return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL); | 473 return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL); |
476 } | |
477 | |
478 Symbol* MethodFamily::generate_abstract_method_message(Method* method, TRAPS) const { | |
479 Symbol* klass = method->klass_name(); | |
480 Symbol* name = method->name(); | |
481 Symbol* sig = method->signature(); | |
482 stringStream ss; | |
483 ss.print("Method "); | |
484 ss.write((const char*)klass->bytes(), klass->utf8_length()); | |
485 ss.print("."); | |
486 ss.write((const char*)name->bytes(), name->utf8_length()); | |
487 ss.write((const char*)sig->bytes(), sig->utf8_length()); | |
488 ss.print(" is abstract"); | |
489 return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL); | |
490 } | 474 } |
491 | 475 |
492 Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const { | 476 Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const { |
493 stringStream ss; | 477 stringStream ss; |
494 ss.print("Conflicting default methods:"); | 478 ss.print("Conflicting default methods:"); |
593 print_slot(str, name(), signature()); | 577 print_slot(str, name(), signature()); |
594 } | 578 } |
595 #endif // ndef PRODUCT | 579 #endif // ndef PRODUCT |
596 }; | 580 }; |
597 | 581 |
582 static bool already_in_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots, Method* m) { | |
583 bool found = false; | |
584 for (int j = 0; j < slots->length(); ++j) { | |
585 if (slots->at(j)->name() == m->name() && | |
586 slots->at(j)->signature() == m->signature() ) { | |
587 found = true; | |
588 break; | |
589 } | |
590 } | |
591 return found; | |
592 } | |
593 | |
598 static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots( | 594 static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots( |
599 InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) { | 595 InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) { |
600 | 596 |
601 assert(klass != NULL, "Must be valid class"); | 597 assert(klass != NULL, "Must be valid class"); |
602 | 598 |
603 GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>(); | 599 GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>(); |
604 | 600 |
605 // All miranda methods are obvious candidates | 601 // All miranda methods are obvious candidates |
606 for (int i = 0; i < mirandas->length(); ++i) { | 602 for (int i = 0; i < mirandas->length(); ++i) { |
607 EmptyVtableSlot* slot = new EmptyVtableSlot(mirandas->at(i)); | 603 Method* m = mirandas->at(i); |
608 slots->append(slot); | 604 if (!already_in_vtable_slots(slots, m)) { |
605 slots->append(new EmptyVtableSlot(m)); | |
606 } | |
609 } | 607 } |
610 | 608 |
611 // Also any overpasses in our superclasses, that we haven't implemented. | 609 // Also any overpasses in our superclasses, that we haven't implemented. |
612 // (can't use the vtable because it is not guaranteed to be initialized yet) | 610 // (can't use the vtable because it is not guaranteed to be initialized yet) |
613 InstanceKlass* super = klass->java_super(); | 611 InstanceKlass* super = klass->java_super(); |
619 // default method processing that occurred on behalf of our superclass, | 617 // default method processing that occurred on behalf of our superclass, |
620 // so it's a method we want to re-examine in this new context. That is, | 618 // so it's a method we want to re-examine in this new context. That is, |
621 // unless we have a real implementation of it in the current class. | 619 // unless we have a real implementation of it in the current class. |
622 Method* impl = klass->lookup_method(m->name(), m->signature()); | 620 Method* impl = klass->lookup_method(m->name(), m->signature()); |
623 if (impl == NULL || impl->is_overpass()) { | 621 if (impl == NULL || impl->is_overpass()) { |
624 slots->append(new EmptyVtableSlot(m)); | 622 if (!already_in_vtable_slots(slots, m)) { |
623 slots->append(new EmptyVtableSlot(m)); | |
624 } | |
625 } | |
626 } | |
627 } | |
628 | |
629 // also any default methods in our superclasses | |
630 if (super->default_methods() != NULL) { | |
631 for (int i = 0; i < super->default_methods()->length(); ++i) { | |
632 Method* m = super->default_methods()->at(i); | |
633 // m is a method that would have been a miranda if not for the | |
634 // default method processing that occurred on behalf of our superclass, | |
635 // so it's a method we want to re-examine in this new context. That is, | |
636 // unless we have a real implementation of it in the current class. | |
637 Method* impl = klass->lookup_method(m->name(), m->signature()); | |
638 if (impl == NULL || impl->is_overpass()) { | |
639 if (!already_in_vtable_slots(slots, m)) { | |
640 slots->append(new EmptyVtableSlot(m)); | |
641 } | |
625 } | 642 } |
626 } | 643 } |
627 } | 644 } |
628 super = super->java_super(); | 645 super = super->java_super(); |
629 } | 646 } |
677 | 694 |
678 Method* m = iklass->find_method(_method_name, _method_signature); | 695 Method* m = iklass->find_method(_method_name, _method_signature); |
679 // private interface methods are not candidates for default methods | 696 // private interface methods are not candidates for default methods |
680 // invokespecial to private interface methods doesn't use default method logic | 697 // invokespecial to private interface methods doesn't use default method logic |
681 // future: take access controls into account for superclass methods | 698 // future: take access controls into account for superclass methods |
682 if (m != NULL && (!iklass->is_interface() || m->is_public())) { | 699 if (m != NULL && !m->is_static() && (!iklass->is_interface() || m->is_public())) { |
683 if (_family == NULL) { | 700 if (_family == NULL) { |
684 _family = new StatefulMethodFamily(); | 701 _family = new StatefulMethodFamily(); |
685 } | 702 } |
686 | 703 |
687 if (iklass->is_interface()) { | 704 if (iklass->is_interface()) { |
698 | 715 |
699 }; | 716 }; |
700 | 717 |
701 | 718 |
702 | 719 |
703 static void create_overpasses( | 720 static void create_defaults_and_exceptions( |
704 GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS); | 721 GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS); |
705 | 722 |
706 static void generate_erased_defaults( | 723 static void generate_erased_defaults( |
707 InstanceKlass* klass, GrowableArray<EmptyVtableSlot*>* empty_slots, | 724 InstanceKlass* klass, GrowableArray<EmptyVtableSlot*>* empty_slots, |
708 EmptyVtableSlot* slot, TRAPS) { | 725 EmptyVtableSlot* slot, TRAPS) { |
718 slot->bind_family(family); | 735 slot->bind_family(family); |
719 } | 736 } |
720 } | 737 } |
721 | 738 |
722 static void merge_in_new_methods(InstanceKlass* klass, | 739 static void merge_in_new_methods(InstanceKlass* klass, |
740 GrowableArray<Method*>* new_methods, TRAPS); | |
741 static void create_default_methods( InstanceKlass* klass, | |
723 GrowableArray<Method*>* new_methods, TRAPS); | 742 GrowableArray<Method*>* new_methods, TRAPS); |
724 | 743 |
725 // This is the guts of the default methods implementation. This is called just | 744 // This is the guts of the default methods implementation. This is called just |
726 // after the classfile has been parsed if some ancestor has default methods. | 745 // after the classfile has been parsed if some ancestor has default methods. |
727 // | 746 // |
780 if (TraceDefaultMethods) { | 799 if (TraceDefaultMethods) { |
781 tty->print_cr("Creating overpasses..."); | 800 tty->print_cr("Creating overpasses..."); |
782 } | 801 } |
783 #endif // ndef PRODUCT | 802 #endif // ndef PRODUCT |
784 | 803 |
785 create_overpasses(empty_slots, klass, CHECK); | 804 create_defaults_and_exceptions(empty_slots, klass, CHECK); |
786 | 805 |
787 #ifndef PRODUCT | 806 #ifndef PRODUCT |
788 if (TraceDefaultMethods) { | 807 if (TraceDefaultMethods) { |
789 tty->print_cr("Default method processing complete"); | 808 tty->print_cr("Default method processing complete"); |
790 } | 809 } |
791 #endif // ndef PRODUCT | 810 #endif // ndef PRODUCT |
792 } | |
793 | |
794 | |
795 | |
796 #ifdef ASSERT | |
797 // Return true is broad type is a covariant return of narrow type | |
798 static bool covariant_return_type(BasicType narrow, BasicType broad) { | |
799 if (narrow == broad) { | |
800 return true; | |
801 } | |
802 if (broad == T_OBJECT) { | |
803 return true; | |
804 } | |
805 return false; | |
806 } | |
807 #endif | |
808 | |
809 static int assemble_redirect( | |
810 BytecodeConstantPool* cp, BytecodeBuffer* buffer, | |
811 Symbol* incoming, Method* target, TRAPS) { | |
812 | |
813 BytecodeAssembler assem(buffer, cp); | |
814 | |
815 SignatureStream in(incoming, true); | |
816 SignatureStream out(target->signature(), true); | |
817 u2 parameter_count = 0; | |
818 | |
819 assem.aload(parameter_count++); // load 'this' | |
820 | |
821 while (!in.at_return_type()) { | |
822 assert(!out.at_return_type(), "Parameter counts do not match"); | |
823 BasicType bt = in.type(); | |
824 assert(out.type() == bt, "Parameter types are not compatible"); | |
825 assem.load(bt, parameter_count); | |
826 if (in.is_object() && in.as_symbol(THREAD) != out.as_symbol(THREAD)) { | |
827 assem.checkcast(out.as_symbol(THREAD)); | |
828 } else if (bt == T_LONG || bt == T_DOUBLE) { | |
829 ++parameter_count; // longs and doubles use two slots | |
830 } | |
831 ++parameter_count; | |
832 in.next(); | |
833 out.next(); | |
834 } | |
835 assert(out.at_return_type(), "Parameter counts do not match"); | |
836 assert(covariant_return_type(out.type(), in.type()), "Return types are not compatible"); | |
837 | |
838 if (parameter_count == 1 && (in.type() == T_LONG || in.type() == T_DOUBLE)) { | |
839 ++parameter_count; // need room for return value | |
840 } | |
841 if (target->method_holder()->is_interface()) { | |
842 assem.invokespecial(target); | |
843 } else { | |
844 assem.invokevirtual(target); | |
845 } | |
846 | |
847 if (in.is_object() && in.as_symbol(THREAD) != out.as_symbol(THREAD)) { | |
848 assem.checkcast(in.as_symbol(THREAD)); | |
849 } | |
850 assem._return(in.type()); | |
851 return parameter_count; | |
852 } | 811 } |
853 | 812 |
854 static int assemble_method_error( | 813 static int assemble_method_error( |
855 BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) { | 814 BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) { |
856 | 815 |
922 } | 881 } |
923 } | 882 } |
924 } | 883 } |
925 } | 884 } |
926 | 885 |
927 // A "bridge" is a method created by javac to bridge the gap between | 886 // Create default_methods list for the current class. |
928 // an implementation and a generically-compatible, but different, signature. | 887 // With the VM only processing erased signatures, the VM only |
929 // Bridges have actual bytecode implementation in classfiles. | 888 // creates an overpass in a conflict case or a case with no candidates. |
930 // An "overpass", on the other hand, performs the same function as a bridge | 889 // This allows virtual methods to override the overpass, but ensures |
931 // but does not occur in a classfile; the VM creates overpass itself, | 890 // that a local method search will find the exception rather than an abstract |
932 // when it needs a path to get from a call site to an default method, and | 891 // or default method that is not a valid candidate. |
933 // a bridge doesn't exist. | 892 static void create_defaults_and_exceptions( |
934 static void create_overpasses( | |
935 GrowableArray<EmptyVtableSlot*>* slots, | 893 GrowableArray<EmptyVtableSlot*>* slots, |
936 InstanceKlass* klass, TRAPS) { | 894 InstanceKlass* klass, TRAPS) { |
937 | 895 |
938 GrowableArray<Method*> overpasses; | 896 GrowableArray<Method*> overpasses; |
897 GrowableArray<Method*> defaults; | |
939 BytecodeConstantPool bpool(klass->constants()); | 898 BytecodeConstantPool bpool(klass->constants()); |
940 | 899 |
941 for (int i = 0; i < slots->length(); ++i) { | 900 for (int i = 0; i < slots->length(); ++i) { |
942 EmptyVtableSlot* slot = slots->at(i); | 901 EmptyVtableSlot* slot = slots->at(i); |
943 | 902 |
944 if (slot->is_bound()) { | 903 if (slot->is_bound()) { |
945 MethodFamily* method = slot->get_binding(); | 904 MethodFamily* method = slot->get_binding(); |
946 int max_stack = 0; | |
947 BytecodeBuffer buffer; | 905 BytecodeBuffer buffer; |
948 | 906 |
949 #ifndef PRODUCT | 907 #ifndef PRODUCT |
950 if (TraceDefaultMethods) { | 908 if (TraceDefaultMethods) { |
951 tty->print("for slot: "); | 909 tty->print("for slot: "); |
952 slot->print_on(tty); | 910 slot->print_on(tty); |
953 tty->print_cr(""); | 911 tty->print_cr(""); |
954 if (method->has_target()) { | 912 if (method->has_target()) { |
955 method->print_selected(tty, 1); | 913 method->print_selected(tty, 1); |
956 } else { | 914 } else if (method->throws_exception()) { |
957 method->print_exception(tty, 1); | 915 method->print_exception(tty, 1); |
958 } | 916 } |
959 } | 917 } |
960 #endif // ndef PRODUCT | 918 #endif // ndef PRODUCT |
919 | |
961 if (method->has_target()) { | 920 if (method->has_target()) { |
962 Method* selected = method->get_selected_target(); | 921 Method* selected = method->get_selected_target(); |
963 if (selected->method_holder()->is_interface()) { | 922 if (selected->method_holder()->is_interface()) { |
964 max_stack = assemble_redirect( | 923 defaults.push(selected); |
965 &bpool, &buffer, slot->signature(), selected, CHECK); | |
966 } | 924 } |
967 } else if (method->throws_exception()) { | 925 } else if (method->throws_exception()) { |
968 max_stack = assemble_method_error(&bpool, &buffer, method->get_exception_name(), method->get_exception_message(), CHECK); | 926 int max_stack = assemble_method_error(&bpool, &buffer, |
969 } | 927 method->get_exception_name(), method->get_exception_message(), CHECK); |
970 if (max_stack != 0) { | |
971 AccessFlags flags = accessFlags_from( | 928 AccessFlags flags = accessFlags_from( |
972 JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); | 929 JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); |
973 Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), | 930 Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), |
974 flags, max_stack, slot->size_of_parameters(), | 931 flags, max_stack, slot->size_of_parameters(), |
975 ConstMethod::OVERPASS, CHECK); | 932 ConstMethod::OVERPASS, CHECK); |
933 // We push to the methods list: | |
934 // overpass methods which are exception throwing methods | |
976 if (m != NULL) { | 935 if (m != NULL) { |
977 overpasses.push(m); | 936 overpasses.push(m); |
978 } | 937 } |
979 } | 938 } |
980 } | 939 } |
981 } | 940 } |
982 | 941 |
983 #ifndef PRODUCT | 942 #ifndef PRODUCT |
984 if (TraceDefaultMethods) { | 943 if (TraceDefaultMethods) { |
985 tty->print_cr("Created %d overpass methods", overpasses.length()); | 944 tty->print_cr("Created %d overpass methods", overpasses.length()); |
945 tty->print_cr("Created %d default methods", defaults.length()); | |
986 } | 946 } |
987 #endif // ndef PRODUCT | 947 #endif // ndef PRODUCT |
988 | 948 |
989 switchover_constant_pool(&bpool, klass, &overpasses, CHECK); | 949 if (overpasses.length() > 0) { |
990 merge_in_new_methods(klass, &overpasses, CHECK); | 950 switchover_constant_pool(&bpool, klass, &overpasses, CHECK); |
951 merge_in_new_methods(klass, &overpasses, CHECK); | |
952 } | |
953 if (defaults.length() > 0) { | |
954 create_default_methods(klass, &defaults, CHECK); | |
955 } | |
956 } | |
957 | |
958 static void create_default_methods( InstanceKlass* klass, | |
959 GrowableArray<Method*>* new_methods, TRAPS) { | |
960 | |
961 int new_size = new_methods->length(); | |
962 Array<Method*>* total_default_methods = MetadataFactory::new_array<Method*>( | |
963 klass->class_loader_data(), new_size, NULL, CHECK); | |
964 for (int index = 0; index < new_size; index++ ) { | |
965 total_default_methods->at_put(index, new_methods->at(index)); | |
966 } | |
967 Method::sort_methods(total_default_methods, false, false); | |
968 | |
969 klass->set_default_methods(total_default_methods); | |
991 } | 970 } |
992 | 971 |
993 static void sort_methods(GrowableArray<Method*>* methods) { | 972 static void sort_methods(GrowableArray<Method*>* methods) { |
994 // Note that this must sort using the same key as is used for sorting | 973 // Note that this must sort using the same key as is used for sorting |
995 // methods in InstanceKlass. | 974 // methods in InstanceKlass. |