22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/symbolTable.hpp" |
26 #include "classfile/symbolTable.hpp" |
|
27 #include "compiler/compileBroker.hpp" |
27 #include "interpreter/interpreter.hpp" |
28 #include "interpreter/interpreter.hpp" |
28 #include "interpreter/oopMapCache.hpp" |
29 #include "interpreter/oopMapCache.hpp" |
29 #include "memory/allocation.inline.hpp" |
30 #include "memory/allocation.inline.hpp" |
30 #include "memory/oopFactory.hpp" |
31 #include "memory/oopFactory.hpp" |
31 #include "prims/methodHandles.hpp" |
32 #include "prims/methodHandles.hpp" |
32 #include "prims/methodHandleWalk.hpp" |
33 #include "prims/methodHandleWalk.hpp" |
|
34 #include "runtime/compilationPolicy.hpp" |
33 #include "runtime/javaCalls.hpp" |
35 #include "runtime/javaCalls.hpp" |
34 #include "runtime/reflection.hpp" |
36 #include "runtime/reflection.hpp" |
35 #include "runtime/signature.hpp" |
37 #include "runtime/signature.hpp" |
36 #include "runtime/stubRoutines.hpp" |
38 #include "runtime/stubRoutines.hpp" |
37 |
39 |
765 if (HAS_PENDING_EXCEPTION) { |
767 if (HAS_PENDING_EXCEPTION) { |
766 CLEAR_PENDING_EXCEPTION; |
768 CLEAR_PENDING_EXCEPTION; |
767 m = NULL; |
769 m = NULL; |
768 // try again with a different class loader... |
770 // try again with a different class loader... |
769 } |
771 } |
770 if (m != NULL) { |
772 if (m != NULL && |
|
773 m->is_method_handle_invoke() && |
|
774 java_lang_invoke_MethodType::equals(polymorphic_method_type(), m->method_handle_type())) { |
771 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
775 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
772 java_lang_invoke_MemberName::set_vmtarget(mname(), m); |
776 java_lang_invoke_MemberName::set_vmtarget(mname(), m); |
773 java_lang_invoke_MemberName::set_vmindex(mname(), m->vtable_index()); |
777 java_lang_invoke_MemberName::set_vmindex(mname(), m->vtable_index()); |
774 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
778 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
775 return; |
779 return; |
984 // Decode the vmtarget field of a method handle. |
988 // Decode the vmtarget field of a method handle. |
985 // Sanitize out methodOops, klassOops, and any other non-Java data. |
989 // Sanitize out methodOops, klassOops, and any other non-Java data. |
986 // This is for debugging and reflection. |
990 // This is for debugging and reflection. |
987 oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { |
991 oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { |
988 assert(java_lang_invoke_MethodHandle::is_instance(mh()), "must be a MH"); |
992 assert(java_lang_invoke_MethodHandle::is_instance(mh()), "must be a MH"); |
|
993 if (format == ETF_FORCE_DIRECT_HANDLE || |
|
994 format == ETF_COMPILE_DIRECT_HANDLE) { |
|
995 // Internal function for stress testing. |
|
996 Handle mt = java_lang_invoke_MethodHandle::type(mh()); |
|
997 int invocation_count = 10000; |
|
998 TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK_NULL); |
|
999 bool omit_receiver_argument = true; |
|
1000 MethodHandleCompiler mhc(mh, vmSymbols::invoke_name(), signature, invocation_count, omit_receiver_argument, CHECK_NULL); |
|
1001 methodHandle m = mhc.compile(CHECK_NULL); |
|
1002 if (StressMethodHandleWalk && Verbose || PrintMiscellaneous) { |
|
1003 tty->print_cr("MethodHandleNatives.getTarget(%s)", |
|
1004 format == ETF_FORCE_DIRECT_HANDLE ? "FORCE_DIRECT" : "COMPILE_DIRECT"); |
|
1005 if (Verbose) { |
|
1006 m->print_codes(); |
|
1007 } |
|
1008 } |
|
1009 if (StressMethodHandleWalk) { |
|
1010 InterpreterOopMap mask; |
|
1011 OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask); |
|
1012 } |
|
1013 if ((format == ETF_COMPILE_DIRECT_HANDLE || |
|
1014 CompilationPolicy::must_be_compiled(m)) |
|
1015 && !instanceKlass::cast(m->method_holder())->is_not_initialized() |
|
1016 && CompilationPolicy::can_be_compiled(m)) { |
|
1017 // Force compilation |
|
1018 CompileBroker::compile_method(m, InvocationEntryBci, |
|
1019 CompLevel_initial_compile, |
|
1020 methodHandle(), 0, "MethodHandleNatives.getTarget", |
|
1021 CHECK_NULL); |
|
1022 } |
|
1023 // Now wrap m in a DirectMethodHandle. |
|
1024 instanceKlassHandle dmh_klass(THREAD, SystemDictionary::DirectMethodHandle_klass()); |
|
1025 Handle dmh = dmh_klass->allocate_instance_handle(CHECK_NULL); |
|
1026 JavaValue ignore_result(T_VOID); |
|
1027 Symbol* init_name = vmSymbols::object_initializer_name(); |
|
1028 Symbol* init_sig = vmSymbols::notifyGenericMethodType_signature(); |
|
1029 JavaCalls::call_special(&ignore_result, dmh, |
|
1030 SystemDictionaryHandles::MethodHandle_klass(), init_name, init_sig, |
|
1031 java_lang_invoke_MethodHandle::type(mh()), CHECK_NULL); |
|
1032 MethodHandles::init_DirectMethodHandle(dmh, m, false, CHECK_NULL); |
|
1033 return dmh(); |
|
1034 } |
989 if (format == ETF_HANDLE_OR_METHOD_NAME) { |
1035 if (format == ETF_HANDLE_OR_METHOD_NAME) { |
990 oop target = java_lang_invoke_MethodHandle::vmtarget(mh()); |
1036 oop target = java_lang_invoke_MethodHandle::vmtarget(mh()); |
991 if (target == NULL) { |
1037 if (target == NULL) { |
992 return NULL; // unformed MH |
1038 return NULL; // unformed MH |
993 } |
1039 } |
1219 Handle loader(THREAD, mk->class_loader()); |
1265 Handle loader(THREAD, mk->class_loader()); |
1220 Handle domain(THREAD, mk->protection_domain()); |
1266 Handle domain(THREAD, mk->protection_domain()); |
1221 klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); |
1267 klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); |
1222 if (aklass_oop != NULL) |
1268 if (aklass_oop != NULL) |
1223 aklass = KlassHandle(THREAD, aklass_oop); |
1269 aklass = KlassHandle(THREAD, aklass_oop); |
|
1270 if (aklass.is_null() && |
|
1271 pklass.not_null() && |
|
1272 loader.is_null() && |
|
1273 pklass->name() == name) |
|
1274 // accept name equivalence here, since that's the best we can do |
|
1275 aklass = pklass; |
1224 } |
1276 } |
1225 } else { |
1277 } else { |
1226 // for method handle invokers we don't look at the name in the signature |
1278 // for method handle invokers we don't look at the name in the signature |
1227 oop atype_oop; |
1279 oop atype_oop; |
1228 if (ss.at_return_type()) |
1280 if (ss.at_return_type()) |
2652 if (Verbose) { |
2704 if (Verbose) { |
2653 m->print_codes(); |
2705 m->print_codes(); |
2654 } |
2706 } |
2655 InterpreterOopMap mask; |
2707 InterpreterOopMap mask; |
2656 OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask); |
2708 OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask); |
|
2709 // compile to object code if -Xcomp or WizardMode |
|
2710 if ((WizardMode || |
|
2711 CompilationPolicy::must_be_compiled(m)) |
|
2712 && !instanceKlass::cast(m->method_holder())->is_not_initialized() |
|
2713 && CompilationPolicy::can_be_compiled(m)) { |
|
2714 // Force compilation |
|
2715 CompileBroker::compile_method(m, InvocationEntryBci, |
|
2716 CompLevel_initial_compile, |
|
2717 methodHandle(), 0, "StressMethodHandleWalk", |
|
2718 CHECK); |
|
2719 } |
2657 } |
2720 } |
2658 } |
2721 } |
2659 |
2722 |
2660 static void stress_method_handle_walk(Handle mh, TRAPS) { |
2723 static void stress_method_handle_walk(Handle mh, TRAPS) { |
2661 stress_method_handle_walk_impl(mh, THREAD); |
2724 stress_method_handle_walk_impl(mh, THREAD); |
2771 CHECK); |
2834 CHECK); |
2772 } else { |
2835 } else { |
2773 // Build a BMH on top of a DMH or another BMH: |
2836 // Build a BMH on top of a DMH or another BMH: |
2774 MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); |
2837 MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); |
2775 } |
2838 } |
2776 stress_method_handle_walk(mh, CHECK); |
2839 |
|
2840 if (StressMethodHandleWalk) { |
|
2841 if (mh->klass() == SystemDictionary::BoundMethodHandle_klass()) |
|
2842 stress_method_handle_walk(mh, CHECK); |
|
2843 // else don't, since the subclass has not yet initialized its own fields |
|
2844 } |
2777 } |
2845 } |
2778 JVM_END |
2846 JVM_END |
2779 |
2847 |
2780 // adapter method handles |
2848 // adapter method handles |
2781 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2849 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh, |