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

src/share/vm/prims/methodHandles.cpp

Print this page




1288   // Check the other arguments for mistypes.
1289   verify_method_signature(m, mtype, first_ptype_pos, bound_recv_type, CHECK);
1290   return;
1291 
1292  die:
1293   THROW_MSG(vmSymbols::java_lang_InternalError(), err);
1294 }
1295 
1296 void MethodHandles::verify_vmslots(Handle mh, TRAPS) {
1297   // Verify vmslots.
1298   int check_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(mh()));
1299   if (java_lang_invoke_MethodHandle::vmslots(mh()) != check_slots) {
1300     THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH");
1301   }
1302 }
1303 
1304 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
1305   // Verify that argslot points at the given argnum.
1306   int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum);
1307   if (argslot != check_slot || argslot < 0) {

1308     const char* fmt = "for argnum of %d, vmargslot is %d, should be %d";
1309     size_t msglen = strlen(fmt) + 3*11 + 1;
1310     char* msg = NEW_RESOURCE_ARRAY(char, msglen);
1311     jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
1312     THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
1313   }
1314 }
1315 
1316 // Verify the correspondence between two method types.
1317 // Apart from the advertised changes, caller method type X must
1318 // be able to invoke the callee method Y type with no violations
1319 // of type integrity.
1320 // Return NULL if all is well, else a short error message.
1321 const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end,
1322                                                     int insert_argnum, oop insert_type,
1323                                                     int change_argnum, oop change_type,
1324                                                     int delete_argnum,
1325                                                     oop dst_mtype, int dst_beg, int dst_end,
1326                                                     bool raw) {
1327   objArrayOop src_ptypes = java_lang_invoke_MethodType::ptypes(src_mtype);


1963       }
1964       break;
1965     case _adapter_ref_to_prim:
1966       if (src != T_OBJECT || !is_java_primitive(dest)
1967           || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
1968         err = "adapter requires primitive dest conversion subfield"; break;
1969       }
1970       break;
1971     case _adapter_prim_to_ref:
1972       if (!is_java_primitive(src) || dest != T_OBJECT) {
1973         err = "adapter requires primitive src conversion subfield"; break;
1974       }
1975       break;
1976     case _adapter_swap_args:
1977     case _adapter_rot_args:
1978       {
1979         if (!src || src != dest) {
1980           err = "adapter requires src/dest conversion subfields for swap"; break;
1981         }
1982         int swap_size = type2size[src];
1983         int slot_limit = java_lang_invoke_MethodHandle::vmslots(target());
1984         int src_slot   = argslot;
1985         int dest_slot  = vminfo;
1986         bool rotate_up = (src_slot > dest_slot); // upward rotation
1987         int src_arg    = argnum;
1988         int dest_arg   = argument_slot_to_argnum(dst_mtype(), dest_slot);
1989         verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
1990         if (!(dest_slot >= src_slot + swap_size) &&
1991             !(src_slot >= dest_slot + swap_size)) {
1992           err = "source, destination slots must be distinct";
1993         } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
1994           err = "source of swap must be deeper in stack";
1995         } else if (ek == _adapter_swap_args) {
1996           err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
1997                                            java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
1998                                            dest_arg);
1999         } else if (ek == _adapter_rot_args) {
2000           if (rotate_up) {
2001             assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
2002             // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
2003             // that is:   [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]


2316             ek_adapter_opt_collect_slot(ek_try) == argslot) {
2317           assert(ek_adapter_opt_collect_count(ek_try) == 2 &&
2318                  ek_adapter_opt_collect_type(ek_try) == T_OBJECT, "");
2319           ek_opt = ek_try;
2320           break;
2321         }
2322         // else downgrade to variable slot:
2323         ek_opt = _adapter_opt_collect_2_ref;
2324         break;
2325       default:
2326         goto throw_not_impl;
2327         break;
2328       }
2329     }
2330     break;
2331 
2332   case _adapter_swap_args:
2333   case _adapter_rot_args:
2334     {
2335       int swap_slots = type2size[src];
2336       int slot_limit = java_lang_invoke_AdapterMethodHandle::vmslots(mh());
2337       int src_slot   = argslot;
2338       int dest_slot  = vminfo;
2339       int rotate     = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
2340       switch (swap_slots) {
2341       case 1:
2342         ek_opt = (!rotate    ? _adapter_opt_swap_1 :
2343                   rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
2344         break;
2345       case 2:
2346         ek_opt = (!rotate    ? _adapter_opt_swap_2 :
2347                   rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
2348         break;
2349       default:
2350         goto throw_not_impl;
2351         break;
2352       }
2353     }
2354     break;
2355 
2356   case _adapter_spread_args:


2644 static void stress_method_handle_walk(Handle mh, TRAPS) {}
2645 
2646 #endif
2647 
2648 //
2649 // Here are the native methods on sun.invoke.MethodHandleImpl.
2650 // They are the private interface between this JVM and the HotSpot-specific
2651 // Java code that implements JSR 292 method handles.
2652 //
2653 // Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
2654 // that intrinsic (non-JNI) native methods are defined in HotSpot.
2655 //
2656 
2657 // direct method handles for invokestatic or invokespecial
2658 // void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller);
2659 JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
2660                              jobject target_jh, jboolean do_dispatch, jobject caller_jh)) {
2661   ResourceMark rm;              // for error messages
2662 
2663   // This is the guy we are initializing:
2664   if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
2665   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
2666 
2667   // Early returns out of this method leave the DMH in an unfinished state.
2668   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
2669 
2670   // which method are we really talking about?
2671   if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
2672   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
2673   if (java_lang_invoke_MemberName::is_instance(target()) &&
2674       java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) {
2675     MethodHandles::resolve_MemberName(target, CHECK);
2676   }
2677 
2678   KlassHandle receiver_limit; int decode_flags = 0;
2679   methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
2680   if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
2681 
2682   // The trusted Java code that calls this method should already have performed
2683   // access checks on behalf of the given caller.  But, we can verify this.
2684   if (VerifyMethodHandles && caller_jh != NULL) {
2685     KlassHandle caller(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)));
2686     // If this were a bytecode, the first access check would be against
2687     // the "reference class" mentioned in the CONSTANT_Methodref.
2688     // We don't know at this point which class that was, and if we
2689     // check against m.method_holder we might get the wrong answer.
2690     // So we just make sure to handle this check when the resolution
2691     // happens, when we call resolve_MemberName.


