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

src/share/vm/prims/methodHandles.cpp

Print this page




 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


1963       if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
1964         err = "adapter requires primitive src/dest conversion subfields"; break;
1965       }
1966       if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
1967           !(src == T_FLOAT || src == T_DOUBLE) &&  (dest == T_FLOAT || dest == T_DOUBLE)) {
1968         err = "adapter cannot convert beween floating and fixed-point"; break;
1969       }
1970       break;
1971     case _adapter_ref_to_prim:
1972       if (src != T_OBJECT || !is_java_primitive(dest)
1973           || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
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
2015             assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
2016             // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
2017             // that is:     [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
2018             for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {

2019               err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2020                                                java_lang_invoke_MethodType::ptype(dst_mtype(), i+1),
2021                                                i);
2022             }
2023           }
2024         }
2025         if (err == NULL)
2026           err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
2027                                            java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
2028                                            src_arg);
2029       }

2030       break;
2031     case _adapter_spread_args:
2032     case _adapter_collect_args:
2033     case _adapter_fold_args:
2034       {
2035         bool is_spread = (ek == _adapter_spread_args);
2036         bool is_fold   = (ek == _adapter_fold_args);
2037         BasicType coll_type = is_spread ? src : dest;
2038         BasicType elem_type = is_spread ? dest : src;
2039         // coll_type is type of args in collected form (or T_VOID if none)
2040         // elem_type is common type of args in spread form (or T_VOID if missing or heterogeneous)
2041         if (coll_type == 0 || elem_type == 0) {
2042           err = "adapter requires src/dest subfields for spread or collect"; break;
2043         }
2044         if (is_spread && coll_type != T_OBJECT) {
2045           err = "spread adapter requires object type for argument bundle"; break;
2046         }
2047         Handle spread_mtype = (is_spread ? dst_mtype : src_mtype);
2048         int spread_slot = argslot;
2049         int spread_arg  = argnum;


2796   Handle mh(THREAD, JNIHandles::resolve(mh_jh));
2797   if (!java_lang_invoke_MethodHandle::is_instance(mh())) {
2798     THROW_NULL(vmSymbols::java_lang_IllegalArgumentException());
2799   }
2800   oop target = MethodHandles::encode_target(mh, format, CHECK_NULL);
2801   return JNIHandles::make_local(THREAD, target);
2802 }
2803 JVM_END
2804 
2805 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
2806   switch (which) {
2807   case MethodHandles::GC_JVM_PUSH_LIMIT:
2808     guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF,
2809               "MethodHandlePushLimit parameter must be in valid range");
2810     return MethodHandlePushLimit;
2811   case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
2812     // return number of words per slot, signed according to stack direction
2813     return MethodHandles::stack_move_unit();
2814   case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
2815     return MethodHandles::adapter_conversion_ops_supported_mask();


2816   }
2817   return 0;
2818 }
2819 JVM_END
2820 
2821 #ifndef PRODUCT
2822 #define EACH_NAMED_CON(template) \
2823   /* hold back this one until JDK stabilizes */ \
2824   /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */  \
2825   /* hold back this one until JDK stabilizes */ \
2826   /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \


2827     template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
2828     template(MethodHandles,ETF_DIRECT_HANDLE) \
2829     template(MethodHandles,ETF_METHOD_NAME) \
2830     template(MethodHandles,ETF_REFLECT_METHOD) \
2831     template(java_lang_invoke_MemberName,MN_IS_METHOD) \
2832     template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
2833     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
2834     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
2835     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
2836     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
2837     template(java_lang_invoke_MemberName,VM_INDEX_UNINITIALIZED) \
2838     template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_ONLY) \
2839     template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_RAW) \
2840     template(java_lang_invoke_AdapterMethodHandle,OP_CHECK_CAST) \
2841     template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
2842     template(java_lang_invoke_AdapterMethodHandle,OP_REF_TO_PRIM) \
2843     template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_REF) \
2844     template(java_lang_invoke_AdapterMethodHandle,OP_SWAP_ARGS) \
2845     template(java_lang_invoke_AdapterMethodHandle,OP_ROT_ARGS) \
2846     template(java_lang_invoke_AdapterMethodHandle,OP_DUP_ARGS) \




 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 
 210 //------------------------------------------------------------------------------
 211 // MethodHandlesAdapterGenerator::generate
 212 //
 213 void MethodHandlesAdapterGenerator::generate() {
 214   // Generate generic method handle adapters.
 215   for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
 216        ek < MethodHandles::_EK_LIMIT;
 217        ek = MethodHandles::EntryKind(1 + (int)ek)) {
 218     if (MethodHandles::ek_supported(ek)) {
 219       StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
 220       MethodHandles::generate_method_handle_stub(_masm, ek);
 221     }
 222   }
 223 }
 224 
 225 
 226 #ifdef TARGET_ARCH_NYI_6939861
 227 // these defs belong in methodHandles_<arch>.cpp


