Mercurial > hg > graal-compiler
comparison src/share/vm/prims/methodHandles.cpp @ 1039:987e948ebbc8
6815692: method handle code needs some cleanup (post-6655638)
Summary: correctly raise exceptions, support safe bitwise "raw" conversions, fix bugs revealed by VerifyMethodHandles, remove dead code, improve debugging support
Reviewed-by: never, twisti
author | jrose |
---|---|
date | Sat, 17 Oct 2009 19:51:05 -0700 |
parents | be93aad57795 |
children | 389049f3f393 |
comparison
equal
deleted
inserted
replaced
1038:71fdc5052e49 | 1039:987e948ebbc8 |
---|---|
31 | 31 |
32 bool MethodHandles::_enabled = false; // set true after successful native linkage | 32 bool MethodHandles::_enabled = false; // set true after successful native linkage |
33 | 33 |
34 MethodHandleEntry* MethodHandles::_entries[MethodHandles::_EK_LIMIT] = {NULL}; | 34 MethodHandleEntry* MethodHandles::_entries[MethodHandles::_EK_LIMIT] = {NULL}; |
35 const char* MethodHandles::_entry_names[_EK_LIMIT+1] = { | 35 const char* MethodHandles::_entry_names[_EK_LIMIT+1] = { |
36 "check_mtype", | 36 "raise_exception", |
37 "wrong_method_type", // what happens when there is a type mismatch | |
38 "invokestatic", // how a MH emulates invokestatic | 37 "invokestatic", // how a MH emulates invokestatic |
39 "invokespecial", // ditto for the other invokes... | 38 "invokespecial", // ditto for the other invokes... |
40 "invokevirtual", | 39 "invokevirtual", |
41 "invokeinterface", | 40 "invokeinterface", |
42 "bound_ref", // these are for BMH... | 41 "bound_ref", // these are for BMH... |
46 "bound_int_direct", | 45 "bound_int_direct", |
47 "bound_long_direct", | 46 "bound_long_direct", |
48 | 47 |
49 // starting at _adapter_mh_first: | 48 // starting at _adapter_mh_first: |
50 "adapter_retype_only", // these are for AMH... | 49 "adapter_retype_only", // these are for AMH... |
50 "adapter_retype_raw", | |
51 "adapter_check_cast", | 51 "adapter_check_cast", |
52 "adapter_prim_to_prim", | 52 "adapter_prim_to_prim", |
53 "adapter_ref_to_prim", | 53 "adapter_ref_to_prim", |
54 "adapter_prim_to_ref", | 54 "adapter_prim_to_ref", |
55 "adapter_swap_args", | 55 "adapter_swap_args", |
80 "adapter_spread_args/more", | 80 "adapter_spread_args/more", |
81 | 81 |
82 NULL | 82 NULL |
83 }; | 83 }; |
84 | 84 |
85 jobject MethodHandles::_raise_exception_method; | |
86 | |
85 #ifdef ASSERT | 87 #ifdef ASSERT |
86 bool MethodHandles::spot_check_entry_names() { | 88 bool MethodHandles::spot_check_entry_names() { |
87 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); | 89 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); |
88 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); | 90 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); |
89 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); | 91 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); |
155 oop mtype = sun_dyn_DirectMethodHandle::type(mh); | 157 oop mtype = sun_dyn_DirectMethodHandle::type(mh); |
156 return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result); | 158 return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result); |
157 } | 159 } |
158 | 160 |
159 methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { | 161 methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
160 assert(mh->klass() == SystemDictionary::BoundMethodHandle_klass(), ""); | 162 assert(sun_dyn_BoundMethodHandle::is_instance(mh), ""); |
163 assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), ""); | |
161 for (oop bmh = mh;;) { | 164 for (oop bmh = mh;;) { |
162 // Bound MHs can be stacked to bind several arguments. | 165 // Bound MHs can be stacked to bind several arguments. |
163 oop target = java_dyn_MethodHandle::vmtarget(bmh); | 166 oop target = java_dyn_MethodHandle::vmtarget(bmh); |
164 if (target == NULL) return NULL; | 167 if (target == NULL) return NULL; |
165 decode_flags_result |= MethodHandles::_dmf_binds_argument; | 168 decode_flags_result |= MethodHandles::_dmf_binds_argument; |
172 //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH"); | 175 //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH"); |
173 return decode_MethodHandle(target, receiver_limit_result, decode_flags_result); | 176 return decode_MethodHandle(target, receiver_limit_result, decode_flags_result); |
174 } else { | 177 } else { |
175 // Optimized case: binding a receiver to a non-dispatched DMH | 178 // Optimized case: binding a receiver to a non-dispatched DMH |
176 // short-circuits directly to the methodOop. | 179 // short-circuits directly to the methodOop. |
180 // (It might be another argument besides a receiver also.) | |
177 assert(target->is_method(), "must be a simple method"); | 181 assert(target->is_method(), "must be a simple method"); |
178 methodOop m = (methodOop) target; | 182 methodOop m = (methodOop) target; |
179 DEBUG_ONLY(int argslot = sun_dyn_BoundMethodHandle::vmargslot(bmh)); | |
180 assert(argslot == m->size_of_parameters() - 1, "must be initial argument (receiver)"); | |
181 decode_flags_result |= MethodHandles::_dmf_binds_method; | 183 decode_flags_result |= MethodHandles::_dmf_binds_method; |
182 return m; | 184 return m; |
183 } | 185 } |
184 } | 186 } |
185 } | 187 } |
212 return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result); | 214 return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result); |
213 } else if (mhk == SystemDictionary::BoundMethodHandle_klass()) { | 215 } else if (mhk == SystemDictionary::BoundMethodHandle_klass()) { |
214 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); | 216 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); |
215 } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) { | 217 } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) { |
216 return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result); | 218 return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result); |
219 } else if (sun_dyn_BoundMethodHandle::is_subclass(mhk)) { | |
220 // could be a JavaMethodHandle (but not an adapter MH) | |
221 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); | |
217 } else { | 222 } else { |
218 assert(false, "cannot parse this MH"); | 223 assert(false, "cannot parse this MH"); |
219 return NULL; // random MH? | 224 return NULL; // random MH? |
220 } | 225 } |
221 } | 226 } |
364 int flags = sun_dyn_MemberName::flags(mname); | 369 int flags = sun_dyn_MemberName::flags(mname); |
365 if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable | 370 if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable |
366 oop vmtarget = sun_dyn_MemberName::vmtarget(mname); | 371 oop vmtarget = sun_dyn_MemberName::vmtarget(mname); |
367 int vmindex = sun_dyn_MemberName::vmindex(mname); | 372 int vmindex = sun_dyn_MemberName::vmindex(mname); |
368 if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved | 373 if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved |
369 return decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); | 374 methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); |
375 oop clazz = sun_dyn_MemberName::clazz(mname); | |
376 if (clazz != NULL && java_lang_Class::is_instance(clazz)) { | |
377 klassOop klass = java_lang_Class::as_klassOop(clazz); | |
378 if (klass != NULL) receiver_limit_result = klass; | |
379 } | |
380 return m; | |
370 } | 381 } |
371 | 382 |
372 // An unresolved member name is a mere symbolic reference. | 383 // An unresolved member name is a mere symbolic reference. |
373 // Resolving it plants a vmtarget/vmindex in it, | 384 // Resolving it plants a vmtarget/vmindex in it, |
374 // which refers dirctly to JVM internals. | 385 // which refers dirctly to JVM internals. |
787 char msg[50]; | 798 char msg[50]; |
788 jio_snprintf(msg, sizeof(msg), "unknown getTarget format=%d", format); | 799 jio_snprintf(msg, sizeof(msg), "unknown getTarget format=%d", format); |
789 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg); | 800 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg); |
790 } | 801 } |
791 | 802 |
803 static const char* always_null_names[] = { | |
804 "java/lang/Void", | |
805 "java/lang/Null", | |
806 //"java/lang/Nothing", | |
807 "sun/dyn/empty/Empty", | |
808 NULL | |
809 }; | |
810 | |
811 static bool is_always_null_type(klassOop klass) { | |
812 if (!Klass::cast(klass)->oop_is_instance()) return false; | |
813 instanceKlass* ik = instanceKlass::cast(klass); | |
814 // Must be on the boot class path: | |
815 if (ik->class_loader() != NULL) return false; | |
816 // Check the name. | |
817 symbolOop name = ik->name(); | |
818 for (int i = 0; ; i++) { | |
819 const char* test_name = always_null_names[i]; | |
820 if (test_name == NULL) break; | |
821 if (name->equals(test_name, (int) strlen(test_name))) | |
822 return true; | |
823 } | |
824 return false; | |
825 } | |
826 | |
792 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) { | 827 bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) { |
793 if (src == dst || dst == SystemDictionary::object_klass()) | 828 if (src == dst || dst == SystemDictionary::object_klass()) |
794 return false; // quickest checks | 829 return false; // quickest checks |
795 Klass* srck = Klass::cast(src); | 830 Klass* srck = Klass::cast(src); |
796 Klass* dstk = Klass::cast(dst); | 831 Klass* dstk = Klass::cast(dst); |
803 if (srck->is_interface()) { | 838 if (srck->is_interface()) { |
804 // interface arguments must be viewed as untyped | 839 // interface arguments must be viewed as untyped |
805 //srck = Klass::cast(SystemDictionary::object_klass()); | 840 //srck = Klass::cast(SystemDictionary::object_klass()); |
806 return true; | 841 return true; |
807 } | 842 } |
843 if (is_always_null_type(src)) { | |
844 // some source types are known to be never instantiated; | |
845 // they represent references which are always null | |
846 // such null references never fail to convert safely | |
847 return false; | |
848 } | |
808 return !srck->is_subclass_of(dstk->as_klassOop()); | 849 return !srck->is_subclass_of(dstk->as_klassOop()); |
809 } | 850 } |
810 | 851 |
811 static oop object_java_mirror() { | 852 static oop object_java_mirror() { |
812 return Klass::cast(SystemDictionary::object_klass())->java_mirror(); | 853 return Klass::cast(SystemDictionary::object_klass())->java_mirror(); |
813 } | 854 } |
814 | 855 |
815 bool MethodHandles::same_basic_type_for_arguments(BasicType src, | 856 bool MethodHandles::same_basic_type_for_arguments(BasicType src, |
816 BasicType dst, | 857 BasicType dst, |
858 bool raw, | |
817 bool for_return) { | 859 bool for_return) { |
818 // return values can always be forgotten: | 860 if (for_return) { |
819 if (for_return && dst == T_VOID) return true; | 861 // return values can always be forgotten: |
862 if (dst == T_VOID) return true; | |
863 if (src == T_VOID) return raw && (dst == T_INT); | |
864 // We allow caller to receive a garbage int, which is harmless. | |
865 // This trick is pulled by trusted code (see VerifyType.canPassRaw). | |
866 } | |
820 assert(src != T_VOID && dst != T_VOID, "should not be here"); | 867 assert(src != T_VOID && dst != T_VOID, "should not be here"); |
821 if (src == dst) return true; | 868 if (src == dst) return true; |
822 if (type2size[src] != type2size[dst]) return false; | 869 if (type2size[src] != type2size[dst]) return false; |
823 // allow reinterpretation casts for integral widening | 870 // allow reinterpretation casts for integral widening |
824 if (is_subword_type(src)) { // subwords can fit in int or other subwords | 871 if (is_subword_type(src)) { // subwords can fit in int or other subwords |
927 bool m_needs_receiver = !m->is_static(); | 974 bool m_needs_receiver = !m->is_static(); |
928 | 975 |
929 const char* err = NULL; | 976 const char* err = NULL; |
930 | 977 |
931 int first_ptype_pos = m_needs_receiver ? 1 : 0; | 978 int first_ptype_pos = m_needs_receiver ? 1 : 0; |
932 if (has_bound_recv && err == NULL) { | 979 if (has_bound_recv) { |
933 first_ptype_pos -= 1; | 980 first_ptype_pos -= 1; // ptypes do not include the bound argument; start earlier in them |
934 if (m_needs_receiver && bound_recv_type.is_null()) | 981 if (m_needs_receiver && bound_recv_type.is_null()) |
935 { err = "bound receiver is not an object"; goto die; } | 982 { err = "bound receiver is not an object"; goto die; } |
936 } | 983 } |
937 | 984 |
938 if (m_needs_receiver && err == NULL) { | 985 if (m_needs_receiver && err == NULL) { |
939 objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype()); | 986 objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype()); |
940 if (ptypes->length() < first_ptype_pos) | 987 if (ptypes->length() < first_ptype_pos) |
941 { err = "receiver argument is missing"; goto die; } | 988 { err = "receiver argument is missing"; goto die; } |
942 if (first_ptype_pos == -1) | 989 if (has_bound_recv) |
943 err = check_method_receiver(m(), bound_recv_type->as_klassOop()); | 990 err = check_method_receiver(m(), bound_recv_type->as_klassOop()); |
944 else | 991 else |
945 err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(0))); | 992 err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(first_ptype_pos-1))); |
946 if (err != NULL) goto die; | 993 if (err != NULL) goto die; |
947 } | 994 } |
948 | 995 |
949 // Check the other arguments for mistypes. | 996 // Check the other arguments for mistypes. |
950 verify_method_signature(m, mtype, first_ptype_pos, bound_recv_type, CHECK); | 997 verify_method_signature(m, mtype, first_ptype_pos, bound_recv_type, CHECK); |
981 // Return NULL if all is well, else a short error message. | 1028 // Return NULL if all is well, else a short error message. |
982 const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end, | 1029 const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end, |
983 int insert_argnum, oop insert_type, | 1030 int insert_argnum, oop insert_type, |
984 int change_argnum, oop change_type, | 1031 int change_argnum, oop change_type, |
985 int delete_argnum, | 1032 int delete_argnum, |
986 oop dst_mtype, int dst_beg, int dst_end) { | 1033 oop dst_mtype, int dst_beg, int dst_end, |
1034 bool raw) { | |
987 objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype); | 1035 objArrayOop src_ptypes = java_dyn_MethodType::ptypes(src_mtype); |
988 objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype); | 1036 objArrayOop dst_ptypes = java_dyn_MethodType::ptypes(dst_mtype); |
989 | 1037 |
990 int src_max = src_ptypes->length(); | 1038 int src_max = src_ptypes->length(); |
991 int dst_max = dst_ptypes->length(); | 1039 int dst_max = dst_ptypes->length(); |
1040 | 1088 |
1041 // Compare the two argument types. | 1089 // Compare the two argument types. |
1042 if (src_type != dst_type) { | 1090 if (src_type != dst_type) { |
1043 if (src_type == NULL) return "not enough arguments"; | 1091 if (src_type == NULL) return "not enough arguments"; |
1044 if (dst_type == NULL) return "too many arguments"; | 1092 if (dst_type == NULL) return "too many arguments"; |
1045 err = check_argument_type_change(src_type, dst_type, dst_idx); | 1093 err = check_argument_type_change(src_type, dst_type, dst_idx, raw); |
1046 if (err != NULL) return err; | 1094 if (err != NULL) return err; |
1047 } | 1095 } |
1048 } | 1096 } |
1049 | 1097 |
1050 // Now compare return types also. | 1098 // Now compare return types also. |
1051 oop src_rtype = java_dyn_MethodType::rtype(src_mtype); | 1099 oop src_rtype = java_dyn_MethodType::rtype(src_mtype); |
1052 oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype); | 1100 oop dst_rtype = java_dyn_MethodType::rtype(dst_mtype); |
1053 if (src_rtype != dst_rtype) { | 1101 if (src_rtype != dst_rtype) { |
1054 err = check_return_type_change(dst_rtype, src_rtype); // note reversal! | 1102 err = check_return_type_change(dst_rtype, src_rtype, raw); // note reversal! |
1055 if (err != NULL) return err; | 1103 if (err != NULL) return err; |
1056 } | 1104 } |
1057 | 1105 |
1058 assert(err == NULL, ""); | 1106 assert(err == NULL, ""); |
1059 return NULL; // all is well | 1107 return NULL; // all is well |
1060 } | 1108 } |
1061 | 1109 |
1062 | 1110 |
1063 const char* MethodHandles::check_argument_type_change(BasicType src_type, | 1111 const char* MethodHandles::check_argument_type_change(BasicType src_type, |
1064 klassOop src_klass, | 1112 klassOop src_klass, |
1065 BasicType dst_type, | 1113 BasicType dst_type, |
1066 klassOop dst_klass, | 1114 klassOop dst_klass, |
1067 int argnum) { | 1115 int argnum, |
1116 bool raw) { | |
1068 const char* err = NULL; | 1117 const char* err = NULL; |
1118 bool for_return = (argnum < 0); | |
1069 | 1119 |
1070 // just in case: | 1120 // just in case: |
1071 if (src_type == T_ARRAY) src_type = T_OBJECT; | 1121 if (src_type == T_ARRAY) src_type = T_OBJECT; |
1072 if (dst_type == T_ARRAY) dst_type = T_OBJECT; | 1122 if (dst_type == T_ARRAY) dst_type = T_OBJECT; |
1073 | 1123 |
1074 // Produce some nice messages if VerifyMethodHandles is turned on: | 1124 // Produce some nice messages if VerifyMethodHandles is turned on: |
1075 if (!same_basic_type_for_arguments(src_type, dst_type, (argnum < 0))) { | 1125 if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) { |
1076 if (src_type == T_OBJECT) { | 1126 if (src_type == T_OBJECT) { |
1127 if (raw && dst_type == T_INT && is_always_null_type(src_klass)) | |
1128 return NULL; // OK to convert a null pointer to a garbage int | |
1077 err = ((argnum >= 0) | 1129 err = ((argnum >= 0) |
1078 ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s" | 1130 ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s" |
1079 : "type mismatch: returning a %s, but caller expects primitive %s"); | 1131 : "type mismatch: returning a %s, but caller expects primitive %s"); |
1080 } else if (dst_type == T_OBJECT) { | 1132 } else if (dst_type == T_OBJECT) { |
1081 err = ((argnum < 0) | 1133 err = ((argnum >= 0) |
1082 ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s" | 1134 ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s" |
1083 : "type mismatch: returning a primitive %s, but caller expects %s"); | 1135 : "type mismatch: returning a primitive %s, but caller expects %s"); |
1084 } else { | 1136 } else { |
1085 err = ((argnum < 0) | 1137 err = ((argnum >= 0) |
1086 ? "type mismatch: passing a %s for method argument #%d, which expects %s" | 1138 ? "type mismatch: passing a %s for method argument #%d, which expects %s" |
1087 : "type mismatch: returning a %s, but caller expects %s"); | 1139 : "type mismatch: returning a %s, but caller expects %s"); |
1088 } | 1140 } |
1089 } else if (src_type == T_OBJECT && class_cast_needed(src_klass, dst_klass)) { | 1141 } else if (src_type == T_OBJECT && dst_type == T_OBJECT && |
1142 class_cast_needed(src_klass, dst_klass)) { | |
1090 if (!class_cast_needed(dst_klass, src_klass)) { | 1143 if (!class_cast_needed(dst_klass, src_klass)) { |
1091 err = ((argnum < 0) | 1144 if (raw) |
1145 return NULL; // reverse cast is OK; the MH target is trusted to enforce it | |
1146 err = ((argnum >= 0) | |
1092 ? "cast required: passing a %s for method argument #%d, which expects %s" | 1147 ? "cast required: passing a %s for method argument #%d, which expects %s" |
1093 : "cast required: returning a %s, but caller expects %s"); | 1148 : "cast required: returning a %s, but caller expects %s"); |
1094 } else { | 1149 } else { |
1095 err = ((argnum < 0) | 1150 err = ((argnum >= 0) |
1096 ? "reference mismatch: passing a %s for method argument #%d, which expects %s" | 1151 ? "reference mismatch: passing a %s for method argument #%d, which expects %s" |
1097 : "reference mismatch: returning a %s, but caller expects %s"); | 1152 : "reference mismatch: returning a %s, but caller expects %s"); |
1098 } | 1153 } |
1099 } else { | 1154 } else { |
1100 // passed the obstacle course | 1155 // passed the obstacle course |
1427 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); | 1482 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); |
1428 if (direct_to_method) { | 1483 if (direct_to_method) { |
1429 assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots"); | 1484 assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots"); |
1430 assert(slots_pushed <= MethodHandlePushLimit, ""); | 1485 assert(slots_pushed <= MethodHandlePushLimit, ""); |
1431 } else { | 1486 } else { |
1432 int prev_pushes = decode_MethodHandle_stack_pushes(target()); | 1487 int target_pushes = decode_MethodHandle_stack_pushes(target()); |
1433 assert(this_pushes == slots_pushed + prev_pushes, "BMH stack motion must be correct"); | 1488 assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct"); |
1434 // do not blow the stack; use a Java-based adapter if this limit is exceeded | 1489 // do not blow the stack; use a Java-based adapter if this limit is exceeded |
1435 if (slots_pushed + prev_pushes > MethodHandlePushLimit) | 1490 if (slots_pushed + target_pushes > MethodHandlePushLimit) |
1436 err = "too many bound parameters"; | 1491 err = "too many bound parameters"; |
1437 } | 1492 } |
1438 } | 1493 } |
1439 | 1494 |
1440 if (err == NULL) { | 1495 if (err == NULL) { |
1586 } | 1641 } |
1587 | 1642 |
1588 if (err == NULL) { | 1643 if (err == NULL) { |
1589 // Check that the src/dest types are supplied if needed. | 1644 // Check that the src/dest types are supplied if needed. |
1590 switch (ek) { | 1645 switch (ek) { |
1646 case _adapter_check_cast: | |
1647 if (src != T_OBJECT || dest != T_OBJECT) { | |
1648 err = "adapter requires object src/dest conversion subfields"; | |
1649 } | |
1650 break; | |
1591 case _adapter_prim_to_prim: | 1651 case _adapter_prim_to_prim: |
1592 if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) { | 1652 if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) { |
1593 err = "adapter requires primitive src/dest conversion subfields"; break; | 1653 err = "adapter requires primitive src/dest conversion subfields"; break; |
1594 } | 1654 } |
1595 if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) || | 1655 if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) || |
1614 { | 1674 { |
1615 if (!src || src != dest) { | 1675 if (!src || src != dest) { |
1616 err = "adapter requires src/dest conversion subfields for swap"; break; | 1676 err = "adapter requires src/dest conversion subfields for swap"; break; |
1617 } | 1677 } |
1618 int swap_size = type2size[src]; | 1678 int swap_size = type2size[src]; |
1619 oop src_mtype = sun_dyn_AdapterMethodHandle::type(target()); | 1679 oop src_mtype = sun_dyn_AdapterMethodHandle::type(mh()); |
1620 oop dest_mtype = sun_dyn_AdapterMethodHandle::type(mh()); | 1680 oop dest_mtype = sun_dyn_AdapterMethodHandle::type(target()); |
1621 int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(src_mtype); | 1681 int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(target()); |
1622 int src_slot = argslot; | 1682 int src_slot = argslot; |
1623 int dest_slot = vminfo; | 1683 int dest_slot = vminfo; |
1624 bool rotate_up = (src_slot > dest_slot); // upward rotation | 1684 bool rotate_up = (src_slot > dest_slot); // upward rotation |
1625 int src_arg = argnum; | 1685 int src_arg = argnum; |
1626 int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot); | 1686 int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot); |
1727 | 1787 |
1728 if (err == NULL) { | 1788 if (err == NULL) { |
1729 // Make sure this adapter does not push too deeply. | 1789 // Make sure this adapter does not push too deeply. |
1730 int slots_pushed = stack_move / stack_move_unit(); | 1790 int slots_pushed = stack_move / stack_move_unit(); |
1731 int this_vmslots = java_dyn_MethodHandle::vmslots(mh()); | 1791 int this_vmslots = java_dyn_MethodHandle::vmslots(mh()); |
1732 int prev_vmslots = java_dyn_MethodHandle::vmslots(target()); | 1792 int target_vmslots = java_dyn_MethodHandle::vmslots(target()); |
1733 if (slots_pushed != (this_vmslots - prev_vmslots)) { | 1793 if (slots_pushed != (target_vmslots - this_vmslots)) { |
1734 err = "stack_move inconsistent with previous and current MethodType vmslots"; | 1794 err = "stack_move inconsistent with previous and current MethodType vmslots"; |
1735 } else if (slots_pushed > 0) { | 1795 } else if (slots_pushed > 0) { |
1736 // verify stack_move against MethodHandlePushLimit | 1796 // verify stack_move against MethodHandlePushLimit |
1737 int prev_pushes = decode_MethodHandle_stack_pushes(target()); | 1797 int target_pushes = decode_MethodHandle_stack_pushes(target()); |
1738 // do not blow the stack; use a Java-based adapter if this limit is exceeded | 1798 // do not blow the stack; use a Java-based adapter if this limit is exceeded |
1739 if (slots_pushed + prev_pushes > MethodHandlePushLimit) { | 1799 if (slots_pushed + target_pushes > MethodHandlePushLimit) { |
1740 err = "adapter pushes too many parameters"; | 1800 err = "adapter pushes too many parameters"; |
1741 } | 1801 } |
1742 } | 1802 } |
1743 | 1803 |
1744 // While we're at it, check that the stack motion decoder works: | 1804 // While we're at it, check that the stack motion decoder works: |
1745 DEBUG_ONLY(int prev_pushes = decode_MethodHandle_stack_pushes(target())); | 1805 DEBUG_ONLY(int target_pushes = decode_MethodHandle_stack_pushes(target())); |
1746 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); | 1806 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); |
1747 assert(this_pushes == slots_pushed + prev_pushes, "AMH stack motion must be correct"); | 1807 assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct"); |
1748 } | 1808 } |
1749 | 1809 |
1750 if (err == NULL && vminfo != 0) { | 1810 if (err == NULL && vminfo != 0) { |
1751 switch (ek) { | 1811 switch (ek) { |
1752 case _adapter_swap_args: | 1812 case _adapter_swap_args: |
1759 | 1819 |
1760 // Do additional ad hoc checks. | 1820 // Do additional ad hoc checks. |
1761 if (err == NULL) { | 1821 if (err == NULL) { |
1762 switch (ek) { | 1822 switch (ek) { |
1763 case _adapter_retype_only: | 1823 case _adapter_retype_only: |
1764 err = check_method_type_passthrough(src_mtype(), dst_mtype()); | 1824 err = check_method_type_passthrough(src_mtype(), dst_mtype(), false); |
1825 break; | |
1826 | |
1827 case _adapter_retype_raw: | |
1828 err = check_method_type_passthrough(src_mtype(), dst_mtype(), true); | |
1765 break; | 1829 break; |
1766 | 1830 |
1767 case _adapter_check_cast: | 1831 case _adapter_check_cast: |
1768 { | 1832 { |
1769 // The actual value being checked must be a reference: | 1833 // The actual value being checked must be a reference: |
1819 const char* err = NULL; | 1883 const char* err = NULL; |
1820 | 1884 |
1821 // Now it's time to finish the case analysis and pick a MethodHandleEntry. | 1885 // Now it's time to finish the case analysis and pick a MethodHandleEntry. |
1822 switch (ek_orig) { | 1886 switch (ek_orig) { |
1823 case _adapter_retype_only: | 1887 case _adapter_retype_only: |
1888 case _adapter_retype_raw: | |
1824 case _adapter_check_cast: | 1889 case _adapter_check_cast: |
1825 case _adapter_dup_args: | 1890 case _adapter_dup_args: |
1826 case _adapter_drop_args: | 1891 case _adapter_drop_args: |
1827 // these work fine via general case code | 1892 // these work fine via general case code |
1828 break; | 1893 break; |
1886 | 1951 |
1887 case _adapter_swap_args: | 1952 case _adapter_swap_args: |
1888 case _adapter_rot_args: | 1953 case _adapter_rot_args: |
1889 { | 1954 { |
1890 int swap_slots = type2size[src]; | 1955 int swap_slots = type2size[src]; |
1891 oop mtype = sun_dyn_AdapterMethodHandle::type(mh()); | 1956 int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mh()); |
1892 int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(mtype); | |
1893 int src_slot = argslot; | 1957 int src_slot = argslot; |
1894 int dest_slot = vminfo; | 1958 int dest_slot = vminfo; |
1895 int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1; | 1959 int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1; |
1896 switch (swap_slots) { | 1960 switch (swap_slots) { |
1897 case 1: | 1961 case 1: |
2131 switch (which) { | 2195 switch (which) { |
2132 case MethodHandles::GC_JVM_PUSH_LIMIT: | 2196 case MethodHandles::GC_JVM_PUSH_LIMIT: |
2133 guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF, | 2197 guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF, |
2134 "MethodHandlePushLimit parameter must be in valid range"); | 2198 "MethodHandlePushLimit parameter must be in valid range"); |
2135 return MethodHandlePushLimit; | 2199 return MethodHandlePushLimit; |
2136 case MethodHandles::GC_JVM_STACK_MOVE_LIMIT: | 2200 case MethodHandles::GC_JVM_STACK_MOVE_UNIT: |
2137 // return number of words per slot, signed according to stack direction | 2201 // return number of words per slot, signed according to stack direction |
2138 return MethodHandles::stack_move_unit(); | 2202 return MethodHandles::stack_move_unit(); |
2139 } | 2203 } |
2140 return 0; | 2204 return 0; |
2141 } | 2205 } |
2142 JVM_END | 2206 JVM_END |
2143 | 2207 |
2144 #ifndef PRODUCT | 2208 #ifndef PRODUCT |
2145 #define EACH_NAMED_CON(template) \ | 2209 #define EACH_NAMED_CON(template) \ |
2146 template(MethodHandles,GC_JVM_PUSH_LIMIT) \ | 2210 template(MethodHandles,GC_JVM_PUSH_LIMIT) \ |
2147 template(MethodHandles,GC_JVM_STACK_MOVE_LIMIT) \ | 2211 template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) \ |
2148 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ | 2212 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ |
2149 template(MethodHandles,ETF_DIRECT_HANDLE) \ | 2213 template(MethodHandles,ETF_DIRECT_HANDLE) \ |
2150 template(MethodHandles,ETF_METHOD_NAME) \ | 2214 template(MethodHandles,ETF_METHOD_NAME) \ |
2151 template(MethodHandles,ETF_REFLECT_METHOD) \ | 2215 template(MethodHandles,ETF_REFLECT_METHOD) \ |
2152 template(sun_dyn_MemberName,MN_IS_METHOD) \ | 2216 template(sun_dyn_MemberName,MN_IS_METHOD) \ |
2155 template(sun_dyn_MemberName,MN_IS_TYPE) \ | 2219 template(sun_dyn_MemberName,MN_IS_TYPE) \ |
2156 template(sun_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \ | 2220 template(sun_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \ |
2157 template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \ | 2221 template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \ |
2158 template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \ | 2222 template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \ |
2159 template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \ | 2223 template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \ |
2224 template(sun_dyn_AdapterMethodHandle,OP_RETYPE_RAW) \ | |
2160 template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \ | 2225 template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \ |
2161 template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \ | 2226 template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \ |
2162 template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \ | 2227 template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \ |
2163 template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_REF) \ | 2228 template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_REF) \ |
2164 template(sun_dyn_AdapterMethodHandle,OP_SWAP_ARGS) \ | 2229 template(sun_dyn_AdapterMethodHandle,OP_SWAP_ARGS) \ |
2343 assert(MethodHandles::spot_check_entry_names(), "entry enum is OK"); | 2408 assert(MethodHandles::spot_check_entry_names(), "entry enum is OK"); |
2344 | 2409 |
2345 // note: this explicit warning-producing stuff will be replaced by auto-detection of the JSR 292 classes | 2410 // note: this explicit warning-producing stuff will be replaced by auto-detection of the JSR 292 classes |
2346 | 2411 |
2347 if (!EnableMethodHandles) { | 2412 if (!EnableMethodHandles) { |
2348 warning("JSR 292 method handles are disabled in this JVM. Use -XX:+EnableMethodHandles to enable."); | 2413 warning("JSR 292 method handles are disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable."); |
2349 return; // bind nothing | 2414 return; // bind nothing |
2350 } | 2415 } |
2416 | |
2417 bool enable_MH = true; | |
2351 | 2418 |
2352 { | 2419 { |
2353 ThreadToNativeFromVM ttnfv(thread); | 2420 ThreadToNativeFromVM ttnfv(thread); |
2354 | 2421 |
2355 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod)); | 2422 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod)); |
2356 if (env->ExceptionOccurred()) { | 2423 if (env->ExceptionOccurred()) { |
2357 MethodHandles::set_enabled(false); | 2424 MethodHandles::set_enabled(false); |
2358 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); | 2425 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); |
2426 enable_MH = false; | |
2359 env->ExceptionClear(); | 2427 env->ExceptionClear(); |
2360 } else { | 2428 } |
2361 MethodHandles::set_enabled(true); | 2429 } |
2362 } | 2430 |
2431 if (enable_MH) { | |
2432 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); | |
2433 if (MHI_klass.not_null()) { | |
2434 symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK); | |
2435 symbolHandle raiseException_sig = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); | |
2436 methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) | |
2437 ->find_method(raiseException_name(), raiseException_sig()); | |
2438 if (raiseException_method != NULL && raiseException_method->is_static()) { | |
2439 MethodHandles::set_raise_exception_method(raiseException_method); | |
2440 } else { | |
2441 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); | |
2442 enable_MH = false; | |
2443 } | |
2444 } | |
2445 } | |
2446 | |
2447 if (enable_MH) { | |
2448 MethodHandles::set_enabled(true); | |
2363 } | 2449 } |
2364 | 2450 |
2365 if (!EnableInvokeDynamic) { | 2451 if (!EnableInvokeDynamic) { |
2366 warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+EnableInvokeDynamic to enable."); | 2452 warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable."); |
2367 return; // bind nothing | 2453 return; // bind nothing |
2368 } | 2454 } |
2369 | 2455 |
2370 { | 2456 { |
2371 ThreadToNativeFromVM ttnfv(thread); | 2457 ThreadToNativeFromVM ttnfv(thread); |