Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/methodHandles.cpp @ 3363:167b70ff3abc
6939861: JVM should handle more conversion operations
Reviewed-by: twisti, jrose
author | never |
---|---|
date | Fri, 06 May 2011 16:33:13 -0700 |
parents | 2a23b1b5a0a8 |
children | fabcf26ee72f |
comparison
equal
deleted
inserted
replaced
3362:d4c1fbc3de95 | 3363:167b70ff3abc |
---|---|
64 "adapter_rot_args", | 64 "adapter_rot_args", |
65 "adapter_dup_args", | 65 "adapter_dup_args", |
66 "adapter_drop_args", | 66 "adapter_drop_args", |
67 "adapter_collect_args", | 67 "adapter_collect_args", |
68 "adapter_spread_args", | 68 "adapter_spread_args", |
69 "adapter_flyby", | 69 "adapter_fold_args", |
70 "adapter_ricochet", | 70 "adapter_unused_13", |
71 | 71 |
72 // optimized adapter types: | 72 // optimized adapter types: |
73 "adapter_swap_args/1", | 73 "adapter_swap_args/1", |
74 "adapter_swap_args/2", | 74 "adapter_swap_args/2", |
75 "adapter_rot_args/1,up", | 75 "adapter_rot_args/1,up", |
81 "adapter_prim_to_prim/d2f", | 81 "adapter_prim_to_prim/d2f", |
82 "adapter_prim_to_prim/i2l", | 82 "adapter_prim_to_prim/i2l", |
83 "adapter_prim_to_prim/f2d", | 83 "adapter_prim_to_prim/f2d", |
84 "adapter_ref_to_prim/unboxi", | 84 "adapter_ref_to_prim/unboxi", |
85 "adapter_ref_to_prim/unboxl", | 85 "adapter_ref_to_prim/unboxl", |
86 "adapter_spread_args/0", | 86 |
87 "adapter_spread_args/1", | 87 // return value handlers for collect/filter/fold adapters: |
88 "adapter_spread_args/more", | 88 "return/ref", |
89 "return/int", | |
90 "return/long", | |
91 "return/float", | |
92 "return/double", | |
93 "return/void", | |
94 "return/S0/ref", | |
95 "return/S1/ref", | |
96 "return/S2/ref", | |
97 "return/S3/ref", | |
98 "return/S4/ref", | |
99 "return/S5/ref", | |
100 "return/any", | |
101 | |
102 // spreading (array length cases 0, 1, ...) | |
103 "adapter_spread/0", | |
104 "adapter_spread/1/ref", | |
105 "adapter_spread/2/ref", | |
106 "adapter_spread/3/ref", | |
107 "adapter_spread/4/ref", | |
108 "adapter_spread/5/ref", | |
109 "adapter_spread/ref", | |
110 "adapter_spread/byte", | |
111 "adapter_spread/char", | |
112 "adapter_spread/short", | |
113 "adapter_spread/int", | |
114 "adapter_spread/long", | |
115 "adapter_spread/float", | |
116 "adapter_spread/double", | |
117 | |
118 // blocking filter/collect conversions: | |
119 "adapter_collect/ref", | |
120 "adapter_collect/int", | |
121 "adapter_collect/long", | |
122 "adapter_collect/float", | |
123 "adapter_collect/double", | |
124 "adapter_collect/void", | |
125 "adapter_collect/0/ref", | |
126 "adapter_collect/1/ref", | |
127 "adapter_collect/2/ref", | |
128 "adapter_collect/3/ref", | |
129 "adapter_collect/4/ref", | |
130 "adapter_collect/5/ref", | |
131 "adapter_filter/S0/ref", | |
132 "adapter_filter/S1/ref", | |
133 "adapter_filter/S2/ref", | |
134 "adapter_filter/S3/ref", | |
135 "adapter_filter/S4/ref", | |
136 "adapter_filter/S5/ref", | |
137 "adapter_collect/2/S0/ref", | |
138 "adapter_collect/2/S1/ref", | |
139 "adapter_collect/2/S2/ref", | |
140 "adapter_collect/2/S3/ref", | |
141 "adapter_collect/2/S4/ref", | |
142 "adapter_collect/2/S5/ref", | |
143 | |
144 // blocking fold conversions: | |
145 "adapter_fold/ref", | |
146 "adapter_fold/int", | |
147 "adapter_fold/long", | |
148 "adapter_fold/float", | |
149 "adapter_fold/double", | |
150 "adapter_fold/void", | |
151 "adapter_fold/1/ref", | |
152 "adapter_fold/2/ref", | |
153 "adapter_fold/3/ref", | |
154 "adapter_fold/4/ref", | |
155 "adapter_fold/5/ref", | |
89 | 156 |
90 NULL | 157 NULL |
91 }; | 158 }; |
92 | 159 |
93 // Adapters. | 160 // Adapters. |
94 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; | 161 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; |
95 int MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size; | 162 int MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size; |
96 | 163 |
97 jobject MethodHandles::_raise_exception_method; | 164 jobject MethodHandles::_raise_exception_method; |
165 | |
166 address MethodHandles::_adapter_return_handlers[CONV_TYPE_MASK+1]; | |
98 | 167 |
99 #ifdef ASSERT | 168 #ifdef ASSERT |
100 bool MethodHandles::spot_check_entry_names() { | 169 bool MethodHandles::spot_check_entry_names() { |
101 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); | 170 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); |
102 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); | 171 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); |
103 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); | 172 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); |
104 assert(!strcmp(entry_name(_adapter_ricochet), "adapter_ricochet"), ""); | 173 assert(!strcmp(entry_name(_adapter_fold_args), "adapter_fold_args"), ""); |
105 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), ""); | 174 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), ""); |
175 assert(!strcmp(entry_name(_adapter_opt_spread_char), "adapter_spread/char"), ""); | |
176 assert(!strcmp(entry_name(_adapter_opt_spread_double), "adapter_spread/double"), ""); | |
177 assert(!strcmp(entry_name(_adapter_opt_collect_int), "adapter_collect/int"), ""); | |
178 assert(!strcmp(entry_name(_adapter_opt_collect_0_ref), "adapter_collect/0/ref"), ""); | |
179 assert(!strcmp(entry_name(_adapter_opt_collect_2_S3_ref), "adapter_collect/2/S3/ref"), ""); | |
180 assert(!strcmp(entry_name(_adapter_opt_filter_S5_ref), "adapter_filter/S5/ref"), ""); | |
181 assert(!strcmp(entry_name(_adapter_opt_fold_3_ref), "adapter_fold/3/ref"), ""); | |
182 assert(!strcmp(entry_name(_adapter_opt_fold_void), "adapter_fold/void"), ""); | |
106 return true; | 183 return true; |
107 } | 184 } |
108 #endif | 185 #endif |
109 | 186 |
110 | 187 |
111 //------------------------------------------------------------------------------ | 188 //------------------------------------------------------------------------------ |
112 // MethodHandles::generate_adapters | 189 // MethodHandles::generate_adapters |
113 // | 190 // |
114 void MethodHandles::generate_adapters() { | 191 void MethodHandles::generate_adapters() { |
192 #ifdef TARGET_ARCH_NYI_6939861 | |
193 if (FLAG_IS_DEFAULT(UseRicochetFrames)) UseRicochetFrames = false; | |
194 #endif | |
115 if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL) return; | 195 if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL) return; |
116 | 196 |
117 assert(_adapter_code == NULL, "generate only once"); | 197 assert(_adapter_code == NULL, "generate only once"); |
118 | 198 |
119 ResourceMark rm; | 199 ResourceMark rm; |
124 CodeBuffer code(_adapter_code); | 204 CodeBuffer code(_adapter_code); |
125 MethodHandlesAdapterGenerator g(&code); | 205 MethodHandlesAdapterGenerator g(&code); |
126 g.generate(); | 206 g.generate(); |
127 } | 207 } |
128 | 208 |
129 | |
130 //------------------------------------------------------------------------------ | 209 //------------------------------------------------------------------------------ |
131 // MethodHandlesAdapterGenerator::generate | 210 // MethodHandlesAdapterGenerator::generate |
132 // | 211 // |
133 void MethodHandlesAdapterGenerator::generate() { | 212 void MethodHandlesAdapterGenerator::generate() { |
134 // Generate generic method handle adapters. | 213 // Generate generic method handle adapters. |
135 for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; | 214 for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; |
136 ek < MethodHandles::_EK_LIMIT; | 215 ek < MethodHandles::_EK_LIMIT; |
137 ek = MethodHandles::EntryKind(1 + (int)ek)) { | 216 ek = MethodHandles::EntryKind(1 + (int)ek)) { |
138 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); | 217 if (MethodHandles::ek_supported(ek)) { |
139 MethodHandles::generate_method_handle_stub(_masm, ek); | 218 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); |
140 } | 219 MethodHandles::generate_method_handle_stub(_masm, ek); |
220 } | |
221 } | |
222 } | |
223 | |
224 | |
225 #ifdef TARGET_ARCH_NYI_6939861 | |
226 // these defs belong in methodHandles_<arch>.cpp | |
227 frame MethodHandles::ricochet_frame_sender(const frame& fr, RegisterMap *map) { | |
228 ShouldNotCallThis(); | |
229 return fr; | |
230 } | |
231 void MethodHandles::ricochet_frame_oops_do(const frame& fr, OopClosure* f, const RegisterMap* reg_map) { | |
232 ShouldNotCallThis(); | |
233 } | |
234 #endif //TARGET_ARCH_NYI_6939861 | |
235 | |
236 | |
237 //------------------------------------------------------------------------------ | |
238 // MethodHandles::ek_supported | |
239 // | |
240 bool MethodHandles::ek_supported(MethodHandles::EntryKind ek) { | |
241 MethodHandles::EntryKind ek_orig = MethodHandles::ek_original_kind(ek); | |
242 switch (ek_orig) { | |
243 case _adapter_unused_13: | |
244 return false; // not defined yet | |
245 case _adapter_prim_to_ref: | |
246 return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF); | |
247 case _adapter_collect_args: | |
248 return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS); | |
249 case _adapter_fold_args: | |
250 return UseRicochetFrames && conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS); | |
251 case _adapter_opt_return_any: | |
252 return UseRicochetFrames; | |
253 #ifdef TARGET_ARCH_NYI_6939861 | |
254 // ports before 6939861 supported only three kinds of spread ops | |
255 case _adapter_spread_args: | |
256 // restrict spreads to three kinds: | |
257 switch (ek) { | |
258 case _adapter_opt_spread_0: | |
259 case _adapter_opt_spread_1: | |
260 case _adapter_opt_spread_more: | |
261 break; | |
262 default: | |
263 return false; | |
264 break; | |
265 } | |
266 break; | |
267 #endif //TARGET_ARCH_NYI_6939861 | |
268 } | |
269 return true; | |
141 } | 270 } |
142 | 271 |
143 | 272 |
144 void MethodHandles::set_enabled(bool z) { | 273 void MethodHandles::set_enabled(bool z) { |
145 if (_enabled != z) { | 274 if (_enabled != z) { |
1562 CHECK); | 1691 CHECK); |
1563 if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } | 1692 if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } |
1564 if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); } | 1693 if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); } |
1565 | 1694 |
1566 java_lang_invoke_MethodHandle::init_vmslots(mh()); | 1695 java_lang_invoke_MethodHandle::init_vmslots(mh()); |
1696 int vmargslot = m->size_of_parameters() - 1; | |
1697 assert(java_lang_invoke_BoundMethodHandle::vmargslot(mh()) == vmargslot, ""); | |
1567 | 1698 |
1568 if (VerifyMethodHandles) { | 1699 if (VerifyMethodHandles) { |
1569 verify_BoundMethodHandle_with_receiver(mh, m, CHECK); | 1700 verify_BoundMethodHandle_with_receiver(mh, m, CHECK); |
1570 } | 1701 } |
1571 | 1702 |
1640 | 1771 |
1641 if (err == NULL) { | 1772 if (err == NULL) { |
1642 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); | 1773 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); |
1643 if (direct_to_method) { | 1774 if (direct_to_method) { |
1644 assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots"); | 1775 assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots"); |
1645 assert(slots_pushed <= MethodHandlePushLimit, ""); | |
1646 } else { | 1776 } else { |
1647 int target_pushes = decode_MethodHandle_stack_pushes(target()); | 1777 int target_pushes = decode_MethodHandle_stack_pushes(target()); |
1648 assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct"); | 1778 assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct"); |
1649 // do not blow the stack; use a Java-based adapter if this limit is exceeded | |
1650 // FIXME | |
1651 // if (slots_pushed + target_pushes > MethodHandlePushLimit) | |
1652 // err = "too many bound parameters"; | |
1653 } | 1779 } |
1654 } | 1780 } |
1655 | 1781 |
1656 if (err == NULL) { | 1782 if (err == NULL) { |
1657 // Verify the rest of the method type. | 1783 // Verify the rest of the method type. |
1670 if (mh.is_null() || target.is_null() || !java_lang_invoke_MethodHandle::is_instance(target())) { | 1796 if (mh.is_null() || target.is_null() || !java_lang_invoke_MethodHandle::is_instance(target())) { |
1671 THROW(vmSymbols::java_lang_InternalError()); | 1797 THROW(vmSymbols::java_lang_InternalError()); |
1672 } | 1798 } |
1673 | 1799 |
1674 java_lang_invoke_MethodHandle::init_vmslots(mh()); | 1800 java_lang_invoke_MethodHandle::init_vmslots(mh()); |
1801 int argslot = java_lang_invoke_BoundMethodHandle::vmargslot(mh()); | |
1675 | 1802 |
1676 if (VerifyMethodHandles) { | 1803 if (VerifyMethodHandles) { |
1677 int insert_after = argnum - 1; | 1804 int insert_after = argnum - 1; |
1678 verify_vmargslot(mh, insert_after, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK); | 1805 verify_vmargslot(mh, insert_after, argslot, CHECK); |
1679 verify_vmslots(mh, CHECK); | 1806 verify_vmslots(mh, CHECK); |
1680 } | 1807 } |
1681 | 1808 |
1682 // Get bound type and required slots. | 1809 // Get bound type and required slots. |
1683 BasicType ptype; | 1810 BasicType ptype; |
1767 | 1894 |
1768 Handle argument(THREAD, java_lang_invoke_AdapterMethodHandle::argument(mh())); | 1895 Handle argument(THREAD, java_lang_invoke_AdapterMethodHandle::argument(mh())); |
1769 Handle target(THREAD, java_lang_invoke_AdapterMethodHandle::vmtarget(mh())); | 1896 Handle target(THREAD, java_lang_invoke_AdapterMethodHandle::vmtarget(mh())); |
1770 Handle src_mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); | 1897 Handle src_mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); |
1771 Handle dst_mtype(THREAD, java_lang_invoke_MethodHandle::type(target())); | 1898 Handle dst_mtype(THREAD, java_lang_invoke_MethodHandle::type(target())); |
1899 Handle arg_mtype; | |
1772 | 1900 |
1773 const char* err = NULL; | 1901 const char* err = NULL; |
1774 | 1902 |
1775 if (err == NULL) { | 1903 if (err == NULL) { |
1776 // Check that the correct argument is supplied, but only if it is required. | 1904 // Check that the correct argument is supplied, but only if it is required. |
1777 switch (ek) { | 1905 switch (ek) { |
1778 case _adapter_check_cast: // target type of cast | 1906 case _adapter_check_cast: // target type of cast |
1779 case _adapter_ref_to_prim: // wrapper type from which to unbox | 1907 case _adapter_ref_to_prim: // wrapper type from which to unbox |
1780 case _adapter_prim_to_ref: // wrapper type to box into | |
1781 case _adapter_collect_args: // array type to collect into | |
1782 case _adapter_spread_args: // array type to spread from | 1908 case _adapter_spread_args: // array type to spread from |
1783 if (!java_lang_Class::is_instance(argument()) | 1909 if (!java_lang_Class::is_instance(argument()) |
1784 || java_lang_Class::is_primitive(argument())) | 1910 || java_lang_Class::is_primitive(argument())) |
1785 { err = "adapter requires argument of type java.lang.Class"; break; } | 1911 { err = "adapter requires argument of type java.lang.Class"; break; } |
1786 if (ek == _adapter_collect_args || | 1912 if (ek == _adapter_spread_args) { |
1787 ek == _adapter_spread_args) { | |
1788 // Make sure it is a suitable collection type. (Array, for now.) | 1913 // Make sure it is a suitable collection type. (Array, for now.) |
1789 Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument())); | 1914 Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument())); |
1790 if (!ak->oop_is_objArray()) { | 1915 if (!ak->oop_is_array()) |
1791 { err = "adapter requires argument of type java.lang.Class<Object[]>"; break; } | 1916 { err = "spread adapter requires argument representing an array class"; break; } |
1792 } | 1917 BasicType et = arrayKlass::cast(ak->as_klassOop())->element_type(); |
1918 if (et != dest && stack_move <= 0) | |
1919 { err = "spread adapter requires array class argument of correct type"; break; } | |
1793 } | 1920 } |
1794 break; | 1921 break; |
1795 case _adapter_flyby: | 1922 case _adapter_prim_to_ref: // boxer MH to use |
1796 case _adapter_ricochet: | 1923 case _adapter_collect_args: // method handle which collects the args |
1924 case _adapter_fold_args: // method handle which collects the args | |
1925 if (!UseRicochetFrames) { | |
1926 { err = "box/collect/fold operators are not supported"; break; } | |
1927 } | |
1797 if (!java_lang_invoke_MethodHandle::is_instance(argument())) | 1928 if (!java_lang_invoke_MethodHandle::is_instance(argument())) |
1798 { err = "MethodHandle adapter argument required"; break; } | 1929 { err = "MethodHandle adapter argument required"; break; } |
1930 arg_mtype = Handle(THREAD, java_lang_invoke_MethodHandle::type(argument())); | |
1799 break; | 1931 break; |
1800 default: | 1932 default: |
1801 if (argument.not_null()) | 1933 if (argument.not_null()) |
1802 { err = "adapter has spurious argument"; break; } | 1934 { err = "adapter has spurious argument"; break; } |
1803 break; | 1935 break; |
1804 } | 1936 } |
1805 } | 1937 } |
1806 | 1938 |
1807 if (err == NULL) { | 1939 if (err == NULL) { |
1808 // Check that the src/dest types are supplied if needed. | 1940 // Check that the src/dest types are supplied if needed. |
1941 // Also check relevant parameter or return types. | |
1809 switch (ek) { | 1942 switch (ek) { |
1810 case _adapter_check_cast: | 1943 case _adapter_check_cast: |
1811 if (src != T_OBJECT || dest != T_OBJECT) { | 1944 if (src != T_OBJECT || dest != T_OBJECT) { |
1812 err = "adapter requires object src/dest conversion subfields"; | 1945 err = "adapter requires object src/dest conversion subfields"; |
1813 } | 1946 } |
1826 || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) { | 1959 || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) { |
1827 err = "adapter requires primitive dest conversion subfield"; break; | 1960 err = "adapter requires primitive dest conversion subfield"; break; |
1828 } | 1961 } |
1829 break; | 1962 break; |
1830 case _adapter_prim_to_ref: | 1963 case _adapter_prim_to_ref: |
1831 if (!is_java_primitive(src) || dest != T_OBJECT | 1964 if (!is_java_primitive(src) || dest != T_OBJECT) { |
1832 || argument() != Klass::cast(SystemDictionary::box_klass(src))->java_mirror()) { | |
1833 err = "adapter requires primitive src conversion subfield"; break; | 1965 err = "adapter requires primitive src conversion subfield"; break; |
1834 } | 1966 } |
1835 break; | 1967 break; |
1836 case _adapter_swap_args: | 1968 case _adapter_swap_args: |
1837 case _adapter_rot_args: | 1969 case _adapter_rot_args: |
1838 { | 1970 { |
1839 if (!src || src != dest) { | 1971 if (!src || src != dest) { |
1840 err = "adapter requires src/dest conversion subfields for swap"; break; | 1972 err = "adapter requires src/dest conversion subfields for swap"; break; |
1841 } | 1973 } |
1842 int swap_size = type2size[src]; | 1974 int swap_size = type2size[src]; |
1843 oop src_mtype = java_lang_invoke_AdapterMethodHandle::type(mh()); | 1975 int slot_limit = java_lang_invoke_MethodHandle::vmslots(target()); |
1844 oop dest_mtype = java_lang_invoke_AdapterMethodHandle::type(target()); | |
1845 int slot_limit = java_lang_invoke_AdapterMethodHandle::vmslots(target()); | |
1846 int src_slot = argslot; | 1976 int src_slot = argslot; |
1847 int dest_slot = vminfo; | 1977 int dest_slot = vminfo; |
1848 bool rotate_up = (src_slot > dest_slot); // upward rotation | 1978 bool rotate_up = (src_slot > dest_slot); // upward rotation |
1849 int src_arg = argnum; | 1979 int src_arg = argnum; |
1850 int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot); | 1980 int dest_arg = argument_slot_to_argnum(dst_mtype(), dest_slot); |
1851 verify_vmargslot(mh, dest_arg, dest_slot, CHECK); | 1981 verify_vmargslot(mh, dest_arg, dest_slot, CHECK); |
1852 if (!(dest_slot >= src_slot + swap_size) && | 1982 if (!(dest_slot >= src_slot + swap_size) && |
1853 !(src_slot >= dest_slot + swap_size)) { | 1983 !(src_slot >= dest_slot + swap_size)) { |
1854 err = "source, destination slots must be distinct"; | 1984 err = "source, destination slots must be distinct"; |
1855 } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) { | 1985 } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) { |
1856 err = "source of swap must be deeper in stack"; | 1986 err = "source of swap must be deeper in stack"; |
1857 } else if (ek == _adapter_swap_args) { | 1987 } else if (ek == _adapter_swap_args) { |
1858 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, dest_arg), | 1988 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg), |
1859 java_lang_invoke_MethodType::ptype(dest_mtype, src_arg), | 1989 java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg), |
1860 dest_arg); | 1990 dest_arg); |
1861 } else if (ek == _adapter_rot_args) { | 1991 } else if (ek == _adapter_rot_args) { |
1862 if (rotate_up) { | 1992 if (rotate_up) { |
1863 assert((src_slot > dest_slot) && (src_arg < dest_arg), ""); | 1993 assert((src_slot > dest_slot) && (src_arg < dest_arg), ""); |
1864 // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot] | 1994 // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot] |
1865 // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1] | 1995 // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1] |
1866 for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) { | 1996 for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) { |
1867 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, i), | 1997 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i), |
1868 java_lang_invoke_MethodType::ptype(dest_mtype, i-1), | 1998 java_lang_invoke_MethodType::ptype(dst_mtype(), i-1), |
1869 i); | 1999 i); |
1870 } | 2000 } |
1871 } else { // rotate down | 2001 } else { // rotate down |
1872 assert((src_slot < dest_slot) && (src_arg > dest_arg), ""); | 2002 assert((src_slot < dest_slot) && (src_arg > dest_arg), ""); |
1873 // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss] | 2003 // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss] |
1874 // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg] | 2004 // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg] |
1875 for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) { | 2005 for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) { |
1876 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, i), | 2006 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i), |
1877 java_lang_invoke_MethodType::ptype(dest_mtype, i+1), | 2007 java_lang_invoke_MethodType::ptype(dst_mtype(), i+1), |
1878 i); | 2008 i); |
1879 } | 2009 } |
1880 } | 2010 } |
1881 } | 2011 } |
1882 if (err == NULL) | 2012 if (err == NULL) |
1883 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, src_arg), | 2013 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg), |
1884 java_lang_invoke_MethodType::ptype(dest_mtype, dest_arg), | 2014 java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg), |
1885 src_arg); | 2015 src_arg); |
1886 } | 2016 } |
1887 break; | 2017 break; |
2018 case _adapter_spread_args: | |
1888 case _adapter_collect_args: | 2019 case _adapter_collect_args: |
1889 case _adapter_spread_args: | 2020 case _adapter_fold_args: |
1890 { | 2021 { |
1891 BasicType coll_type = (ek == _adapter_collect_args) ? dest : src; | 2022 bool is_spread = (ek == _adapter_spread_args); |
1892 BasicType elem_type = (ek == _adapter_collect_args) ? src : dest; | 2023 bool is_fold = (ek == _adapter_fold_args); |
1893 if (coll_type != T_OBJECT || elem_type != T_OBJECT) { | 2024 BasicType coll_type = is_spread ? src : dest; |
1894 err = "adapter requires src/dest subfields"; break; | 2025 BasicType elem_type = is_spread ? dest : src; |
1895 // later: | 2026 // coll_type is type of args in collected form (or T_VOID if none) |
1896 // - consider making coll be a primitive array | 2027 // elem_type is common type of args in spread form (or T_VOID if missing or heterogeneous) |
1897 // - consider making coll be a heterogeneous collection | 2028 if (coll_type == 0 || elem_type == 0) { |
2029 err = "adapter requires src/dest subfields for spread or collect"; break; | |
2030 } | |
2031 if (is_spread && coll_type != T_OBJECT) { | |
2032 err = "spread adapter requires object type for argument bundle"; break; | |
2033 } | |
2034 Handle spread_mtype = (is_spread ? dst_mtype : src_mtype); | |
2035 int spread_slot = argslot; | |
2036 int spread_arg = argnum; | |
2037 int slots_pushed = stack_move / stack_move_unit(); | |
2038 int coll_slot_count = type2size[coll_type]; | |
2039 int spread_slot_count = (is_spread ? slots_pushed : -slots_pushed) + coll_slot_count; | |
2040 if (is_fold) spread_slot_count = argument_slot_count(arg_mtype()); | |
2041 if (!is_spread) { | |
2042 int init_slots = argument_slot_count(src_mtype()); | |
2043 int coll_slots = argument_slot_count(arg_mtype()); | |
2044 if (spread_slot_count > init_slots || | |
2045 spread_slot_count != coll_slots) { | |
2046 err = "collect adapter has inconsistent arg counts"; break; | |
2047 } | |
2048 int next_slots = argument_slot_count(dst_mtype()); | |
2049 int unchanged_slots_in = (init_slots - spread_slot_count); | |
2050 int unchanged_slots_out = (next_slots - coll_slot_count - (is_fold ? spread_slot_count : 0)); | |
2051 if (unchanged_slots_in != unchanged_slots_out) { | |
2052 err = "collect adapter continuation has inconsistent arg counts"; break; | |
2053 } | |
1898 } | 2054 } |
1899 } | 2055 } |
1900 break; | 2056 break; |
1901 default: | 2057 default: |
1902 if (src != 0 || dest != 0) { | 2058 if (src != 0 || dest != 0) { |
1927 if (slots_pushed >= 0) { | 2083 if (slots_pushed >= 0) { |
1928 err = "adapter requires conversion subfield slots_pushed < 0"; | 2084 err = "adapter requires conversion subfield slots_pushed < 0"; |
1929 } | 2085 } |
1930 break; | 2086 break; |
1931 case _adapter_collect_args: | 2087 case _adapter_collect_args: |
1932 if (slots_pushed > 1) { | 2088 case _adapter_fold_args: |
1933 err = "adapter requires conversion subfield slots_pushed <= 1"; | 2089 if (slots_pushed > 2) { |
2090 err = "adapter requires conversion subfield slots_pushed <= 2"; | |
1934 } | 2091 } |
1935 break; | 2092 break; |
1936 case _adapter_spread_args: | 2093 case _adapter_spread_args: |
1937 if (slots_pushed < -1) { | 2094 if (slots_pushed < -1) { |
1938 err = "adapter requires conversion subfield slots_pushed >= -1"; | 2095 err = "adapter requires conversion subfield slots_pushed >= -1"; |
1948 err = "stack_move conversion subfield must be multiple of stack_move_unit"; | 2105 err = "stack_move conversion subfield must be multiple of stack_move_unit"; |
1949 } | 2106 } |
1950 } | 2107 } |
1951 | 2108 |
1952 if (err == NULL) { | 2109 if (err == NULL) { |
1953 // Make sure this adapter does not push too deeply. | 2110 // Make sure this adapter's stack pushing is accurately recorded. |
1954 int slots_pushed = stack_move / stack_move_unit(); | 2111 int slots_pushed = stack_move / stack_move_unit(); |
1955 int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh()); | 2112 int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh()); |
1956 int target_vmslots = java_lang_invoke_MethodHandle::vmslots(target()); | 2113 int target_vmslots = java_lang_invoke_MethodHandle::vmslots(target()); |
2114 int target_pushes = decode_MethodHandle_stack_pushes(target()); | |
1957 if (slots_pushed != (target_vmslots - this_vmslots)) { | 2115 if (slots_pushed != (target_vmslots - this_vmslots)) { |
1958 err = "stack_move inconsistent with previous and current MethodType vmslots"; | 2116 err = "stack_move inconsistent with previous and current MethodType vmslots"; |
1959 } else if (slots_pushed > 0) { | 2117 } else { |
1960 // verify stack_move against MethodHandlePushLimit | 2118 int this_pushes = decode_MethodHandle_stack_pushes(mh()); |
1961 int target_pushes = decode_MethodHandle_stack_pushes(target()); | 2119 if (slots_pushed + target_pushes != this_pushes) { |
1962 // do not blow the stack; use a Java-based adapter if this limit is exceeded | 2120 if (this_pushes == 0) |
1963 if (slots_pushed + target_pushes > MethodHandlePushLimit) { | 2121 err = "adapter push count not initialized"; |
1964 err = "adapter pushes too many parameters"; | 2122 else |
2123 err = "adapter push count is wrong"; | |
1965 } | 2124 } |
1966 } | 2125 } |
1967 | 2126 |
1968 // While we're at it, check that the stack motion decoder works: | 2127 // While we're at it, check that the stack motion decoder works: |
1969 DEBUG_ONLY(int target_pushes = decode_MethodHandle_stack_pushes(target())); | |
1970 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); | 2128 DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh())); |
1971 assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct"); | 2129 assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct"); |
1972 } | 2130 } |
1973 | 2131 |
1974 if (err == NULL && vminfo != 0) { | 2132 if (err == NULL && vminfo != 0) { |
1975 switch (ek) { | 2133 switch (ek) { |
1976 case _adapter_swap_args: | 2134 case _adapter_swap_args: |
1977 case _adapter_rot_args: | 2135 case _adapter_rot_args: |
1978 break; // OK | 2136 case _adapter_prim_to_ref: |
2137 case _adapter_collect_args: | |
2138 case _adapter_fold_args: | |
2139 break; // OK | |
1979 default: | 2140 default: |
1980 err = "vminfo subfield is reserved to the JVM"; | 2141 err = "vminfo subfield is reserved to the JVM"; |
1981 } | 2142 } |
1982 } | 2143 } |
1983 | 2144 |
2024 jint conv_op = adapter_conversion_op(conversion); | 2185 jint conv_op = adapter_conversion_op(conversion); |
2025 | 2186 |
2026 // adjust the adapter code to the internal EntryKind enumeration: | 2187 // adjust the adapter code to the internal EntryKind enumeration: |
2027 EntryKind ek_orig = adapter_entry_kind(conv_op); | 2188 EntryKind ek_orig = adapter_entry_kind(conv_op); |
2028 EntryKind ek_opt = ek_orig; // may be optimized | 2189 EntryKind ek_opt = ek_orig; // may be optimized |
2190 EntryKind ek_try; // temp | |
2029 | 2191 |
2030 // Finalize the vmtarget field (Java initialized it to null). | 2192 // Finalize the vmtarget field (Java initialized it to null). |
2031 if (!java_lang_invoke_MethodHandle::is_instance(target())) { | 2193 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
2032 throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD); | 2194 throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD); |
2033 return; | 2195 return; |
2034 } | 2196 } |
2035 java_lang_invoke_AdapterMethodHandle::set_vmtarget(mh(), target()); | 2197 java_lang_invoke_AdapterMethodHandle::set_vmtarget(mh(), target()); |
2036 | 2198 |
2037 if (VerifyMethodHandles) { | |
2038 verify_AdapterMethodHandle(mh, argnum, CHECK); | |
2039 } | |
2040 | |
2041 int stack_move = adapter_conversion_stack_move(conversion); | 2199 int stack_move = adapter_conversion_stack_move(conversion); |
2042 BasicType src = adapter_conversion_src_type(conversion); | 2200 BasicType src = adapter_conversion_src_type(conversion); |
2043 BasicType dest = adapter_conversion_dest_type(conversion); | 2201 BasicType dest = adapter_conversion_dest_type(conversion); |
2044 int vminfo = adapter_conversion_vminfo(conversion); // should be zero | 2202 int vminfo = adapter_conversion_vminfo(conversion); // should be zero |
2045 | 2203 |
2204 int slots_pushed = stack_move / stack_move_unit(); | |
2205 | |
2206 if (VerifyMethodHandles) { | |
2207 verify_AdapterMethodHandle(mh, argnum, CHECK); | |
2208 } | |
2209 | |
2046 const char* err = NULL; | 2210 const char* err = NULL; |
2211 | |
2212 if (!conv_op_supported(conv_op)) { | |
2213 err = "adapter not yet implemented in the JVM"; | |
2214 } | |
2047 | 2215 |
2048 // Now it's time to finish the case analysis and pick a MethodHandleEntry. | 2216 // Now it's time to finish the case analysis and pick a MethodHandleEntry. |
2049 switch (ek_orig) { | 2217 switch (ek_orig) { |
2050 case _adapter_retype_only: | 2218 case _adapter_retype_only: |
2051 case _adapter_retype_raw: | 2219 case _adapter_retype_raw: |
2075 } else { | 2243 } else { |
2076 assert(false, ""); | 2244 assert(false, ""); |
2077 } | 2245 } |
2078 break; | 2246 break; |
2079 case 1 *4+ 2: | 2247 case 1 *4+ 2: |
2080 if (src == T_INT && dest == T_LONG) { | 2248 if ((src == T_INT || is_subword_type(src)) && dest == T_LONG) { |
2081 ek_opt = _adapter_opt_i2l; | 2249 ek_opt = _adapter_opt_i2l; |
2082 } else if (src == T_FLOAT && dest == T_DOUBLE) { | 2250 } else if (src == T_FLOAT && dest == T_DOUBLE) { |
2083 ek_opt = _adapter_opt_f2d; | 2251 ek_opt = _adapter_opt_f2d; |
2084 } else { | 2252 } else { |
2085 assert(false, ""); | 2253 assert(false, ""); |
2108 } | 2276 } |
2109 } | 2277 } |
2110 break; | 2278 break; |
2111 | 2279 |
2112 case _adapter_prim_to_ref: | 2280 case _adapter_prim_to_ref: |
2113 goto throw_not_impl; // allocates, hence could block | 2281 { |
2282 assert(UseRicochetFrames, "else don't come here"); | |
2283 // vminfo will be the location to insert the return value | |
2284 vminfo = argslot; | |
2285 ek_opt = _adapter_opt_collect_ref; | |
2286 ensure_vmlayout_field(target, CHECK); | |
2287 if (!OptimizeMethodHandles) break; | |
2288 switch (type2size[src]) { | |
2289 case 1: | |
2290 ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot); | |
2291 if (ek_try < _adapter_opt_collect_LAST && | |
2292 ek_adapter_opt_collect_slot(ek_try) == argslot) { | |
2293 assert(ek_adapter_opt_collect_count(ek_try) == 1 && | |
2294 ek_adapter_opt_collect_type(ek_try) == T_OBJECT, ""); | |
2295 ek_opt = ek_try; | |
2296 break; | |
2297 } | |
2298 // else downgrade to variable slot: | |
2299 ek_opt = _adapter_opt_collect_1_ref; | |
2300 break; | |
2301 case 2: | |
2302 ek_try = EntryKind(_adapter_opt_collect_2_S0_ref + argslot); | |
2303 if (ek_try < _adapter_opt_collect_LAST && | |
2304 ek_adapter_opt_collect_slot(ek_try) == argslot) { | |
2305 assert(ek_adapter_opt_collect_count(ek_try) == 2 && | |
2306 ek_adapter_opt_collect_type(ek_try) == T_OBJECT, ""); | |
2307 ek_opt = ek_try; | |
2308 break; | |
2309 } | |
2310 // else downgrade to variable slot: | |
2311 ek_opt = _adapter_opt_collect_2_ref; | |
2312 break; | |
2313 default: | |
2314 assert(false, ""); | |
2315 break; | |
2316 } | |
2317 } | |
2318 break; | |
2114 | 2319 |
2115 case _adapter_swap_args: | 2320 case _adapter_swap_args: |
2116 case _adapter_rot_args: | 2321 case _adapter_rot_args: |
2117 { | 2322 { |
2118 int swap_slots = type2size[src]; | 2323 int swap_slots = type2size[src]; |
2134 break; | 2339 break; |
2135 } | 2340 } |
2136 } | 2341 } |
2137 break; | 2342 break; |
2138 | 2343 |
2139 case _adapter_collect_args: | |
2140 goto throw_not_impl; // allocates, hence could block | |
2141 | |
2142 case _adapter_spread_args: | 2344 case _adapter_spread_args: |
2143 { | 2345 { |
2346 #ifdef TARGET_ARCH_NYI_6939861 | |
2347 // ports before 6939861 supported only three kinds of spread ops | |
2348 if (!UseRicochetFrames) { | |
2349 int array_size = slots_pushed + 1; | |
2350 assert(array_size >= 0, ""); | |
2351 vminfo = array_size; | |
2352 switch (array_size) { | |
2353 case 0: ek_opt = _adapter_opt_spread_0; break; | |
2354 case 1: ek_opt = _adapter_opt_spread_1; break; | |
2355 default: ek_opt = _adapter_opt_spread_more; break; | |
2356 } | |
2357 break; | |
2358 } | |
2359 #endif //TARGET_ARCH_NYI_6939861 | |
2144 // vminfo will be the required length of the array | 2360 // vminfo will be the required length of the array |
2145 int slots_pushed = stack_move / stack_move_unit(); | 2361 int array_size = (slots_pushed + 1) / (type2size[dest] == 2 ? 2 : 1); |
2146 int array_size = slots_pushed + 1; | |
2147 assert(array_size >= 0, ""); | |
2148 vminfo = array_size; | 2362 vminfo = array_size; |
2149 switch (array_size) { | 2363 // general case |
2150 case 0: ek_opt = _adapter_opt_spread_0; break; | 2364 switch (dest) { |
2151 case 1: ek_opt = _adapter_opt_spread_1; break; | 2365 case T_BOOLEAN : // fall through to T_BYTE: |
2152 default: ek_opt = _adapter_opt_spread_more; break; | 2366 case T_BYTE : ek_opt = _adapter_opt_spread_byte; break; |
2153 } | 2367 case T_CHAR : ek_opt = _adapter_opt_spread_char; break; |
2154 if ((vminfo & CONV_VMINFO_MASK) != vminfo) | 2368 case T_SHORT : ek_opt = _adapter_opt_spread_short; break; |
2155 goto throw_not_impl; // overflow | 2369 case T_INT : ek_opt = _adapter_opt_spread_int; break; |
2370 case T_LONG : ek_opt = _adapter_opt_spread_long; break; | |
2371 case T_FLOAT : ek_opt = _adapter_opt_spread_float; break; | |
2372 case T_DOUBLE : ek_opt = _adapter_opt_spread_double; break; | |
2373 case T_OBJECT : ek_opt = _adapter_opt_spread_ref; break; | |
2374 case T_VOID : if (array_size != 0) goto throw_not_impl; | |
2375 ek_opt = _adapter_opt_spread_ref; break; | |
2376 default : goto throw_not_impl; | |
2377 } | |
2378 assert(array_size == 0 || // it doesn't matter what the spreader is | |
2379 (ek_adapter_opt_spread_count(ek_opt) == -1 && | |
2380 (ek_adapter_opt_spread_type(ek_opt) == dest || | |
2381 (ek_adapter_opt_spread_type(ek_opt) == T_BYTE && dest == T_BOOLEAN))), | |
2382 err_msg("dest=%d ek_opt=%d", dest, ek_opt)); | |
2383 | |
2384 if (array_size <= 0) { | |
2385 // since the general case does not handle length 0, this case is required: | |
2386 ek_opt = _adapter_opt_spread_0; | |
2387 break; | |
2388 } | |
2389 if (dest == T_OBJECT) { | |
2390 ek_try = EntryKind(_adapter_opt_spread_1_ref - 1 + array_size); | |
2391 if (ek_try < _adapter_opt_spread_LAST && | |
2392 ek_adapter_opt_spread_count(ek_try) == array_size) { | |
2393 assert(ek_adapter_opt_spread_type(ek_try) == dest, ""); | |
2394 ek_opt = ek_try; | |
2395 break; | |
2396 } | |
2397 } | |
2398 break; | |
2156 } | 2399 } |
2157 break; | 2400 break; |
2158 | 2401 |
2159 case _adapter_flyby: | 2402 case _adapter_collect_args: |
2160 case _adapter_ricochet: | 2403 { |
2161 goto throw_not_impl; // runs Java code, hence could block | 2404 assert(UseRicochetFrames, "else don't come here"); |
2405 int elem_slots = argument_slot_count( | |
2406 java_lang_invoke_MethodHandle::type( | |
2407 java_lang_invoke_AdapterMethodHandle::argument(mh()) ) ); | |
2408 // vminfo will be the location to insert the return value | |
2409 vminfo = argslot; | |
2410 ensure_vmlayout_field(target, CHECK); | |
2411 | |
2412 // general case: | |
2413 switch (dest) { | |
2414 default : if (!is_subword_type(dest)) goto throw_not_impl; | |
2415 // else fall through: | |
2416 case T_INT : ek_opt = _adapter_opt_collect_int; break; | |
2417 case T_LONG : ek_opt = _adapter_opt_collect_long; break; | |
2418 case T_FLOAT : ek_opt = _adapter_opt_collect_float; break; | |
2419 case T_DOUBLE : ek_opt = _adapter_opt_collect_double; break; | |
2420 case T_OBJECT : ek_opt = _adapter_opt_collect_ref; break; | |
2421 case T_VOID : ek_opt = _adapter_opt_collect_void; break; | |
2422 } | |
2423 assert(ek_adapter_opt_collect_slot(ek_opt) == -1 && | |
2424 ek_adapter_opt_collect_count(ek_opt) == -1 && | |
2425 (ek_adapter_opt_collect_type(ek_opt) == dest || | |
2426 ek_adapter_opt_collect_type(ek_opt) == T_INT && is_subword_type(dest)), | |
2427 ""); | |
2428 | |
2429 if (dest == T_OBJECT && elem_slots == 1 && OptimizeMethodHandles) { | |
2430 // filter operation on a ref | |
2431 ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot); | |
2432 if (ek_try < _adapter_opt_collect_LAST && | |
2433 ek_adapter_opt_collect_slot(ek_try) == argslot) { | |
2434 assert(ek_adapter_opt_collect_count(ek_try) == elem_slots && | |
2435 ek_adapter_opt_collect_type(ek_try) == dest, ""); | |
2436 ek_opt = ek_try; | |
2437 break; | |
2438 } | |
2439 ek_opt = _adapter_opt_collect_1_ref; | |
2440 break; | |
2441 } | |
2442 | |
2443 if (dest == T_OBJECT && elem_slots == 2 && OptimizeMethodHandles) { | |
2444 // filter of two arguments | |
2445 ek_try = EntryKind(_adapter_opt_collect_2_S0_ref + argslot); | |
2446 if (ek_try < _adapter_opt_collect_LAST && | |
2447 ek_adapter_opt_collect_slot(ek_try) == argslot) { | |
2448 assert(ek_adapter_opt_collect_count(ek_try) == elem_slots && | |
2449 ek_adapter_opt_collect_type(ek_try) == dest, ""); | |
2450 ek_opt = ek_try; | |
2451 break; | |
2452 } | |
2453 ek_opt = _adapter_opt_collect_2_ref; | |
2454 break; | |
2455 } | |
2456 | |
2457 if (dest == T_OBJECT && OptimizeMethodHandles) { | |
2458 // try to use a fixed length adapter | |
2459 ek_try = EntryKind(_adapter_opt_collect_0_ref + elem_slots); | |
2460 if (ek_try < _adapter_opt_collect_LAST && | |
2461 ek_adapter_opt_collect_count(ek_try) == elem_slots) { | |
2462 assert(ek_adapter_opt_collect_slot(ek_try) == -1 && | |
2463 ek_adapter_opt_collect_type(ek_try) == dest, ""); | |
2464 ek_opt = ek_try; | |
2465 break; | |
2466 } | |
2467 } | |
2468 | |
2469 break; | |
2470 } | |
2471 | |
2472 case _adapter_fold_args: | |
2473 { | |
2474 assert(UseRicochetFrames, "else don't come here"); | |
2475 int elem_slots = argument_slot_count( | |
2476 java_lang_invoke_MethodHandle::type( | |
2477 java_lang_invoke_AdapterMethodHandle::argument(mh()) ) ); | |
2478 // vminfo will be the location to insert the return value | |
2479 vminfo = argslot + elem_slots; | |
2480 ensure_vmlayout_field(target, CHECK); | |
2481 | |
2482 switch (dest) { | |
2483 default : if (!is_subword_type(dest)) goto throw_not_impl; | |
2484 // else fall through: | |
2485 case T_INT : ek_opt = _adapter_opt_fold_int; break; | |
2486 case T_LONG : ek_opt = _adapter_opt_fold_long; break; | |
2487 case T_FLOAT : ek_opt = _adapter_opt_fold_float; break; | |
2488 case T_DOUBLE : ek_opt = _adapter_opt_fold_double; break; | |
2489 case T_OBJECT : ek_opt = _adapter_opt_fold_ref; break; | |
2490 case T_VOID : ek_opt = _adapter_opt_fold_void; break; | |
2491 } | |
2492 assert(ek_adapter_opt_collect_slot(ek_opt) == -1 && | |
2493 ek_adapter_opt_collect_count(ek_opt) == -1 && | |
2494 (ek_adapter_opt_collect_type(ek_opt) == dest || | |
2495 ek_adapter_opt_collect_type(ek_opt) == T_INT && is_subword_type(dest)), | |
2496 ""); | |
2497 | |
2498 if (dest == T_OBJECT && elem_slots == 0 && OptimizeMethodHandles) { | |
2499 // if there are no args, just pretend it's a collect | |
2500 ek_opt = _adapter_opt_collect_0_ref; | |
2501 break; | |
2502 } | |
2503 | |
2504 if (dest == T_OBJECT && OptimizeMethodHandles) { | |
2505 // try to use a fixed length adapter | |
2506 ek_try = EntryKind(_adapter_opt_fold_1_ref - 1 + elem_slots); | |
2507 if (ek_try < _adapter_opt_fold_LAST && | |
2508 ek_adapter_opt_collect_count(ek_try) == elem_slots) { | |
2509 assert(ek_adapter_opt_collect_slot(ek_try) == -1 && | |
2510 ek_adapter_opt_collect_type(ek_try) == dest, ""); | |
2511 ek_opt = ek_try; | |
2512 break; | |
2513 } | |
2514 } | |
2515 | |
2516 break; | |
2517 } | |
2162 | 2518 |
2163 default: | 2519 default: |
2164 // should have failed much earlier; must be a missing case here | 2520 // should have failed much earlier; must be a missing case here |
2165 assert(false, "incomplete switch"); | 2521 assert(false, "incomplete switch"); |
2166 // and fall through: | 2522 // and fall through: |
2167 | 2523 |
2168 throw_not_impl: | 2524 throw_not_impl: |
2169 // FIXME: these adapters are NYI | 2525 if (err == NULL) |
2170 err = "adapter not yet implemented in the JVM"; | 2526 err = "unknown adapter type"; |
2171 break; | 2527 break; |
2528 } | |
2529 | |
2530 if (err != NULL && (vminfo & CONV_VMINFO_MASK) != vminfo) { | |
2531 // should not happen, since vminfo is used to encode arg/slot indexes < 255 | |
2532 err = "vminfo overflow"; | |
2533 } | |
2534 | |
2535 if (err != NULL && !have_entry(ek_opt)) { | |
2536 err = "adapter stub for this kind of method handle is missing"; | |
2172 } | 2537 } |
2173 | 2538 |
2174 if (err != NULL) { | 2539 if (err != NULL) { |
2175 throw_InternalError_for_bad_conversion(conversion, err, THREAD); | 2540 throw_InternalError_for_bad_conversion(conversion, err, THREAD); |
2176 return; | 2541 return; |
2186 java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt)); | 2551 java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt)); |
2187 | 2552 |
2188 // There should be enough memory barriers on exit from native methods | 2553 // There should be enough memory barriers on exit from native methods |
2189 // to ensure that the MH is fully initialized to all threads before | 2554 // to ensure that the MH is fully initialized to all threads before |
2190 // Java code can publish it in global data structures. | 2555 // Java code can publish it in global data structures. |
2556 } | |
2557 | |
2558 void MethodHandles::ensure_vmlayout_field(Handle target, TRAPS) { | |
2559 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(target())); | |
2560 Handle mtform(THREAD, java_lang_invoke_MethodType::form(mtype())); | |
2561 if (mtform.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } | |
2562 if (java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) { | |
2563 if (java_lang_invoke_MethodTypeForm::vmlayout(mtform()) == NULL) { | |
2564 // fill it in | |
2565 Handle erased_mtype(THREAD, java_lang_invoke_MethodTypeForm::erasedType(mtform())); | |
2566 TempNewSymbol erased_signature | |
2567 = java_lang_invoke_MethodType::as_signature(erased_mtype(), /*intern:*/true, CHECK); | |
2568 methodOop cookie | |
2569 = SystemDictionary::find_method_handle_invoke(vmSymbols::invokeExact_name(), | |
2570 erased_signature, | |
2571 SystemDictionaryHandles::Object_klass(), | |
2572 THREAD); | |
2573 java_lang_invoke_MethodTypeForm::init_vmlayout(mtform(), cookie); | |
2574 } | |
2575 } | |
2191 } | 2576 } |
2192 | 2577 |
2193 // | 2578 // |
2194 // Here are the native methods on sun.invoke.MethodHandleImpl. | 2579 // Here are the native methods on sun.invoke.MethodHandleImpl. |
2195 // They are the private interface between this JVM and the HotSpot-specific | 2580 // They are the private interface between this JVM and the HotSpot-specific |
2358 } | 2743 } |
2359 JVM_END | 2744 JVM_END |
2360 | 2745 |
2361 #ifndef PRODUCT | 2746 #ifndef PRODUCT |
2362 #define EACH_NAMED_CON(template) \ | 2747 #define EACH_NAMED_CON(template) \ |
2363 template(MethodHandles,GC_JVM_PUSH_LIMIT) \ | 2748 /* hold back this one until JDK stabilizes */ \ |
2364 template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) \ | 2749 /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */ \ |
2750 /* hold back this one until JDK stabilizes */ \ | |
2751 /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \ | |
2365 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ | 2752 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ |
2366 template(MethodHandles,ETF_DIRECT_HANDLE) \ | 2753 template(MethodHandles,ETF_DIRECT_HANDLE) \ |
2367 template(MethodHandles,ETF_METHOD_NAME) \ | 2754 template(MethodHandles,ETF_METHOD_NAME) \ |
2368 template(MethodHandles,ETF_REFLECT_METHOD) \ | 2755 template(MethodHandles,ETF_REFLECT_METHOD) \ |
2369 template(java_lang_invoke_MemberName,MN_IS_METHOD) \ | 2756 template(java_lang_invoke_MemberName,MN_IS_METHOD) \ |
2383 template(java_lang_invoke_AdapterMethodHandle,OP_ROT_ARGS) \ | 2770 template(java_lang_invoke_AdapterMethodHandle,OP_ROT_ARGS) \ |
2384 template(java_lang_invoke_AdapterMethodHandle,OP_DUP_ARGS) \ | 2771 template(java_lang_invoke_AdapterMethodHandle,OP_DUP_ARGS) \ |
2385 template(java_lang_invoke_AdapterMethodHandle,OP_DROP_ARGS) \ | 2772 template(java_lang_invoke_AdapterMethodHandle,OP_DROP_ARGS) \ |
2386 template(java_lang_invoke_AdapterMethodHandle,OP_COLLECT_ARGS) \ | 2773 template(java_lang_invoke_AdapterMethodHandle,OP_COLLECT_ARGS) \ |
2387 template(java_lang_invoke_AdapterMethodHandle,OP_SPREAD_ARGS) \ | 2774 template(java_lang_invoke_AdapterMethodHandle,OP_SPREAD_ARGS) \ |
2388 template(java_lang_invoke_AdapterMethodHandle,OP_FLYBY) \ | 2775 /* hold back this one until JDK stabilizes */ \ |
2389 template(java_lang_invoke_AdapterMethodHandle,OP_RICOCHET) \ | 2776 /*template(java_lang_invoke_AdapterMethodHandle,CONV_OP_LIMIT)*/ \ |
2390 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_LIMIT) \ | |
2391 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_MASK) \ | 2777 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_MASK) \ |
2392 template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_MASK) \ | 2778 template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_MASK) \ |
2393 template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_SHIFT) \ | 2779 template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_SHIFT) \ |
2394 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_SHIFT) \ | 2780 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_SHIFT) \ |
2395 template(java_lang_invoke_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \ | 2781 template(java_lang_invoke_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \ |