141 "adapter_collect/2/S0/ref", 142 "adapter_collect/2/S1/ref", 143 "adapter_collect/2/S2/ref", 144 "adapter_collect/2/S3/ref", 145 "adapter_collect/2/S4/ref", 146 "adapter_collect/2/S5/ref", 147 148 // blocking fold conversions: 149 "adapter_fold/ref", 150 "adapter_fold/int", 151 "adapter_fold/long", 152 "adapter_fold/float", 153 "adapter_fold/double", 154 "adapter_fold/void", 155 "adapter_fold/1/ref", 156 "adapter_fold/2/ref", 157 "adapter_fold/3/ref", 158 "adapter_fold/4/ref", 159 "adapter_fold/5/ref", 160 161 NULL 162 }; 163 164 // Adapters. 165 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; 166 167 jobject MethodHandles::_raise_exception_method; 168 169 address MethodHandles::_adapter_return_handlers[CONV_TYPE_MASK+1]; 170 171 #ifdef ASSERT 172 bool MethodHandles::spot_check_entry_names() { 173 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); 174 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); 175 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); 176 assert(!strcmp(entry_name(_adapter_fold_args), "adapter_fold_args"), ""); 177 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), ""); 178 assert(!strcmp(entry_name(_adapter_opt_spread_char), "adapter_spread/char"), ""); 179 assert(!strcmp(entry_name(_adapter_opt_spread_double), "adapter_spread/double"), ""); 180 assert(!strcmp(entry_name(_adapter_opt_collect_int), "adapter_collect/int"), ""); 2636 case _adapter_collect_args: 2637 case _adapter_fold_args: 2638 case _adapter_spread_args: 2639 // should be handled completely by optimized cases; see above 2640 err = "init_AdapterMethodHandle should not issue this"; 2641 break; 2642 } 2643 } 2644 2645 if (err != NULL) { 2646 throw_InternalError_for_bad_conversion(conversion, err_msg("%s: conv_op %d ek_opt %d", err, conv_op, ek_opt), THREAD); 2647 return; 2648 } 2649 2650 // Rebuild the conversion value; maybe parts of it were changed. 2651 jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo); 2652 2653 // Finalize the conversion field. (Note that it is final to Java code.) 2654 java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion); 2655 2656 // Done! 2657 java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt)); 2658 2659 // There should be enough memory barriers on exit from native methods 2660 // to ensure that the MH is fully initialized to all threads before 2661 // Java code can publish it in global data structures. 2662 } 2663 2664 void MethodHandles::ensure_vmlayout_field(Handle target, TRAPS) { 2665 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(target())); 2666 Handle mtform(THREAD, java_lang_invoke_MethodType::form(mtype())); 2667 if (mtform.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } 2668 if (java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) { 2669 if (java_lang_invoke_MethodTypeForm::vmlayout(mtform()) == NULL) { 2670 // fill it in 2671 Handle erased_mtype(THREAD, java_lang_invoke_MethodTypeForm::erasedType(mtform())); 2672 TempNewSymbol erased_signature 2673 = java_lang_invoke_MethodType::as_signature(erased_mtype(), /*intern:*/true, CHECK); 2674 methodOop cookie 2675 = SystemDictionary::find_method_handle_invoke(vmSymbols::invokeExact_name(), 2888 Handle mh(THREAD, JNIHandles::resolve(mh_jh)); 2889 if (!java_lang_invoke_MethodHandle::is_instance(mh())) { 2890 THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); 2891 } 2892 oop target = MethodHandles::encode_target(mh, format, CHECK_NULL); 2893 return JNIHandles::make_local(THREAD, target); 2894 } 2895 JVM_END 2896 2897 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) { 2898 switch (which) { 2899 case MethodHandles::GC_JVM_PUSH_LIMIT: 2900 guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF, 2901 "MethodHandlePushLimit parameter must be in valid range"); 2902 return MethodHandlePushLimit; 2903 case MethodHandles::GC_JVM_STACK_MOVE_UNIT: 2904 // return number of words per slot, signed according to stack direction 2905 return MethodHandles::stack_move_unit(); 2906 case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK: 2907 return MethodHandles::adapter_conversion_ops_supported_mask(); 2908 case MethodHandles::GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS: 2909 return MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS; 2910 } 2911 return 0; 2912 } 2913 JVM_END 2914 2915 #ifndef PRODUCT 2916 #define EACH_NAMED_CON(template) \ 2917 /* hold back this one until JDK stabilizes */ \ 2918 /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */ \ 2919 /* hold back this one until JDK stabilizes */ \ 2920 /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \ 2921 /* hold back this one until JDK stabilizes */ \ 2922 /* template(MethodHandles,GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS) */ \ 2923 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ 2924 template(MethodHandles,ETF_DIRECT_HANDLE) \ 2925 template(MethodHandles,ETF_METHOD_NAME) \ 2926 template(MethodHandles,ETF_REFLECT_METHOD) \ 2927 template(java_lang_invoke_MemberName,MN_IS_METHOD) \ 2928 template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \ 2929 template(java_lang_invoke_MemberName,MN_IS_FIELD) \ | 141 "adapter_collect/2/S0/ref", 142 "adapter_collect/2/S1/ref", 143 "adapter_collect/2/S2/ref", 144 "adapter_collect/2/S3/ref", 145 "adapter_collect/2/S4/ref", 146 "adapter_collect/2/S5/ref", 147 148 // blocking fold conversions: 149 "adapter_fold/ref", 150 "adapter_fold/int", 151 "adapter_fold/long", 152 "adapter_fold/float", 153 "adapter_fold/double", 154 "adapter_fold/void", 155 "adapter_fold/1/ref", 156 "adapter_fold/2/ref", 157 "adapter_fold/3/ref", 158 "adapter_fold/4/ref", 159 "adapter_fold/5/ref", 160 161 "adapter_opt_profiling", 162 163 NULL 164 }; 165 166 // Adapters. 167 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; 168 169 jobject MethodHandles::_raise_exception_method; 170 171 address MethodHandles::_adapter_return_handlers[CONV_TYPE_MASK+1]; 172 173 #ifdef ASSERT 174 bool MethodHandles::spot_check_entry_names() { 175 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); 176 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); 177 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); 178 assert(!strcmp(entry_name(_adapter_fold_args), "adapter_fold_args"), ""); 179 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), ""); 180 assert(!strcmp(entry_name(_adapter_opt_spread_char), "adapter_spread/char"), ""); 181 assert(!strcmp(entry_name(_adapter_opt_spread_double), "adapter_spread/double"), ""); 182 assert(!strcmp(entry_name(_adapter_opt_collect_int), "adapter_collect/int"), ""); 2638 case _adapter_collect_args: 2639 case _adapter_fold_args: 2640 case _adapter_spread_args: 2641 // should be handled completely by optimized cases; see above 2642 err = "init_AdapterMethodHandle should not issue this"; 2643 break; 2644 } 2645 } 2646 2647 if (err != NULL) { 2648 throw_InternalError_for_bad_conversion(conversion, err_msg("%s: conv_op %d ek_opt %d", err, conv_op, ek_opt), THREAD); 2649 return; 2650 } 2651 2652 // Rebuild the conversion value; maybe parts of it were changed. 2653 jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo); 2654 2655 // Finalize the conversion field. (Note that it is final to Java code.) 2656 java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion); 2657 2658 if (java_lang_invoke_CountingMethodHandle::is_instance(mh())) { 2659 assert(ek_orig == _adapter_retype_only, "only one handled"); 2660 ek_opt = _adapter_opt_profiling; 2661 } 2662 2663 // Done! 2664 java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt)); 2665 2666 // There should be enough memory barriers on exit from native methods 2667 // to ensure that the MH is fully initialized to all threads before 2668 // Java code can publish it in global data structures. 2669 } 2670 2671 void MethodHandles::ensure_vmlayout_field(Handle target, TRAPS) { 2672 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(target())); 2673 Handle mtform(THREAD, java_lang_invoke_MethodType::form(mtype())); 2674 if (mtform.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } 2675 if (java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) { 2676 if (java_lang_invoke_MethodTypeForm::vmlayout(mtform()) == NULL) { 2677 // fill it in 2678 Handle erased_mtype(THREAD, java_lang_invoke_MethodTypeForm::erasedType(mtform())); 2679 TempNewSymbol erased_signature 2680 = java_lang_invoke_MethodType::as_signature(erased_mtype(), /*intern:*/true, CHECK); 2681 methodOop cookie 2682 = SystemDictionary::find_method_handle_invoke(vmSymbols::invokeExact_name(), 2895 Handle mh(THREAD, JNIHandles::resolve(mh_jh)); 2896 if (!java_lang_invoke_MethodHandle::is_instance(mh())) { 2897 THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); 2898 } 2899 oop target = MethodHandles::encode_target(mh, format, CHECK_NULL); 2900 return JNIHandles::make_local(THREAD, target); 2901 } 2902 JVM_END 2903 2904 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) { 2905 switch (which) { 2906 case MethodHandles::GC_JVM_PUSH_LIMIT: 2907 guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF, 2908 "MethodHandlePushLimit parameter must be in valid range"); 2909 return MethodHandlePushLimit; 2910 case MethodHandles::GC_JVM_STACK_MOVE_UNIT: 2911 // return number of words per slot, signed according to stack direction 2912 return MethodHandles::stack_move_unit(); 2913 case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK: 2914 return MethodHandles::adapter_conversion_ops_supported_mask(); 2915 case MethodHandles::GC_COUNT_GWT: 2916 #ifdef COMPILER2 2917 return true; 2918 #else 2919 return false; 2920 #endif 2921 } 2922 return 0; 2923 } 2924 JVM_END 2925 2926 #ifndef PRODUCT 2927 #define EACH_NAMED_CON(template) \ 2928 /* hold back this one until JDK stabilizes */ \ 2929 /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */ \ 2930 /* hold back this one until JDK stabilizes */ \ 2931 /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \ 2932 /* hold back this one until JDK stabilizes */ \ 2933 /* template(MethodHandles,GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS) */ \ 2934 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ 2935 template(MethodHandles,ETF_DIRECT_HANDLE) \ 2936 template(MethodHandles,ETF_METHOD_NAME) \ 2937 template(MethodHandles,ETF_REFLECT_METHOD) \ 2938 template(java_lang_invoke_MemberName,MN_IS_METHOD) \ 2939 template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \ 2940 template(java_lang_invoke_MemberName,MN_IS_FIELD) \ |