2705       // %%% following cutout belongs in Reflection::verify_field_access?
2706       bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(),
2707                                                         resolved_klass, THREAD);
2708       if (!same_pm) {
2709         THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
2710       }
2711     }
2712   }
2713 
2714   MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK);
2715   stress_method_handle_walk(mh, CHECK);
2716 }
2717 JVM_END
2718 
2719 // bound method handles
2720 JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
2721                              jobject target_jh, int argnum)) {
2722   ResourceMark rm;              // for error messages
2723 
2724   // This is the guy we are initializing:
2725   if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
2726   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
2727 
2728   // Early returns out of this method leave the BMH in an unfinished state.
2729   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
2730 
2731   if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
2732   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
2733 
2734   if (!java_lang_invoke_MethodHandle::is_instance(target())) {
2735     // Target object is a reflective method.  (%%% Do we need this alternate path?)
2736     Untested("init_BMH of non-MH");
2737     if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
2738     KlassHandle receiver_limit; int decode_flags = 0;
2739     methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
2740     MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
2741                                                        receiver_limit,
2742                                                        decode_flags,
2743                                                        CHECK);
2744   } else {
2745     // Build a BMH on top of a DMH or another BMH:
2746     MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK);
2747   }
2748   stress_method_handle_walk(mh, CHECK);
2749 }
2750 JVM_END
2751 
2752 // adapter method handles
2753 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
2754                              jobject target_jh, int argnum)) {
2755   // This is the guy we are initializing:
2756   if (mh_jh == NULL || target_jh == NULL) {
2757     THROW(vmSymbols::java_lang_InternalError());
2758   }
2759   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
2760   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
2761 
2762   // Early returns out of this method leave the AMH in an unfinished state.
2763   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
2764 
2765   MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK);
2766   stress_method_handle_walk(mh, CHECK);
2767 }
2768 JVM_END
2769 
2770 // method type forms
2771 JVM_ENTRY(void, MHN_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) {
2772   if (erased_jh == NULL)  return;
2773   if (TraceMethodHandles) {
2774     tty->print("creating MethodType form ");
2775     if (WizardMode || Verbose) {   // Warning: this calls Java code on the MH!
2776       // call Object.toString()
2777       Symbol* name = vmSymbols::toString_name();
2778       Symbol* sig = vmSymbols::void_string_signature();


2873 #ifndef PRODUCT
2874   if (which >= 0 && which < con_value_count) {
2875     int con = con_values[which];
2876     objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
2877     if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
2878       const char* str = &con_names[0];
2879       for (int i = 0; i < which; i++)
2880         str += strlen(str) + 1;   // skip name and null
2881       oop name = java_lang_String::create_oop_from_str(str, CHECK_0);  // possible safepoint
2882       box->obj_at_put(0, name);
2883     }
2884     return con;
2885   }
2886 #endif
2887   return 0;
2888 }
2889 JVM_END
2890 
2891 // void init(MemberName self, AccessibleObject ref)
2892 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
2893   if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }

