144 "adapter_collect/2/S5/ref",
145
146 // blocking fold conversions:
147 "adapter_fold/ref",
148 "adapter_fold/int",
149 "adapter_fold/long",
150 "adapter_fold/float",
151 "adapter_fold/double",
152 "adapter_fold/void",
153 "adapter_fold/1/ref",
154 "adapter_fold/2/ref",
155 "adapter_fold/3/ref",
156 "adapter_fold/4/ref",
157 "adapter_fold/5/ref",
158
159 NULL
160 };
161
162 // Adapters.
163 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL;
164 int MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size;
165
166 jobject MethodHandles::_raise_exception_method;
167
168 address MethodHandles::_adapter_return_handlers[CONV_TYPE_MASK+1];
169
170 #ifdef ASSERT
171 bool MethodHandles::spot_check_entry_names() {
172 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), "");
173 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), "");
174 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), "");
175 assert(!strcmp(entry_name(_adapter_fold_args), "adapter_fold_args"), "");
176 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), "");
177 assert(!strcmp(entry_name(_adapter_opt_spread_char), "adapter_spread/char"), "");
178 assert(!strcmp(entry_name(_adapter_opt_spread_double), "adapter_spread/double"), "");
179 assert(!strcmp(entry_name(_adapter_opt_collect_int), "adapter_collect/int"), "");
180 assert(!strcmp(entry_name(_adapter_opt_collect_0_ref), "adapter_collect/0/ref"), "");
181 assert(!strcmp(entry_name(_adapter_opt_collect_2_S3_ref), "adapter_collect/2/S3/ref"), "");
182 assert(!strcmp(entry_name(_adapter_opt_filter_S5_ref), "adapter_filter/S5/ref"), "");
183 assert(!strcmp(entry_name(_adapter_opt_fold_3_ref), "adapter_fold/3/ref"), "");
184 assert(!strcmp(entry_name(_adapter_opt_fold_void), "adapter_fold/void"), "");
185 return true;
186 }
187 #endif
188
189
190 //------------------------------------------------------------------------------
191 // MethodHandles::generate_adapters
192 //
193 void MethodHandles::generate_adapters() {
194 #ifdef TARGET_ARCH_NYI_6939861
195 if (FLAG_IS_DEFAULT(UseRicochetFrames)) UseRicochetFrames = false;
196 #endif
197 if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL) return;
198
199 assert(_adapter_code == NULL, "generate only once");
200
201 ResourceMark rm;
202 TraceTime timer("MethodHandles adapters generation", TraceStartupTime);
203 _adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size);
204 if (_adapter_code == NULL)
205 vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
206 CodeBuffer code(_adapter_code);
207 MethodHandlesAdapterGenerator g(&code);
208 g.generate();
209 }
210
211 //------------------------------------------------------------------------------
212 // MethodHandlesAdapterGenerator::generate
213 //
214 void MethodHandlesAdapterGenerator::generate() {
215 // Generate generic method handle adapters.
216 for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
217 ek < MethodHandles::_EK_LIMIT;
218 ek = MethodHandles::EntryKind(1 + (int)ek)) {
219 if (MethodHandles::ek_supported(ek)) {
220 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
221 MethodHandles::generate_method_handle_stub(_masm, ek);
222 }
223 }
224 }
225
226
227 #ifdef TARGET_ARCH_NYI_6939861
228 // these defs belong in methodHandles_<arch>.cpp
1704 java_lang_invoke_MethodHandle::init_vmslots(mh());
1705 int vmargslot = m->size_of_parameters() - 1;
1706 assert(java_lang_invoke_BoundMethodHandle::vmargslot(mh()) == vmargslot, "");
1707
1708 if (VerifyMethodHandles) {
1709 verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
1710 }
1711
1712 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
1713
1714 DEBUG_ONLY(KlassHandle junk1; int junk2);
1715 assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding");
1716 assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
1717
1718 // Done!
1719 java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
1720 }
1721
1722 void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
1723 bool direct_to_method, TRAPS) {
1724 Handle ptype_handle(THREAD,
1725 java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum));
1726 KlassHandle ptype_klass;
1727 BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass);
1728 int slots_pushed = type2size[ptype];
1729
1730 oop argument = java_lang_invoke_BoundMethodHandle::argument(mh());
1731
1732 const char* err = NULL;
1733
1734 switch (ptype) {
1735 case T_OBJECT:
1736 if (argument != NULL)
1737 // we must implicitly convert from the arg type to the outgoing ptype
1738 err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass(), argnum);
1739 break;
1740
1741 case T_ARRAY: case T_VOID:
1742 assert(false, "array, void do not appear here");
1743 default:
1867 if (direct_to_method) me = MethodHandles::entry(_bound_long_direct_mh);
1868 else me = MethodHandles::entry(_bound_long_mh);
1869 } else if (slots_pushed == 1) {
1870 if (direct_to_method) me = MethodHandles::entry(_bound_int_direct_mh);
1871 else me = MethodHandles::entry(_bound_int_mh);
1872 } else {
1873 assert(false, "");
1874 }
1875
1876 // Done!
1877 java_lang_invoke_MethodHandle::set_vmentry(mh(), me);
1878 }
1879
1880 static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) {
1881 char msg[200];
1882 jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err);
1883 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg);
1884 }
1885
1886 void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
1887 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
1888 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
1889
1890 verify_vmargslot(mh, argnum, argslot, CHECK);
1891 verify_vmslots(mh, CHECK);
1892
1893 jint conv_op = adapter_conversion_op(conversion);
1894 if (!conv_op_valid(conv_op)) {
1895 throw_InternalError_for_bad_conversion(conversion, "unknown conversion op", THREAD);
1896 return;
1897 }
1898 EntryKind ek = adapter_entry_kind(conv_op);
1899
1900 int stack_move = adapter_conversion_stack_move(conversion);
1901 BasicType src = adapter_conversion_src_type(conversion);
1902 BasicType dest = adapter_conversion_dest_type(conversion);
1903 int vminfo = adapter_conversion_vminfo(conversion); // should be zero
1904
1905 Handle argument(THREAD, java_lang_invoke_AdapterMethodHandle::argument(mh()));
1906 Handle target(THREAD, java_lang_invoke_AdapterMethodHandle::vmtarget(mh()));
1970 err = "adapter requires primitive dest conversion subfield"; break;
1971 }
1972 break;
1973 case _adapter_prim_to_ref:
1974 if (!is_java_primitive(src) || dest != T_OBJECT) {
1975 err = "adapter requires primitive src conversion subfield"; break;
1976 }
1977 break;
1978 case _adapter_swap_args:
1979 case _adapter_rot_args:
1980 {
1981 if (!src || src != dest) {
1982 err = "adapter requires src/dest conversion subfields for swap"; break;
1983 }
1984 int swap_size = type2size[src];
1985 int src_slot = argslot;
1986 int dest_slot = vminfo;
1987 bool rotate_up = (src_slot > dest_slot); // upward rotation
1988 int src_arg = argnum;
1989 int dest_arg = argument_slot_to_argnum(dst_mtype(), dest_slot);
1990 verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
1991 if (!(dest_slot >= src_slot + swap_size) &&
1992 !(src_slot >= dest_slot + swap_size)) {
1993 err = "source, destination slots must be distinct";
1994 } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
1995 err = "source of swap must be deeper in stack";
1996 } else if (ek == _adapter_swap_args) {
1997 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
1998 java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
1999 dest_arg);
2000 } else if (ek == _adapter_rot_args) {
2001 if (rotate_up) {
2002 assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
2003 // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
2004 // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
2005 for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
2006 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2007 java_lang_invoke_MethodType::ptype(dst_mtype(), i-1),
2008 i);
2009 }
2010 } else { // rotate down
|
144 "adapter_collect/2/S5/ref",
145
146 // blocking fold conversions:
147 "adapter_fold/ref",
148 "adapter_fold/int",
149 "adapter_fold/long",
150 "adapter_fold/float",
151 "adapter_fold/double",
152 "adapter_fold/void",
153 "adapter_fold/1/ref",
154 "adapter_fold/2/ref",
155 "adapter_fold/3/ref",
156 "adapter_fold/4/ref",
157 "adapter_fold/5/ref",
158
159 NULL
160 };
161
162 // Adapters.
163 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL;
164
165 jobject MethodHandles::_raise_exception_method;
166
167 address MethodHandles::_adapter_return_handlers[CONV_TYPE_MASK+1];
168
169 #ifdef ASSERT
170 bool MethodHandles::spot_check_entry_names() {
171 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), "");
172 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), "");
173 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), "");
174 assert(!strcmp(entry_name(_adapter_fold_args), "adapter_fold_args"), "");
175 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), "");
176 assert(!strcmp(entry_name(_adapter_opt_spread_char), "adapter_spread/char"), "");
177 assert(!strcmp(entry_name(_adapter_opt_spread_double), "adapter_spread/double"), "");
178 assert(!strcmp(entry_name(_adapter_opt_collect_int), "adapter_collect/int"), "");
179 assert(!strcmp(entry_name(_adapter_opt_collect_0_ref), "adapter_collect/0/ref"), "");
180 assert(!strcmp(entry_name(_adapter_opt_collect_2_S3_ref), "adapter_collect/2/S3/ref"), "");
181 assert(!strcmp(entry_name(_adapter_opt_filter_S5_ref), "adapter_filter/S5/ref"), "");
182 assert(!strcmp(entry_name(_adapter_opt_fold_3_ref), "adapter_fold/3/ref"), "");
183 assert(!strcmp(entry_name(_adapter_opt_fold_void), "adapter_fold/void"), "");
184 return true;
185 }
186 #endif
187
188
189 //------------------------------------------------------------------------------
190 // MethodHandles::generate_adapters
191 //
192 void MethodHandles::generate_adapters() {
193 #ifdef TARGET_ARCH_NYI_6939861
194 if (FLAG_IS_DEFAULT(UseRicochetFrames)) UseRicochetFrames = false;
195 #endif
196 if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL) return;
197
198 assert(_adapter_code == NULL, "generate only once");
199
200 ResourceMark rm;
201 TraceTime timer("MethodHandles adapters generation", TraceStartupTime);
202 _adapter_code = MethodHandlesAdapterBlob::create(adapter_code_size);
203 if (_adapter_code == NULL)
204 vm_exit_out_of_memory(adapter_code_size, "CodeCache: no room for MethodHandles adapters");
205 CodeBuffer code(_adapter_code);
206 MethodHandlesAdapterGenerator g(&code);
207 g.generate();
208
209 // Transfer code comments
210 _adapter_code->set_comments(code.comments());
211 }
212
213 //------------------------------------------------------------------------------
214 // MethodHandlesAdapterGenerator::generate
215 //
216 void MethodHandlesAdapterGenerator::generate() {
217 // Generate generic method handle adapters.
218 for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
219 ek < MethodHandles::_EK_LIMIT;
220 ek = MethodHandles::EntryKind(1 + (int)ek)) {
221 if (MethodHandles::ek_supported(ek)) {
222 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
223 MethodHandles::generate_method_handle_stub(_masm, ek);
224 }
225 }
226 }
227
228
229 #ifdef TARGET_ARCH_NYI_6939861
230 // these defs belong in methodHandles_<arch>.cpp
1706 java_lang_invoke_MethodHandle::init_vmslots(mh());
1707 int vmargslot = m->size_of_parameters() - 1;
1708 assert(java_lang_invoke_BoundMethodHandle::vmargslot(mh()) == vmargslot, "");
1709
1710 if (VerifyMethodHandles) {
1711 verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
1712 }
1713
1714 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
1715
1716 DEBUG_ONLY(KlassHandle junk1; int junk2);
1717 assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding");
1718 assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
1719
1720 // Done!
1721 java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
1722 }
1723
1724 void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
1725 bool direct_to_method, TRAPS) {
1726 ResourceMark rm;
1727 Handle ptype_handle(THREAD,
1728 java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum));
1729 KlassHandle ptype_klass;
1730 BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass);
1731 int slots_pushed = type2size[ptype];
1732
1733 oop argument = java_lang_invoke_BoundMethodHandle::argument(mh());
1734
1735 const char* err = NULL;
1736
1737 switch (ptype) {
1738 case T_OBJECT:
1739 if (argument != NULL)
1740 // we must implicitly convert from the arg type to the outgoing ptype
1741 err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass(), argnum);
1742 break;
1743
1744 case T_ARRAY: case T_VOID:
1745 assert(false, "array, void do not appear here");
1746 default:
1870 if (direct_to_method) me = MethodHandles::entry(_bound_long_direct_mh);
1871 else me = MethodHandles::entry(_bound_long_mh);
1872 } else if (slots_pushed == 1) {
1873 if (direct_to_method) me = MethodHandles::entry(_bound_int_direct_mh);
1874 else me = MethodHandles::entry(_bound_int_mh);
1875 } else {
1876 assert(false, "");
1877 }
1878
1879 // Done!
1880 java_lang_invoke_MethodHandle::set_vmentry(mh(), me);
1881 }
1882
1883 static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) {
1884 char msg[200];
1885 jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err);
1886 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg);
1887 }
1888
1889 void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
1890 ResourceMark rm;
1891 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
1892 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
1893
1894 verify_vmargslot(mh, argnum, argslot, CHECK);
1895 verify_vmslots(mh, CHECK);
1896
1897 jint conv_op = adapter_conversion_op(conversion);
1898 if (!conv_op_valid(conv_op)) {
1899 throw_InternalError_for_bad_conversion(conversion, "unknown conversion op", THREAD);
1900 return;
1901 }
1902 EntryKind ek = adapter_entry_kind(conv_op);
1903
1904 int stack_move = adapter_conversion_stack_move(conversion);
1905 BasicType src = adapter_conversion_src_type(conversion);
1906 BasicType dest = adapter_conversion_dest_type(conversion);
1907 int vminfo = adapter_conversion_vminfo(conversion); // should be zero
1908
1909 Handle argument(THREAD, java_lang_invoke_AdapterMethodHandle::argument(mh()));
1910 Handle target(THREAD, java_lang_invoke_AdapterMethodHandle::vmtarget(mh()));
1974 err = "adapter requires primitive dest conversion subfield"; break;
1975 }
1976 break;
1977 case _adapter_prim_to_ref:
1978 if (!is_java_primitive(src) || dest != T_OBJECT) {
1979 err = "adapter requires primitive src conversion subfield"; break;
1980 }
1981 break;
1982 case _adapter_swap_args:
1983 case _adapter_rot_args:
1984 {
1985 if (!src || src != dest) {
1986 err = "adapter requires src/dest conversion subfields for swap"; break;
1987 }
1988 int swap_size = type2size[src];
1989 int src_slot = argslot;
1990 int dest_slot = vminfo;
1991 bool rotate_up = (src_slot > dest_slot); // upward rotation
1992 int src_arg = argnum;
1993 int dest_arg = argument_slot_to_argnum(dst_mtype(), dest_slot);
1994 verify_vmargslot(target, dest_arg, dest_slot, CHECK);
1995 if (!(dest_slot >= src_slot + swap_size) &&
1996 !(src_slot >= dest_slot + swap_size)) {
1997 err = "source, destination slots must be distinct";
1998 } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
1999 err = "source of swap must be deeper in stack";
2000 } else if (ek == _adapter_swap_args) {
2001 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
2002 java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
2003 dest_arg);
2004 } else if (ek == _adapter_rot_args) {
2005 if (rotate_up) {
2006 assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
2007 // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
2008 // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
2009 for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
2010 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2011 java_lang_invoke_MethodType::ptype(dst_mtype(), i-1),
2012 i);
2013 }
2014 } else { // rotate down
|