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
|