2894   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
2895   oop target_oop = JNIHandles::resolve_non_null(target_jh);
2896   MethodHandles::init_MemberName(mname(), target_oop);
2897 }
2898 JVM_END
2899 
2900 // void expand(MemberName self)
2901 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
2902   if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
2903   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
2904   MethodHandles::expand_MemberName(mname, 0, CHECK);
2905 }
2906 JVM_END
2907 
2908 // void resolve(MemberName self, Class<?> caller)
2909 JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
2910   if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
2911   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
2912 
2913   // The trusted Java code that calls this method should already have performed
2914   // access checks on behalf of the given caller.  But, we can verify this.
2915   if (VerifyMethodHandles && caller_jh != NULL) {
2916     klassOop reference_klass = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(mname()));
2917     if (reference_klass != NULL) {
2918       // Emulate LinkResolver::check_klass_accessability.
2919       klassOop caller = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh));
2920       if (!Reflection::verify_class_access(caller,
2921                                            reference_klass,
2922                                            true)) {
2923         THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(reference_klass)->external_name());
2924       }
2925     }
2926   }
2927 
2928   MethodHandles::resolve_MemberName(mname, CHECK);
2929 }
2930 JVM_END




1288   // Check the other arguments for mistypes.
1289   verify_method_signature(m, mtype, first_ptype_pos, bound_recv_type, CHECK);
1290   return;
1291 
1292  die:
1293   THROW_MSG(vmSymbols::java_lang_InternalError(), err);
1294 }
1295 
1296 void MethodHandles::verify_vmslots(Handle mh, TRAPS) {
1297   // Verify vmslots.
1298   int check_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(mh()));
1299   if (java_lang_invoke_MethodHandle::vmslots(mh()) != check_slots) {
1300     THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH");
1301   }
1302 }
1303 
1304 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
1305   // Verify that argslot points at the given argnum.
1306   int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum);
1307   if (argslot != check_slot || argslot < 0) {
1308     ResourceMark rm;
1309     const char* fmt = "for argnum of %d, vmargslot is %d, should be %d";
1310     size_t msglen = strlen(fmt) + 3*11 + 1;
1311     char* msg = NEW_RESOURCE_ARRAY(char, msglen);
1312     jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
1313     THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
1314   }
1315 }
1316 
1317 // Verify the correspondence between two method types.
1318 // Apart from the advertised changes, caller method type X must
1319 // be able to invoke the callee method Y type with no violations
1320 // of type integrity.
1321 // Return NULL if all is well, else a short error message.
1322 const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end,
1323                                                     int insert_argnum, oop insert_type,
1324                                                     int change_argnum, oop change_type,
1325                                                     int delete_argnum,
1326                                                     oop dst_mtype, int dst_beg, int dst_end,
1327                                                     bool raw) {
1328   objArrayOop src_ptypes = java_lang_invoke_MethodType::ptypes(src_mtype);


1964       }
1965       break;
1966     case _adapter_ref_to_prim:
1967       if (src != T_OBJECT || !is_java_primitive(dest)
1968           || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
1969         err = "adapter requires primitive dest conversion subfield"; break;
1970       }
1971       break;
1972     case _adapter_prim_to_ref:
1973       if (!is_java_primitive(src) || dest != T_OBJECT) {
1974         err = "adapter requires primitive src conversion subfield"; break;
1975       }
1976       break;
1977     case _adapter_swap_args:
1978     case _adapter_rot_args:
1979       {
1980         if (!src || src != dest) {
1981           err = "adapter requires src/dest conversion subfields for swap"; break;
1982         }
1983         int swap_size = type2size[src];

1984         int src_slot   = argslot;
1985         int dest_slot  = vminfo;
1986         bool rotate_up = (src_slot > dest_slot); // upward rotation
1987         int src_arg    = argnum;
1988         int dest_arg   = argument_slot_to_argnum(dst_mtype(), dest_slot);
1989         verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
1990         if (!(dest_slot >= src_slot + swap_size) &&
1991             !(src_slot >= dest_slot + swap_size)) {
1992           err = "source, destination slots must be distinct";
1993         } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) {
1994           err = "source of swap must be deeper in stack";
1995         } else if (ek == _adapter_swap_args) {
1996           err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
1997                                            java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
1998                                            dest_arg);
1999         } else if (ek == _adapter_rot_args) {
2000           if (rotate_up) {
2001             assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
2002             // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
2003             // that is:   [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]


2316             ek_adapter_opt_collect_slot(ek_try) == argslot) {
2317           assert(ek_adapter_opt_collect_count(ek_try) == 2 &&
2318                  ek_adapter_opt_collect_type(ek_try) == T_OBJECT, "");
2319           ek_opt = ek_try;
2320           break;
2321         }
2322         // else downgrade to variable slot:
2323         ek_opt = _adapter_opt_collect_2_ref;
2324         break;
2325       default:
2326         goto throw_not_impl;
2327         break;
2328       }
2329     }
2330     break;
2331 
2332   case _adapter_swap_args:
2333   case _adapter_rot_args:
2334     {
2335       int swap_slots = type2size[src];

2336       int src_slot   = argslot;
2337       int dest_slot  = vminfo;
2338       int rotate     = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
2339       switch (swap_slots) {
2340       case 1:
2341         ek_opt = (!rotate    ? _adapter_opt_swap_1 :
2342                   rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
2343         break;
2344       case 2:
2345         ek_opt = (!rotate    ? _adapter_opt_swap_2 :
2346                   rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
2347         break;
2348       default:
2349         goto throw_not_impl;
2350         break;
2351       }
2352     }
2353     break;
2354 
2355   case _adapter_spread_args:


2643 static void stress_method_handle_walk(Handle mh, TRAPS) {}
2644 
2645 #endif
2646 
2647 //
2648 // Here are the native methods on sun.invoke.MethodHandleImpl.
2649 // They are the private interface between this JVM and the HotSpot-specific
2650 // Java code that implements JSR 292 method handles.
2651 //
2652 // Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
2653 // that intrinsic (non-JNI) native methods are defined in HotSpot.
2654 //
2655 
2656 // direct method handles for invokestatic or invokespecial
2657 // void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller);
2658 JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
2659                              jobject target_jh, jboolean do_dispatch, jobject caller_jh)) {
2660   ResourceMark rm;              // for error messages
2661 
2662   // This is the guy we are initializing:
2663   if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
2664   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
2665 
2666   // Early returns out of this method leave the DMH in an unfinished state.
2667   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
2668 
2669   // which method are we really talking about?
2670   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
2671   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
2672   if (java_lang_invoke_MemberName::is_instance(target()) &&
2673       java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) {
2674     MethodHandles::resolve_MemberName(target, CHECK);
2675   }
2676 
2677   KlassHandle receiver_limit; int decode_flags = 0;
2678   methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
2679   if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
2680 
2681   // The trusted Java code that calls this method should already have performed
2682   // access checks on behalf of the given caller.  But, we can verify this.
2683   if (VerifyMethodHandles && caller_jh != NULL) {
2684     KlassHandle caller(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)));
2685     // If this were a bytecode, the first access check would be against
2686     // the "reference class" mentioned in the CONSTANT_Methodref.
2687     // We don't know at this point which class that was, and if we
2688     // check against m.method_holder we might get the wrong answer.
2689     // So we just make sure to handle this check when the resolution
2690     // happens, when we call resolve_MemberName.