1960       if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
1961         err = "adapter requires primitive src/dest conversion subfields"; break;
1962       }
1963       if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
1964           !(src == T_FLOAT || src == T_DOUBLE) &&  (dest == T_FLOAT || dest == T_DOUBLE)) {
1965         err = "adapter cannot convert beween floating and fixed-point"; break;
1966       }
1967       break;
1968     case _adapter_ref_to_prim:
1969       if (src != T_OBJECT || !is_java_primitive(dest)
1970           || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
1971         err = "adapter requires primitive dest conversion subfield"; break;
1972       }
1973       break;
1974     case _adapter_prim_to_ref:
1975       if (!is_java_primitive(src) || dest != T_OBJECT) {
1976         err = "adapter requires primitive src conversion subfield"; break;
1977       }
1978       break;
1979     case _adapter_swap_args:

1980       {
1981         if (!src || !dest) {
1982           err = "adapter requires src/dest conversion subfields for swap"; break;
1983         }
1984         int src_size  = type2size[src];
1985         if (src_size != type2size[dest]) {
1986           err = "adapter requires equal sizes for src/dest"; break;
1987         }
1988         int src_slot   = argslot;
1989         int dest_slot  = vminfo;

1990         int src_arg    = argnum;
1991         int dest_arg   = argument_slot_to_argnum(src_mtype(), dest_slot);
1992         verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
1993         if (!(dest_slot >= src_slot + src_size) &&
1994             !(src_slot >= dest_slot + src_size)) {
1995           err = "source, destination slots must be distinct"; break;
1996         } else if (!(src_slot > dest_slot)) {
1997           err = "source of swap must be deeper in stack"; break;
1998         }
1999         err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
2000                                          java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
2001                                          dest_arg);
2002         if (err == NULL)
2003           err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
2004                                            java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
2005                                            src_arg);
2006         break;
2007       }
2008     case _adapter_rot_args:
2009       {
2010         if (!src || !dest) {
2011           err = "adapter requires src/dest conversion subfields for rotate"; break;
2012         }
2013         int src_slot   = argslot;
2014         int limit_raw  = vminfo;
2015         bool rot_down  = (src_slot < limit_raw);
2016         int limit_bias = (rot_down ? MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS : 0);
2017         int limit_slot = limit_raw - limit_bias;
2018         int src_arg    = argnum;
2019         int limit_arg  = argument_slot_to_argnum(src_mtype(), limit_slot);
2020         verify_vmargslot(mh, limit_arg, limit_slot, CHECK);
2021         if (src_slot == limit_slot) {
2022           err = "source, destination slots must be distinct"; break;
2023         }
2024         if (!rot_down) {  // rotate slots up == shift arguments left
2025           // limit_slot is an inclusive lower limit
2026           assert((src_slot > limit_slot) && (src_arg < limit_arg), "");
2027           // rotate up: [limit_slot..src_slot-ss] --> [limit_slot+ss..src_slot]
2028           // that is:   [src_arg+1..limit_arg] --> [src_arg..limit_arg-1]
2029           for (int i = src_arg+1; i <= limit_arg && err == NULL; i++) {
2030             err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2031                                              java_lang_invoke_MethodType::ptype(dst_mtype(), i-1),
2032                                              i);
2033           }
2034         } else { // rotate slots down == shfit arguments right
2035           // limit_slot is an exclusive upper limit
2036           assert((src_slot < limit_slot - limit_bias) && (src_arg > limit_arg + limit_bias), "");
2037           // rotate down: [src_slot+ss..limit_slot) --> [src_slot..limit_slot-ss)
2038           // that is:     (limit_arg..src_arg-1] --> (dst_arg+1..src_arg]
2039           for (int i = limit_arg+1; i <= src_arg-1 && err == NULL; i++) {
2040             err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2041                                              java_lang_invoke_MethodType::ptype(dst_mtype(), i+1),
2042                                              i);
2043           }
2044         }
2045         if (err == NULL) {
2046           int dest_arg = (rot_down ? limit_arg+1 : limit_arg);
2047           err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
2048                                            java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
2049                                            src_arg);
2050         }
2051       }
2052       break;
2053     case _adapter_spread_args:
2054     case _adapter_collect_args:
2055     case _adapter_fold_args:
2056       {
2057         bool is_spread = (ek == _adapter_spread_args);
2058         bool is_fold   = (ek == _adapter_fold_args);
2059         BasicType coll_type = is_spread ? src : dest;
2060         BasicType elem_type = is_spread ? dest : src;
2061         // coll_type is type of args in collected form (or T_VOID if none)
2062         // elem_type is common type of args in spread form (or T_VOID if missing or heterogeneous)
2063         if (coll_type == 0 || elem_type == 0) {
2064           err = "adapter requires src/dest subfields for spread or collect"; break;
2065         }
2066         if (is_spread && coll_type != T_OBJECT) {
2067           err = "spread adapter requires object type for argument bundle"; break;
2068         }
2069         Handle spread_mtype = (is_spread ? dst_mtype : src_mtype);
2070         int spread_slot = argslot;
2071         int spread_arg  = argnum;


2818   Handle mh(THREAD, JNIHandles::resolve(mh_jh));
2819   if (!java_lang_invoke_MethodHandle::is_instance(mh())) {
2820     THROW_NULL(vmSymbols::java_lang_IllegalArgumentException());
2821   }
2822   oop target = MethodHandles::encode_target(mh, format, CHECK_NULL);
2823   return JNIHandles::make_local(THREAD, target);
2824 }
2825 JVM_END
2826 
2827 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
2828   switch (which) {
2829   case MethodHandles::GC_JVM_PUSH_LIMIT:
2830     guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF,
2831               "MethodHandlePushLimit parameter must be in valid range");
2832     return MethodHandlePushLimit;
2833   case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
2834     // return number of words per slot, signed according to stack direction
2835     return MethodHandles::stack_move_unit();
2836   case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
2837     return MethodHandles::adapter_conversion_ops_supported_mask();
2838   case MethodHandles::GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS:
2839     return MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS;
2840   }
2841   return 0;
2842 }
2843 JVM_END
2844 
2845 #ifndef PRODUCT
2846 #define EACH_NAMED_CON(template) \
2847   /* hold back this one until JDK stabilizes */ \
2848   /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */  \
2849   /* hold back this one until JDK stabilizes */ \
2850   /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \
2851   /* hold back this one until JDK stabilizes */ \
2852   /* template(MethodHandles,GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS) */ \
2853     template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
2854     template(MethodHandles,ETF_DIRECT_HANDLE) \
2855     template(MethodHandles,ETF_METHOD_NAME) \
2856     template(MethodHandles,ETF_REFLECT_METHOD) \
2857     template(java_lang_invoke_MemberName,MN_IS_METHOD) \
2858     template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
2859     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
2860     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
2861     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
2862     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
2863     template(java_lang_invoke_MemberName,VM_INDEX_UNINITIALIZED) \
2864     template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_ONLY) \
2865     template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_RAW) \
2866     template(java_lang_invoke_AdapterMethodHandle,OP_CHECK_CAST) \
2867     template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
2868     template(java_lang_invoke_AdapterMethodHandle,OP_REF_TO_PRIM) \
2869     template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_REF) \
2870     template(java_lang_invoke_AdapterMethodHandle,OP_SWAP_ARGS) \
2871     template(java_lang_invoke_AdapterMethodHandle,OP_ROT_ARGS) \
2872     template(java_lang_invoke_AdapterMethodHandle,OP_DUP_ARGS) \


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