comparison src/share/vm/interpreter/linkResolver.cpp @ 12318:36b97be47bde

8011311: Private interface methods. Default conflicts:ICCE. no erased_super_default. Reviewed-by: coleenp, bharadwaj, minqi
author acorn
date Tue, 01 Oct 2013 08:10:42 -0400
parents 190899198332
children 359f7e70ae7f ac9cb1d5a202
comparison
equal deleted inserted replaced
12317:a5ac0873476c 12318:36b97be47bde
1 /* 1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 3 *
5 * This code is free software; you can redistribute it and/or modify it 4 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 5 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
571 method_signature)); 570 method_signature));
572 } 571 }
573 } 572 }
574 573
575 if (check_access) { 574 if (check_access) {
575 // JDK8 adds non-public interface methods, and accessability check requirement
576 assert(current_klass.not_null() , "current_klass should not be null");
577
578 // check if method can be accessed by the referring class
579 check_method_accessability(current_klass,
580 resolved_klass,
581 KlassHandle(THREAD, resolved_method->method_holder()),
582 resolved_method,
583 CHECK);
584
576 HandleMark hm(THREAD); 585 HandleMark hm(THREAD);
577 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); 586 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
578 Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); 587 Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
579 { 588 {
580 ResourceMark rm(THREAD); 589 ResourceMark rm(THREAD);
602 target, failed_type_name); 611 target, failed_type_name);
603 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); 612 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
604 } 613 }
605 } 614 }
606 } 615 }
616
617 if (TraceItables && Verbose) {
618 ResourceMark rm(THREAD);
619 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
620 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
621 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
622 Method::name_and_sig_as_C_string(resolved_klass(),
623 resolved_method->name(),
624 resolved_method->signature()),
625 resolved_method->method_holder()->internal_name()
626 );
627 resolved_method->access_flags().print_on(tty);
628 tty->cr();
629 }
607 } 630 }
608 631
609 //------------------------------------------------------------------------------------------------------------------------ 632 //------------------------------------------------------------------------------------------------------------------------
610 // Field resolution 633 // Field resolution
611 634
793 // throws linktime exceptions 816 // throws linktime exceptions
794 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, 817 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
795 Symbol* method_name, Symbol* method_signature, 818 Symbol* method_name, Symbol* method_signature,
796 KlassHandle current_klass, bool check_access, TRAPS) { 819 KlassHandle current_klass, bool check_access, TRAPS) {
797 820
798 if (resolved_klass->is_interface() && current_klass() != NULL) { 821 // Invokespecial is called for multiple special reasons:
799 // If the target class is a direct interface, treat this as a "super" 822 // <init>
800 // default call. 823 // local private method invocation, for classes and interfaces
801 // 824 // superclass.method, which can also resolve to a default method
802 // If the current method is an overpass that happens to call a direct 825 // and the selected method is recalculated relative to the direct superclass
803 // super-interface's method, then we'll end up rerunning the default method 826 // superinterface.method, which explicitly does not check shadowing
804 // analysis even though we don't need to, but that's ok since it will end
805 // up with the same answer.
806 InstanceKlass* ik = InstanceKlass::cast(current_klass());
807 Array<Klass*>* interfaces = ik->local_interfaces();
808 int num_interfaces = interfaces->length();
809 for (int index = 0; index < num_interfaces; index++) {
810 if (interfaces->at(index) == resolved_klass()) {
811 Method* method = DefaultMethods::find_super_default(current_klass(),
812 resolved_klass(), method_name, method_signature, CHECK);
813 resolved_method = methodHandle(THREAD, method);
814 return;
815 }
816 }
817 }
818 827
819 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 828 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
820 829
821 // check if method name is <init>, that it is found in same klass as static type 830 // check if method name is <init>, that it is found in same klass as static type
822 if (resolved_method->name() == vmSymbols::object_initializer_name() && 831 if (resolved_method->name() == vmSymbols::object_initializer_name() &&
842 Method::name_and_sig_as_C_string(resolved_klass(), 851 Method::name_and_sig_as_C_string(resolved_klass(),
843 resolved_method->name(), 852 resolved_method->name(),
844 resolved_method->signature())); 853 resolved_method->signature()));
845 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 854 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
846 } 855 }
856 if (TraceItables && Verbose) {
857 ResourceMark rm(THREAD);
858 tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
859 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
860 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
861 Method::name_and_sig_as_C_string(resolved_klass(),
862 resolved_method->name(),
863 resolved_method->signature()),
864 resolved_method->method_holder()->internal_name()
865 );
866 resolved_method->access_flags().print_on(tty);
867 if (resolved_method->method_holder()->is_interface() &&
868 !resolved_method->is_abstract()) {
869 tty->print("default");
870 }
871 if (resolved_method->is_overpass()) {
872 tty->print("overpass");
873 }
874 tty->cr();
875 }
847 } 876 }
848 877
849 // throws runtime exceptions 878 // throws runtime exceptions
850 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, 879 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
851 KlassHandle current_klass, bool check_access, TRAPS) { 880 KlassHandle current_klass, bool check_access, TRAPS) {
852 881
853 // resolved method is selected method unless we have an old-style lookup 882 // resolved method is selected method unless we have an old-style lookup
883 // for a superclass method
884 // Invokespecial for a superinterface, resolved method is selected method,
885 // no checks for shadowing
854 methodHandle sel_method(THREAD, resolved_method()); 886 methodHandle sel_method(THREAD, resolved_method());
855 887
856 // check if this is an old-style super call and do a new lookup if so 888 // check if this is an old-style super call and do a new lookup if so
857 { KlassHandle method_klass = KlassHandle(THREAD, 889 { KlassHandle method_klass = KlassHandle(THREAD,
858 resolved_method->method_holder()); 890 resolved_method->method_holder());
859 891
860 const bool direct_calling_default_method = 892 if (check_access &&
861 resolved_klass() != NULL && resolved_method() != NULL &&
862 resolved_klass->is_interface() && !resolved_method->is_abstract();
863
864 if (!direct_calling_default_method &&
865 check_access &&
866 // a) check if ACC_SUPER flag is set for the current class 893 // a) check if ACC_SUPER flag is set for the current class
867 (current_klass->is_super() || !AllowNonVirtualCalls) && 894 (current_klass->is_super() || !AllowNonVirtualCalls) &&
868 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) 895 // b) check if the class of the resolved_klass is a superclass
869 current_klass->is_subtype_of(method_klass()) && 896 // (not supertype in order to exclude interface classes) of the current class.
870 current_klass() != method_klass() && 897 // This check is not performed for super.invoke for interface methods
898 // in super interfaces.
899 current_klass->is_subclass_of(resolved_klass()) &&
900 current_klass() != resolved_klass() &&
871 // c) check if the method is not <init> 901 // c) check if the method is not <init>
872 resolved_method->name() != vmSymbols::object_initializer_name()) { 902 resolved_method->name() != vmSymbols::object_initializer_name()) {
873 // Lookup super method 903 // Lookup super method
874 KlassHandle super_klass(THREAD, current_klass->super()); 904 KlassHandle super_klass(THREAD, current_klass->super());
875 lookup_instance_method_in_klasses(sel_method, super_klass, 905 lookup_instance_method_in_klasses(sel_method, super_klass,
903 Method::name_and_sig_as_C_string(resolved_klass(), 933 Method::name_and_sig_as_C_string(resolved_klass(),
904 sel_method->name(), 934 sel_method->name(),
905 sel_method->signature())); 935 sel_method->signature()));
906 } 936 }
907 937
938 if (TraceItables && Verbose) {
939 ResourceMark rm(THREAD);
940 tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
941 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
942 Method::name_and_sig_as_C_string(resolved_klass(),
943 sel_method->name(),
944 sel_method->signature()),
945 sel_method->method_holder()->internal_name()
946 );
947 sel_method->access_flags().print_on(tty);
948 if (sel_method->method_holder()->is_interface() &&
949 !sel_method->is_abstract()) {
950 tty->print("default");
951 }
952 tty->cr();
953 }
954
908 // setup result 955 // setup result
909 result.set_static(resolved_klass, sel_method, CHECK); 956 result.set_static(resolved_klass, sel_method, CHECK);
910 } 957 }
911 958
912 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass, 959 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass,
925 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 972 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
926 973
927 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); 974 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
928 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); 975 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
929 976
977 // check if private interface method
978 if (resolved_klass->is_interface() && resolved_method->is_private()) {
979 ResourceMark rm(THREAD);
980 char buf[200];
981 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
982 Method::name_and_sig_as_C_string(resolved_klass(),
983 resolved_method->name(),
984 resolved_method->signature()),
985 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
986 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
987 }
988
930 // check if not static 989 // check if not static
931 if (resolved_method->is_static()) { 990 if (resolved_method->is_static()) {
932 ResourceMark rm(THREAD); 991 ResourceMark rm(THREAD);
933 char buf[200]; 992 char buf[200];
934 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(), 993 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
935 resolved_method->name(), 994 resolved_method->name(),
936 resolved_method->signature())); 995 resolved_method->signature()));
937 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 996 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
938 } 997 }
998
999 if (PrintVtables && Verbose) {
1000 ResourceMark rm(THREAD);
1001 tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
1002 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
1003 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
1004 Method::name_and_sig_as_C_string(resolved_klass(),
1005 resolved_method->name(),
1006 resolved_method->signature()),
1007 resolved_method->method_holder()->internal_name()
1008 );
1009 resolved_method->access_flags().print_on(tty);
1010 if (resolved_method->method_holder()->is_interface() &&
1011 !resolved_method->is_abstract()) {
1012 tty->print("default");
1013 }
1014 if (resolved_method->is_overpass()) {
1015 tty->print("overpass");
1016 }
1017 tty->cr();
1018 }
939 } 1019 }
940 1020
941 // throws runtime exceptions 1021 // throws runtime exceptions
942 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, 1022 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
943 methodHandle resolved_method, 1023 methodHandle resolved_method,
1010 Method::name_and_sig_as_C_string(resolved_klass(), 1090 Method::name_and_sig_as_C_string(resolved_klass(),
1011 selected_method->name(), 1091 selected_method->name(),
1012 selected_method->signature())); 1092 selected_method->signature()));
1013 } 1093 }
1014 1094
1095 if (PrintVtables && Verbose) {
1096 ResourceMark rm(THREAD);
1097 tty->print("invokevirtual selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, vtable_index:%d, access_flags: ",
1098 (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
1099 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
1100 Method::name_and_sig_as_C_string(resolved_klass(),
1101 resolved_method->name(),
1102 resolved_method->signature()),
1103 selected_method->method_holder()->internal_name(),
1104 vtable_index
1105 );
1106 selected_method->access_flags().print_on(tty);
1107 if (selected_method->method_holder()->is_interface() &&
1108 !selected_method->is_abstract()) {
1109 tty->print("default");
1110 }
1111 if (resolved_method->is_overpass()) {
1112 tty->print("overpass");
1113 }
1114 tty->cr();
1115 }
1015 // setup result 1116 // setup result
1016 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); 1117 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
1017 } 1118 }
1018 1119
1019 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, 1120 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass,
1038 void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, 1139 void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
1039 Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) { 1140 Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
1040 // check if receiver exists 1141 // check if receiver exists
1041 if (check_null_and_abstract && recv.is_null()) { 1142 if (check_null_and_abstract && recv.is_null()) {
1042 THROW(vmSymbols::java_lang_NullPointerException()); 1143 THROW(vmSymbols::java_lang_NullPointerException());
1144 }
1145
1146 // check if private interface method
1147 if (resolved_klass->is_interface() && resolved_method->is_private()) {
1148 ResourceMark rm(THREAD);
1149 char buf[200];
1150 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s",
1151 Method::name_and_sig_as_C_string(resolved_klass(),
1152 resolved_method->name(),
1153 resolved_method->signature()));
1154 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
1043 } 1155 }
1044 1156
1045 // check if receiver klass implements the resolved interface 1157 // check if receiver klass implements the resolved interface
1046 if (!recv_klass->is_subtype_of(resolved_klass())) { 1158 if (!recv_klass->is_subtype_of(resolved_klass())) {
1047 ResourceMark rm(THREAD); 1159 ResourceMark rm(THREAD);
1069 Method::name_and_sig_as_C_string(recv_klass(), 1181 Method::name_and_sig_as_C_string(recv_klass(),
1070 resolved_method->name(), 1182 resolved_method->name(),
1071 resolved_method->signature())); 1183 resolved_method->signature()));
1072 } 1184 }
1073 // check access 1185 // check access
1074 if (sel_method->method_holder()->is_interface()) { 1186 // Throw Illegal Access Error if sel_method is not public.
1075 // Method holder is an interface. Throw Illegal Access Error if sel_method 1187 if (!sel_method->is_public()) {
1076 // is neither public nor private. 1188 ResourceMark rm(THREAD);
1077 if (!(sel_method->is_public() || sel_method->is_private())) { 1189 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
1078 ResourceMark rm(THREAD); 1190 Method::name_and_sig_as_C_string(recv_klass(),
1079 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), 1191 sel_method->name(),
1080 Method::name_and_sig_as_C_string(recv_klass(), 1192 sel_method->signature()));
1081 sel_method->name(), 1193 }
1082 sel_method->signature())); 1194
1083 }
1084 }
1085 else {
1086 // Method holder is a class. Throw Illegal Access Error if sel_method
1087 // is not public.
1088 if (!sel_method->is_public()) {
1089 ResourceMark rm(THREAD);
1090 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
1091 Method::name_and_sig_as_C_string(recv_klass(),
1092 sel_method->name(),
1093 sel_method->signature()));
1094 }
1095 }
1096 // check if abstract 1195 // check if abstract
1097 if (check_null_and_abstract && sel_method->is_abstract()) { 1196 if (check_null_and_abstract && sel_method->is_abstract()) {
1098 ResourceMark rm(THREAD); 1197 ResourceMark rm(THREAD);
1099 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), 1198 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
1100 Method::name_and_sig_as_C_string(recv_klass(), 1199 Method::name_and_sig_as_C_string(recv_klass(),
1107 assert(vtable_index == sel_method->vtable_index(), "sanity check"); 1206 assert(vtable_index == sel_method->vtable_index(), "sanity check");
1108 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK); 1207 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
1109 return; 1208 return;
1110 } 1209 }
1111 int itable_index = resolved_method()->itable_index(); 1210 int itable_index = resolved_method()->itable_index();
1211
1212 if (TraceItables && Verbose) {
1213 ResourceMark rm(THREAD);
1214 tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
1215 (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
1216 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
1217 Method::name_and_sig_as_C_string(resolved_klass(),
1218 resolved_method->name(),
1219 resolved_method->signature()),
1220 sel_method->method_holder()->internal_name()
1221 );
1222 sel_method->access_flags().print_on(tty);
1223 if (sel_method->method_holder()->is_interface() &&
1224 !sel_method->is_abstract()) {
1225 tty->print("default");
1226 }
1227 if (resolved_method->is_overpass()) {
1228 tty->print("overpass");
1229 }
1230 tty->cr();
1231 }
1112 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); 1232 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
1113 } 1233 }
1114 1234
1115 1235
1116 methodHandle LinkResolver::linktime_resolve_interface_method_or_null( 1236 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(