2704       // %%% following cutout belongs in Reflection::verify_field_access?
2705       bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(),
2706                                                         resolved_klass, THREAD);
2707       if (!same_pm) {
2708         THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
2709       }
2710     }
2711   }
2712 
2713   MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK);
2714   stress_method_handle_walk(mh, CHECK);
2715 }
2716 JVM_END
2717 
2718 // bound method handles
2719 JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
2720                              jobject target_jh, int argnum)) {
2721   ResourceMark rm;              // for error messages
2722 
2723   // This is the guy we are initializing:
2724   if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
2725   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
2726 
2727   // Early returns out of this method leave the BMH in an unfinished state.
2728   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
2729 
2730   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
2731   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
2732 
2733   if (!java_lang_invoke_MethodHandle::is_instance(target())) {
2734     // Target object is a reflective method.  (%%% Do we need this alternate path?)
2735     Untested("init_BMH of non-MH");
2736     if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
2737     KlassHandle receiver_limit; int decode_flags = 0;
2738     methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
2739     MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
2740                                                        receiver_limit,
2741                                                        decode_flags,
2742                                                        CHECK);
2743   } else {
2744     // Build a BMH on top of a DMH or another BMH:
2745     MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK);
2746   }
2747   stress_method_handle_walk(mh, CHECK);
2748 }
2749 JVM_END
2750 
2751 // adapter method handles
2752 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
2753                              jobject target_jh, int argnum)) {
2754   // This is the guy we are initializing:
2755   if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
2756   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }

