Mercurial > hg > truffle
comparison src/share/vm/classfile/javaClasses.hpp @ 6266:1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
6984705: JSR 292 method handle creation should not go through JNI
Summary: remove assembly code for JDK 7 chained method handles
Reviewed-by: jrose, twisti, kvn, mhaupt
Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author | twisti |
---|---|
date | Tue, 24 Jul 2012 10:51:00 -0700 |
parents | 58ad5f22317e |
children | 957c266d8bc5 da91efe96a93 |
comparison
equal
deleted
inserted
replaced
6241:aba91a731143 | 6266:1d7922586cf6 |
---|---|
881 }; | 881 }; |
882 | 882 |
883 | 883 |
884 // Interface to java.lang.invoke.MethodHandle objects | 884 // Interface to java.lang.invoke.MethodHandle objects |
885 | 885 |
886 #define METHODHANDLE_INJECTED_FIELDS(macro) \ | |
887 macro(java_lang_invoke_MethodHandle, vmentry, intptr_signature, false) \ | |
888 macro(java_lang_invoke_MethodHandle, vmtarget, object_signature, true) | |
889 | |
890 class MethodHandleEntry; | 886 class MethodHandleEntry; |
891 | 887 |
892 class java_lang_invoke_MethodHandle: AllStatic { | 888 class java_lang_invoke_MethodHandle: AllStatic { |
893 friend class JavaClasses; | 889 friend class JavaClasses; |
894 | 890 |
895 private: | 891 private: |
896 static int _vmentry_offset; // assembly code trampoline for MH | 892 static int _type_offset; // the MethodType of this MH |
897 static int _vmtarget_offset; // class-specific target reference | 893 static int _form_offset; // the LambdaForm of this MH |
898 static int _type_offset; // the MethodType of this MH | |
899 | 894 |
900 static void compute_offsets(); | 895 static void compute_offsets(); |
901 | 896 |
902 public: | 897 public: |
903 // Accessors | 898 // Accessors |
904 static oop type(oop mh); | 899 static oop type(oop mh); |
905 static void set_type(oop mh, oop mtype); | 900 static void set_type(oop mh, oop mtype); |
906 | 901 |
907 static oop vmtarget(oop mh); | 902 static oop form(oop mh); |
908 static void set_vmtarget(oop mh, oop target); | 903 static void set_form(oop mh, oop lform); |
909 | |
910 static MethodHandleEntry* vmentry(oop mh); | |
911 static void set_vmentry(oop mh, MethodHandleEntry* data); | |
912 | |
913 static int vmslots(oop mh); | |
914 | 904 |
915 // Testers | 905 // Testers |
916 static bool is_subclass(klassOop klass) { | 906 static bool is_subclass(klassOop klass) { |
917 return Klass::cast(klass)->is_subclass_of(SystemDictionary::MethodHandle_klass()); | 907 return Klass::cast(klass)->is_subclass_of(SystemDictionary::MethodHandle_klass()); |
918 } | 908 } |
920 return obj != NULL && is_subclass(obj->klass()); | 910 return obj != NULL && is_subclass(obj->klass()); |
921 } | 911 } |
922 | 912 |
923 // Accessors for code generation: | 913 // Accessors for code generation: |
924 static int type_offset_in_bytes() { return _type_offset; } | 914 static int type_offset_in_bytes() { return _type_offset; } |
925 static int vmtarget_offset_in_bytes() { return _vmtarget_offset; } | 915 static int form_offset_in_bytes() { return _form_offset; } |
926 static int vmentry_offset_in_bytes() { return _vmentry_offset; } | 916 }; |
927 }; | 917 |
928 | 918 // Interface to java.lang.invoke.LambdaForm objects |
929 #define DIRECTMETHODHANDLE_INJECTED_FIELDS(macro) \ | 919 // (These are a private interface for managing adapter code generation.) |
930 macro(java_lang_invoke_DirectMethodHandle, vmindex, int_signature, true) | 920 |
931 | 921 class java_lang_invoke_LambdaForm: AllStatic { |
932 class java_lang_invoke_DirectMethodHandle: public java_lang_invoke_MethodHandle { | 922 friend class JavaClasses; |
933 friend class JavaClasses; | 923 |
934 | 924 private: |
935 private: | 925 static int _vmentry_offset; // type is MemberName |
936 static int _vmindex_offset; // negative or vtable idx or itable idx | 926 |
937 static void compute_offsets(); | 927 static void compute_offsets(); |
938 | 928 |
939 public: | 929 public: |
940 // Accessors | 930 // Accessors |
941 static int vmindex(oop mh); | 931 static oop vmentry(oop lform); |
942 static void set_vmindex(oop mh, int index); | 932 static void set_vmentry(oop lform, oop invoker); |
943 | 933 |
944 // Testers | 934 // Testers |
945 static bool is_subclass(klassOop klass) { | 935 static bool is_subclass(klassOop klass) { |
946 return Klass::cast(klass)->is_subclass_of(SystemDictionary::DirectMethodHandle_klass()); | 936 return SystemDictionary::LambdaForm_klass() != NULL && |
937 Klass::cast(klass)->is_subclass_of(SystemDictionary::LambdaForm_klass()); | |
947 } | 938 } |
948 static bool is_instance(oop obj) { | 939 static bool is_instance(oop obj) { |
949 return obj != NULL && is_subclass(obj->klass()); | 940 return obj != NULL && is_subclass(obj->klass()); |
950 } | 941 } |
951 | 942 |
952 // Accessors for code generation: | 943 // Accessors for code generation: |
953 static int vmindex_offset_in_bytes() { return _vmindex_offset; } | 944 static int vmentry_offset_in_bytes() { return _vmentry_offset; } |
954 }; | 945 }; |
955 | |
956 class java_lang_invoke_BoundMethodHandle: public java_lang_invoke_MethodHandle { | |
957 friend class JavaClasses; | |
958 | |
959 private: | |
960 static int _argument_offset; // argument value bound into this MH | |
961 static int _vmargslot_offset; // relevant argument slot (<= vmslots) | |
962 static void compute_offsets(); | |
963 | |
964 public: | |
965 static oop argument(oop mh); | |
966 static void set_argument(oop mh, oop ref); | |
967 | |
968 static jint vmargslot(oop mh); | |
969 static void set_vmargslot(oop mh, jint slot); | |
970 | |
971 // Testers | |
972 static bool is_subclass(klassOop klass) { | |
973 return Klass::cast(klass)->is_subclass_of(SystemDictionary::BoundMethodHandle_klass()); | |
974 } | |
975 static bool is_instance(oop obj) { | |
976 return obj != NULL && is_subclass(obj->klass()); | |
977 } | |
978 | |
979 static int argument_offset_in_bytes() { return _argument_offset; } | |
980 static int vmargslot_offset_in_bytes() { return _vmargslot_offset; } | |
981 }; | |
982 | |
983 class java_lang_invoke_AdapterMethodHandle: public java_lang_invoke_BoundMethodHandle { | |
984 friend class JavaClasses; | |
985 | |
986 private: | |
987 static int _conversion_offset; // type of conversion to apply | |
988 static void compute_offsets(); | |
989 | |
990 public: | |
991 static int conversion(oop mh); | |
992 static void set_conversion(oop mh, int conv); | |
993 | |
994 // Testers | |
995 static bool is_subclass(klassOop klass) { | |
996 return Klass::cast(klass)->is_subclass_of(SystemDictionary::AdapterMethodHandle_klass()); | |
997 } | |
998 static bool is_instance(oop obj) { | |
999 return obj != NULL && is_subclass(obj->klass()); | |
1000 } | |
1001 | |
1002 // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants): | |
1003 enum { | |
1004 OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype | |
1005 OP_RETYPE_RAW = 0x1, // straight retype, trusted (void->int, Object->T) | |
1006 OP_CHECK_CAST = 0x2, // ref-to-ref conversion; requires a Class argument | |
1007 OP_PRIM_TO_PRIM = 0x3, // converts from one primitive to another | |
1008 OP_REF_TO_PRIM = 0x4, // unboxes a wrapper to produce a primitive | |
1009 OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper | |
1010 OP_SWAP_ARGS = 0x6, // swap arguments (vminfo is 2nd arg) | |
1011 OP_ROT_ARGS = 0x7, // rotate arguments (vminfo is displaced arg) | |
1012 OP_DUP_ARGS = 0x8, // duplicates one or more arguments (at TOS) | |
1013 OP_DROP_ARGS = 0x9, // remove one or more argument slots | |
1014 OP_COLLECT_ARGS = 0xA, // combine arguments using an auxiliary function | |
1015 OP_SPREAD_ARGS = 0xB, // expand in place a varargs array (of known size) | |
1016 OP_FOLD_ARGS = 0xC, // combine but do not remove arguments; prepend result | |
1017 //OP_UNUSED_13 = 0xD, // unused code, perhaps for reified argument lists | |
1018 CONV_OP_LIMIT = 0xE, // limit of CONV_OP enumeration | |
1019 | |
1020 CONV_OP_MASK = 0xF00, // this nybble contains the conversion op field | |
1021 CONV_TYPE_MASK = 0x0F, // fits T_ADDRESS and below | |
1022 CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use | |
1023 CONV_VMINFO_SHIFT = 0, // position of bits in CONV_VMINFO_MASK | |
1024 CONV_OP_SHIFT = 8, // position of bits in CONV_OP_MASK | |
1025 CONV_DEST_TYPE_SHIFT = 12, // byte 2 has the adapter BasicType (if needed) | |
1026 CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed) | |
1027 CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change | |
1028 CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1 | |
1029 }; | |
1030 | |
1031 static int conversion_offset_in_bytes() { return _conversion_offset; } | |
1032 }; | |
1033 | |
1034 | |
1035 // A simple class that maintains an invocation count | |
1036 class java_lang_invoke_CountingMethodHandle: public java_lang_invoke_MethodHandle { | |
1037 friend class JavaClasses; | |
1038 | |
1039 private: | |
1040 static int _vmcount_offset; | |
1041 static void compute_offsets(); | |
1042 | |
1043 public: | |
1044 // Accessors | |
1045 static int vmcount(oop mh); | |
1046 static void set_vmcount(oop mh, int count); | |
1047 | |
1048 // Testers | |
1049 static bool is_subclass(klassOop klass) { | |
1050 return SystemDictionary::CountingMethodHandle_klass() != NULL && | |
1051 Klass::cast(klass)->is_subclass_of(SystemDictionary::CountingMethodHandle_klass()); | |
1052 } | |
1053 static bool is_instance(oop obj) { | |
1054 return obj != NULL && is_subclass(obj->klass()); | |
1055 } | |
1056 | |
1057 // Accessors for code generation: | |
1058 static int vmcount_offset_in_bytes() { return _vmcount_offset; } | |
1059 }; | |
1060 | |
1061 | 946 |
1062 | 947 |
1063 // Interface to java.lang.invoke.MemberName objects | 948 // Interface to java.lang.invoke.MemberName objects |
1064 // (These are a private interface for Java code to query the class hierarchy.) | 949 // (These are a private interface for Java code to query the class hierarchy.) |
1065 | 950 |
1066 #define MEMBERNAME_INJECTED_FIELDS(macro) \ | 951 #define MEMBERNAME_INJECTED_FIELDS(macro) \ |
1067 macro(java_lang_invoke_MemberName, vmtarget, object_signature, true) | 952 macro(java_lang_invoke_MemberName, vmindex, intptr_signature, false) \ |
953 macro(java_lang_invoke_MemberName, vmtarget, object_signature, false) | |
1068 | 954 |
1069 class java_lang_invoke_MemberName: AllStatic { | 955 class java_lang_invoke_MemberName: AllStatic { |
1070 friend class JavaClasses; | 956 friend class JavaClasses; |
1071 | 957 |
1072 private: | 958 private: |
1074 // private Class<?> clazz; // class in which the method is defined | 960 // private Class<?> clazz; // class in which the method is defined |
1075 // private String name; // may be null if not yet materialized | 961 // private String name; // may be null if not yet materialized |
1076 // private Object type; // may be null if not yet materialized | 962 // private Object type; // may be null if not yet materialized |
1077 // private int flags; // modifier bits; see reflect.Modifier | 963 // private int flags; // modifier bits; see reflect.Modifier |
1078 // private Object vmtarget; // VM-specific target value | 964 // private Object vmtarget; // VM-specific target value |
1079 // private int vmindex; // method index within class or interface | 965 // private intptr_t vmindex; // member index within class or interface |
1080 static int _clazz_offset; | 966 static int _clazz_offset; |
1081 static int _name_offset; | 967 static int _name_offset; |
1082 static int _type_offset; | 968 static int _type_offset; |
1083 static int _flags_offset; | 969 static int _flags_offset; |
1084 static int _vmtarget_offset; | 970 static int _vmtarget_offset; |
1098 static void set_name(oop mname, oop name); | 984 static void set_name(oop mname, oop name); |
1099 | 985 |
1100 static int flags(oop mname); | 986 static int flags(oop mname); |
1101 static void set_flags(oop mname, int flags); | 987 static void set_flags(oop mname, int flags); |
1102 | 988 |
1103 static int modifiers(oop mname) { return (u2) flags(mname); } | |
1104 static void set_modifiers(oop mname, int mods) | |
1105 { set_flags(mname, (flags(mname) &~ (u2)-1) | (u2)mods); } | |
1106 | |
1107 static oop vmtarget(oop mname); | 989 static oop vmtarget(oop mname); |
1108 static void set_vmtarget(oop mname, oop target); | 990 static void set_vmtarget(oop mname, oop target); |
1109 | 991 |
1110 static int vmindex(oop mname); | 992 static intptr_t vmindex(oop mname); |
1111 static void set_vmindex(oop mname, int index); | 993 static void set_vmindex(oop mname, intptr_t index); |
1112 | 994 |
1113 // Testers | 995 // Testers |
1114 static bool is_subclass(klassOop klass) { | 996 static bool is_subclass(klassOop klass) { |
1115 return Klass::cast(klass)->is_subclass_of(SystemDictionary::MemberName_klass()); | 997 return Klass::cast(klass)->is_subclass_of(SystemDictionary::MemberName_klass()); |
1116 } | 998 } |
1122 enum { | 1004 enum { |
1123 MN_IS_METHOD = 0x00010000, // method (not constructor) | 1005 MN_IS_METHOD = 0x00010000, // method (not constructor) |
1124 MN_IS_CONSTRUCTOR = 0x00020000, // constructor | 1006 MN_IS_CONSTRUCTOR = 0x00020000, // constructor |
1125 MN_IS_FIELD = 0x00040000, // field | 1007 MN_IS_FIELD = 0x00040000, // field |
1126 MN_IS_TYPE = 0x00080000, // nested type | 1008 MN_IS_TYPE = 0x00080000, // nested type |
1127 MN_SEARCH_SUPERCLASSES = 0x00100000, // for MHN.getMembers | 1009 MN_REFERENCE_KIND_SHIFT = 24, // refKind |
1128 MN_SEARCH_INTERFACES = 0x00200000, // for MHN.getMembers | 1010 MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, |
1129 VM_INDEX_UNINITIALIZED = -99 | 1011 // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: |
1012 MN_SEARCH_SUPERCLASSES = 0x00100000, // walk super classes | |
1013 MN_SEARCH_INTERFACES = 0x00200000 // walk implemented interfaces | |
1130 }; | 1014 }; |
1131 | 1015 |
1132 // Accessors for code generation: | 1016 // Accessors for code generation: |
1133 static int clazz_offset_in_bytes() { return _clazz_offset; } | 1017 static int clazz_offset_in_bytes() { return _clazz_offset; } |
1134 static int type_offset_in_bytes() { return _type_offset; } | 1018 static int type_offset_in_bytes() { return _type_offset; } |
1145 friend class JavaClasses; | 1029 friend class JavaClasses; |
1146 | 1030 |
1147 private: | 1031 private: |
1148 static int _rtype_offset; | 1032 static int _rtype_offset; |
1149 static int _ptypes_offset; | 1033 static int _ptypes_offset; |
1150 static int _form_offset; | |
1151 | 1034 |
1152 static void compute_offsets(); | 1035 static void compute_offsets(); |
1153 | 1036 |
1154 public: | 1037 public: |
1155 // Accessors | 1038 // Accessors |
1156 static oop rtype(oop mt); | 1039 static oop rtype(oop mt); |
1157 static objArrayOop ptypes(oop mt); | 1040 static objArrayOop ptypes(oop mt); |
1158 static oop form(oop mt); | |
1159 | 1041 |
1160 static oop ptype(oop mt, int index); | 1042 static oop ptype(oop mt, int index); |
1161 static int ptype_count(oop mt); | 1043 static int ptype_count(oop mt); |
1044 | |
1045 static int ptype_slot_count(oop mt); // extra counts for long/double | |
1046 static int rtype_slot_count(oop mt); // extra counts for long/double | |
1162 | 1047 |
1163 static Symbol* as_signature(oop mt, bool intern_if_not_found, TRAPS); | 1048 static Symbol* as_signature(oop mt, bool intern_if_not_found, TRAPS); |
1164 static void print_signature(oop mt, outputStream* st); | 1049 static void print_signature(oop mt, outputStream* st); |
1165 | 1050 |
1166 static bool is_instance(oop obj) { | 1051 static bool is_instance(oop obj) { |
1170 static bool equals(oop mt1, oop mt2); | 1055 static bool equals(oop mt1, oop mt2); |
1171 | 1056 |
1172 // Accessors for code generation: | 1057 // Accessors for code generation: |
1173 static int rtype_offset_in_bytes() { return _rtype_offset; } | 1058 static int rtype_offset_in_bytes() { return _rtype_offset; } |
1174 static int ptypes_offset_in_bytes() { return _ptypes_offset; } | 1059 static int ptypes_offset_in_bytes() { return _ptypes_offset; } |
1175 static int form_offset_in_bytes() { return _form_offset; } | |
1176 }; | |
1177 | |
1178 #define METHODTYPEFORM_INJECTED_FIELDS(macro) \ | |
1179 macro(java_lang_invoke_MethodTypeForm, vmslots, int_signature, true) \ | |
1180 macro(java_lang_invoke_MethodTypeForm, vmlayout, object_signature, true) | |
1181 | |
1182 class java_lang_invoke_MethodTypeForm: AllStatic { | |
1183 friend class JavaClasses; | |
1184 | |
1185 private: | |
1186 static int _vmslots_offset; // number of argument slots needed | |
1187 static int _vmlayout_offset; // object describing internal calling sequence | |
1188 static int _erasedType_offset; // erasedType = canonical MethodType | |
1189 static int _genericInvoker_offset; // genericInvoker = adapter for invokeGeneric | |
1190 | |
1191 static void compute_offsets(); | |
1192 | |
1193 public: | |
1194 // Accessors | |
1195 static int vmslots(oop mtform); | |
1196 static void set_vmslots(oop mtform, int vmslots); | |
1197 | |
1198 static oop erasedType(oop mtform); | |
1199 static oop genericInvoker(oop mtform); | |
1200 | |
1201 static oop vmlayout(oop mtform); | |
1202 static oop init_vmlayout(oop mtform, oop cookie); | |
1203 | |
1204 // Accessors for code generation: | |
1205 static int vmslots_offset_in_bytes() { return _vmslots_offset; } | |
1206 static int vmlayout_offset_in_bytes() { return _vmlayout_offset; } | |
1207 static int erasedType_offset_in_bytes() { return _erasedType_offset; } | |
1208 static int genericInvoker_offset_in_bytes() { return _genericInvoker_offset; } | |
1209 }; | 1060 }; |
1210 | 1061 |
1211 | 1062 |
1212 // Interface to java.lang.invoke.CallSite objects | 1063 // Interface to java.lang.invoke.CallSite objects |
1213 | 1064 |
1273 | 1124 |
1274 static void compute_offsets(); | 1125 static void compute_offsets(); |
1275 | 1126 |
1276 public: | 1127 public: |
1277 static oop parent(oop loader); | 1128 static oop parent(oop loader); |
1129 static bool isAncestor(oop loader, oop cl); | |
1278 | 1130 |
1279 // Support for parallelCapable field | 1131 // Support for parallelCapable field |
1280 static bool parallelCapable(oop the_class_mirror); | 1132 static bool parallelCapable(oop the_class_mirror); |
1281 | 1133 |
1282 static bool is_trusted_loader(oop loader); | 1134 static bool is_trusted_loader(oop loader); |
1283 | 1135 |
1284 // Fix for 4474172 | 1136 // Fix for 4474172 |
1285 static oop non_reflection_class_loader(oop loader); | 1137 static oop non_reflection_class_loader(oop loader); |
1138 | |
1139 // Testers | |
1140 static bool is_subclass(klassOop klass) { | |
1141 return Klass::cast(klass)->is_subclass_of(SystemDictionary::ClassLoader_klass()); | |
1142 } | |
1143 static bool is_instance(oop obj) { | |
1144 return obj != NULL && is_subclass(obj->klass()); | |
1145 } | |
1286 | 1146 |
1287 // Debugging | 1147 // Debugging |
1288 friend class JavaClasses; | 1148 friend class JavaClasses; |
1289 }; | 1149 }; |
1290 | 1150 |
1423 #define DECLARE_INJECTED_FIELD_ENUM(klass, name, signature, may_be_java) \ | 1283 #define DECLARE_INJECTED_FIELD_ENUM(klass, name, signature, may_be_java) \ |
1424 klass##_##name##_enum, | 1284 klass##_##name##_enum, |
1425 | 1285 |
1426 #define ALL_INJECTED_FIELDS(macro) \ | 1286 #define ALL_INJECTED_FIELDS(macro) \ |
1427 CLASS_INJECTED_FIELDS(macro) \ | 1287 CLASS_INJECTED_FIELDS(macro) \ |
1428 METHODHANDLE_INJECTED_FIELDS(macro) \ | 1288 MEMBERNAME_INJECTED_FIELDS(macro) |
1429 DIRECTMETHODHANDLE_INJECTED_FIELDS(macro) \ | |
1430 MEMBERNAME_INJECTED_FIELDS(macro) \ | |
1431 METHODTYPEFORM_INJECTED_FIELDS(macro) | |
1432 | 1289 |
1433 // Interface to hard-coded offset checking | 1290 // Interface to hard-coded offset checking |
1434 | 1291 |
1435 class JavaClasses : AllStatic { | 1292 class JavaClasses : AllStatic { |
1436 private: | 1293 private: |