hotspot/src/share/vm/prims/methodHandles.cpp
changeset 9963 4a783069663c
parent 9947 34a0c9670b78
child 9967 9ddc1c490930
equal deleted inserted replaced
9961:5d84243241ac 9963:4a783069663c
  1303 
  1303 
  1304 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
  1304 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
  1305   // Verify that argslot points at the given argnum.
  1305   // Verify that argslot points at the given argnum.
  1306   int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum);
  1306   int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum);
  1307   if (argslot != check_slot || argslot < 0) {
  1307   if (argslot != check_slot || argslot < 0) {
       
  1308     ResourceMark rm;
  1308     const char* fmt = "for argnum of %d, vmargslot is %d, should be %d";
  1309     const char* fmt = "for argnum of %d, vmargslot is %d, should be %d";
  1309     size_t msglen = strlen(fmt) + 3*11 + 1;
  1310     size_t msglen = strlen(fmt) + 3*11 + 1;
  1310     char* msg = NEW_RESOURCE_ARRAY(char, msglen);
  1311     char* msg = NEW_RESOURCE_ARRAY(char, msglen);
  1311     jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
  1312     jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
  1312     THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
  1313     THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
  1827   // are binding the receiver, cut out the middle-man.
  1828   // are binding the receiver, cut out the middle-man.
  1828   // Do this by decoding the DMH and using its methodOop directly as vmtarget.
  1829   // Do this by decoding the DMH and using its methodOop directly as vmtarget.
  1829   bool direct_to_method = false;
  1830   bool direct_to_method = false;
  1830   if (OptimizeMethodHandles &&
  1831   if (OptimizeMethodHandles &&
  1831       target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
  1832       target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
       
  1833       (argnum != 0 || java_lang_invoke_BoundMethodHandle::argument(mh()) != NULL) &&
  1832       (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) {
  1834       (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) {
  1833     KlassHandle receiver_limit; int decode_flags = 0;
  1835     KlassHandle receiver_limit; int decode_flags = 0;
  1834     methodHandle m = decode_method(target(), receiver_limit, decode_flags);
  1836     methodHandle m = decode_method(target(), receiver_limit, decode_flags);
  1835     if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
  1837     if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
  1836     DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg.
  1838     DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg.
  1978       {
  1980       {
  1979         if (!src || src != dest) {
  1981         if (!src || src != dest) {
  1980           err = "adapter requires src/dest conversion subfields for swap"; break;
  1982           err = "adapter requires src/dest conversion subfields for swap"; break;
  1981         }
  1983         }
  1982         int swap_size = type2size[src];
  1984         int swap_size = type2size[src];
  1983         int slot_limit = java_lang_invoke_MethodHandle::vmslots(target());
       
  1984         int src_slot   = argslot;
  1985         int src_slot   = argslot;
  1985         int dest_slot  = vminfo;
  1986         int dest_slot  = vminfo;
  1986         bool rotate_up = (src_slot > dest_slot); // upward rotation
  1987         bool rotate_up = (src_slot > dest_slot); // upward rotation
  1987         int src_arg    = argnum;
  1988         int src_arg    = argnum;
  1988         int dest_arg   = argument_slot_to_argnum(dst_mtype(), dest_slot);
  1989         int dest_arg   = argument_slot_to_argnum(dst_mtype(), dest_slot);
  2331 
  2332 
  2332   case _adapter_swap_args:
  2333   case _adapter_swap_args:
  2333   case _adapter_rot_args:
  2334   case _adapter_rot_args:
  2334     {
  2335     {
  2335       int swap_slots = type2size[src];
  2336       int swap_slots = type2size[src];
  2336       int slot_limit = java_lang_invoke_AdapterMethodHandle::vmslots(mh());
       
  2337       int src_slot   = argslot;
  2337       int src_slot   = argslot;
  2338       int dest_slot  = vminfo;
  2338       int dest_slot  = vminfo;
  2339       int rotate     = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
  2339       int rotate     = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
  2340       switch (swap_slots) {
  2340       switch (swap_slots) {
  2341       case 1:
  2341       case 1:
  2659 JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
  2659 JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
  2660                              jobject target_jh, jboolean do_dispatch, jobject caller_jh)) {
  2660                              jobject target_jh, jboolean do_dispatch, jobject caller_jh)) {
  2661   ResourceMark rm;              // for error messages
  2661   ResourceMark rm;              // for error messages
  2662 
  2662 
  2663   // This is the guy we are initializing:
  2663   // This is the guy we are initializing:
  2664   if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
  2664   if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
  2665   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
  2665   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
  2666 
  2666 
  2667   // Early returns out of this method leave the DMH in an unfinished state.
  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");
  2668   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
  2669 
  2669 
  2670   // which method are we really talking about?
  2670   // which method are we really talking about?
  2671   if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
  2671   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
  2672   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
  2672   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
  2673   if (java_lang_invoke_MemberName::is_instance(target()) &&
  2673   if (java_lang_invoke_MemberName::is_instance(target()) &&
  2674       java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) {
  2674       java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) {
  2675     MethodHandles::resolve_MemberName(target, CHECK);
  2675     MethodHandles::resolve_MemberName(target, CHECK);
  2676   }
  2676   }
  2720 JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
  2720 JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
  2721                              jobject target_jh, int argnum)) {
  2721                              jobject target_jh, int argnum)) {
  2722   ResourceMark rm;              // for error messages
  2722   ResourceMark rm;              // for error messages
  2723 
  2723 
  2724   // This is the guy we are initializing:
  2724   // This is the guy we are initializing:
  2725   if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
  2725   if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
  2726   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
  2726   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
  2727 
  2727 
  2728   // Early returns out of this method leave the BMH in an unfinished state.
  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");
  2729   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
  2730 
  2730 
  2731   if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
  2731   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
  2732   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
  2732   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
  2733 
  2733 
  2734   if (!java_lang_invoke_MethodHandle::is_instance(target())) {
  2734   if (!java_lang_invoke_MethodHandle::is_instance(target())) {
  2735     // Target object is a reflective method.  (%%% Do we need this alternate path?)
  2735     // Target object is a reflective method.  (%%% Do we need this alternate path?)
  2736     Untested("init_BMH of non-MH");
  2736     Untested("init_BMH of non-MH");
  2751 
  2751 
  2752 // adapter method handles
  2752 // adapter method handles
  2753 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
  2753 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
  2754                              jobject target_jh, int argnum)) {
  2754                              jobject target_jh, int argnum)) {
  2755   // This is the guy we are initializing:
  2755   // This is the guy we are initializing:
  2756   if (mh_jh == NULL || target_jh == NULL) {
  2756   if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
  2757     THROW(vmSymbols::java_lang_InternalError());
  2757   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
  2758   }
       
  2759   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
  2758   Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
  2760   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
  2759   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
  2761 
  2760 
  2762   // Early returns out of this method leave the AMH in an unfinished state.
  2761   // 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");
  2762   assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
  2888 }
  2887 }
  2889 JVM_END
  2888 JVM_END
  2890 
  2889 
  2891 // void init(MemberName self, AccessibleObject ref)
  2890 // void init(MemberName self, AccessibleObject ref)
  2892 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
  2891 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()); }
  2892   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
       
  2893   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
  2894   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  2894   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  2895   oop target_oop = JNIHandles::resolve_non_null(target_jh);
  2895   oop target_oop = JNIHandles::resolve_non_null(target_jh);
  2896   MethodHandles::init_MemberName(mname(), target_oop);
  2896   MethodHandles::init_MemberName(mname(), target_oop);
  2897 }
  2897 }
  2898 JVM_END
  2898 JVM_END
  2899 
  2899 
  2900 // void expand(MemberName self)
  2900 // void expand(MemberName self)
  2901 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
  2901 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
  2902   if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
  2902   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
  2903   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  2903   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  2904   MethodHandles::expand_MemberName(mname, 0, CHECK);
  2904   MethodHandles::expand_MemberName(mname, 0, CHECK);
  2905 }
  2905 }
  2906 JVM_END
  2906 JVM_END
  2907 
  2907 
  2908 // void resolve(MemberName self, Class<?> caller)
  2908 // void resolve(MemberName self, Class<?> caller)
  2909 JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
  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()); }
  2910   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
  2911   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  2911   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  2912 
  2912 
  2913   // The trusted Java code that calls this method should already have performed
  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.
  2914   // access checks on behalf of the given caller.  But, we can verify this.
  2915   if (VerifyMethodHandles && caller_jh != NULL) {
  2915   if (VerifyMethodHandles && caller_jh != NULL) {