2757   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
2758   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
2759 
2760   // Early returns out of this method leave the AMH in an unfinished state.
2761   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
2762 
2763   MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK);
2764   stress_method_handle_walk(mh, CHECK);
2765 }
2766 JVM_END
2767 
2768 // method type forms
2769 JVM_ENTRY(void, MHN_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) {
2770   if (erased_jh == NULL)  return;
2771   if (TraceMethodHandles) {
2772     tty->print("creating MethodType form ");
2773     if (WizardMode || Verbose) {   // Warning: this calls Java code on the MH!
2774       // call Object.toString()
2775       Symbol* name = vmSymbols::toString_name();
2776       Symbol* sig = vmSymbols::void_string_signature();


2871 #ifndef PRODUCT
2872   if (which >= 0 && which < con_value_count) {
2873     int con = con_values[which];
2874     objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
2875     if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
2876       const char* str = &con_names[0];
2877       for (int i = 0; i < which; i++)
2878         str += strlen(str) + 1;   // skip name and null
2879       oop name = java_lang_String::create_oop_from_str(str, CHECK_0);  // possible safepoint
2880       box->obj_at_put(0, name);
2881     }
2882     return con;
2883   }
2884 #endif
2885   return 0;
2886 }
2887 JVM_END
2888 
2889 // void init(MemberName self, AccessibleObject ref)
2890 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
2891   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
2892   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
2893   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
2894   oop target_oop = JNIHandles::resolve_non_null(target_jh);
2895   MethodHandles::init_MemberName(mname(), target_oop);
2896 }
2897 JVM_END
2898 
2899 // void expand(MemberName self)
2900 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
2901   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
2902   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
2903   MethodHandles::expand_MemberName(mname, 0, CHECK);
2904 }
2905 JVM_END
2906 
2907 // void resolve(MemberName self, Class<?> caller)
2908 JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
2909   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
2910   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
2911 
2912   // The trusted Java code that calls this method should already have performed
2913   // access checks on behalf of the given caller.  But, we can verify this.
2914   if (VerifyMethodHandles && caller_jh != NULL) {
2915     klassOop reference_klass = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(mname()));
2916     if (reference_klass != NULL) {
2917       // Emulate LinkResolver::check_klass_accessability.
2918       klassOop caller = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh));
2919       if (!Reflection::verify_class_access(caller,
2920                                            reference_klass,
2921                                            true)) {
2922         THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(reference_klass)->external_name());
2923       }
2924     }
2925   }
2926 
2927   MethodHandles::resolve_MemberName(mname, CHECK);
2928 }
2929 JVM_END


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