src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7045514 Sdiff src/share/vm/prims

src/share/vm/prims/methodHandles.cpp

Print this page




 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


src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File