23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/symbolTable.hpp" |
26 #include "classfile/symbolTable.hpp" |
27 #include "interpreter/interpreter.hpp" |
27 #include "interpreter/interpreter.hpp" |
|
28 #include "interpreter/oopMapCache.hpp" |
28 #include "memory/allocation.inline.hpp" |
29 #include "memory/allocation.inline.hpp" |
29 #include "memory/oopFactory.hpp" |
30 #include "memory/oopFactory.hpp" |
30 #include "prims/methodHandles.hpp" |
31 #include "prims/methodHandles.hpp" |
|
32 #include "prims/methodHandleWalk.hpp" |
31 #include "runtime/javaCalls.hpp" |
33 #include "runtime/javaCalls.hpp" |
32 #include "runtime/reflection.hpp" |
34 #include "runtime/reflection.hpp" |
33 #include "runtime/signature.hpp" |
35 #include "runtime/signature.hpp" |
34 #include "runtime/stubRoutines.hpp" |
36 #include "runtime/stubRoutines.hpp" |
35 |
37 |
2597 java_lang_invoke_MethodTypeForm::init_vmlayout(mtform(), cookie); |
2599 java_lang_invoke_MethodTypeForm::init_vmlayout(mtform(), cookie); |
2598 } |
2600 } |
2599 } |
2601 } |
2600 } |
2602 } |
2601 |
2603 |
|
2604 #ifdef ASSERT |
|
2605 |
|
2606 extern "C" |
|
2607 void print_method_handle(oop mh); |
|
2608 |
|
2609 static void stress_method_handle_walk_impl(Handle mh, TRAPS) { |
|
2610 if (StressMethodHandleWalk) { |
|
2611 // Exercise the MethodHandleWalk code in various ways and validate |
|
2612 // the resulting method oop. Some of these produce output so they |
|
2613 // are guarded under Verbose. |
|
2614 ResourceMark rm; |
|
2615 HandleMark hm; |
|
2616 if (Verbose) { |
|
2617 print_method_handle(mh()); |
|
2618 } |
|
2619 TempNewSymbol name = SymbolTable::new_symbol("invoke", CHECK); |
|
2620 Handle mt = java_lang_invoke_MethodHandle::type(mh()); |
|
2621 TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK); |
|
2622 MethodHandleCompiler mhc(mh, name, signature, 10000, false, CHECK); |
|
2623 methodHandle m = mhc.compile(CHECK); |
|
2624 if (Verbose) { |
|
2625 m->print_codes(); |
|
2626 } |
|
2627 InterpreterOopMap mask; |
|
2628 OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask); |
|
2629 } |
|
2630 } |
|
2631 |
|
2632 static void stress_method_handle_walk(Handle mh, TRAPS) { |
|
2633 stress_method_handle_walk_impl(mh, THREAD); |
|
2634 if (HAS_PENDING_EXCEPTION) { |
|
2635 oop ex = PENDING_EXCEPTION; |
|
2636 CLEAR_PENDING_EXCEPTION; |
|
2637 tty->print("StressMethodHandleWalk: "); |
|
2638 java_lang_Throwable::print(ex, tty); |
|
2639 tty->cr(); |
|
2640 } |
|
2641 } |
|
2642 #else |
|
2643 |
|
2644 static void stress_method_handle_walk(Handle mh, TRAPS) {} |
|
2645 |
|
2646 #endif |
|
2647 |
2602 // |
2648 // |
2603 // Here are the native methods on sun.invoke.MethodHandleImpl. |
2649 // Here are the native methods on sun.invoke.MethodHandleImpl. |
2604 // They are the private interface between this JVM and the HotSpot-specific |
2650 // They are the private interface between this JVM and the HotSpot-specific |
2605 // Java code that implements JSR 292 method handles. |
2651 // Java code that implements JSR 292 method handles. |
2606 // |
2652 // |
2664 } |
2710 } |
2665 } |
2711 } |
2666 } |
2712 } |
2667 |
2713 |
2668 MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK); |
2714 MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK); |
|
2715 stress_method_handle_walk(mh, CHECK); |
2669 } |
2716 } |
2670 JVM_END |
2717 JVM_END |
2671 |
2718 |
2672 // bound method handles |
2719 // bound method handles |
2673 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, |
2692 methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); |
2739 methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); |
2693 MethodHandles::init_BoundMethodHandle_with_receiver(mh, m, |
2740 MethodHandles::init_BoundMethodHandle_with_receiver(mh, m, |
2694 receiver_limit, |
2741 receiver_limit, |
2695 decode_flags, |
2742 decode_flags, |
2696 CHECK); |
2743 CHECK); |
2697 return; |
2744 } else { |
2698 } |
2745 // Build a BMH on top of a DMH or another BMH: |
2699 |
2746 MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); |
2700 // Build a BMH on top of a DMH or another BMH: |
2747 } |
2701 MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); |
2748 stress_method_handle_walk(mh, CHECK); |
2702 } |
2749 } |
2703 JVM_END |
2750 JVM_END |
2704 |
2751 |
2705 // adapter method handles |
2752 // adapter method handles |
2706 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, |
2714 |
2761 |
2715 // Early returns out of this method leave the AMH in an unfinished state. |
2762 // Early returns out of this method leave the AMH in an unfinished state. |
2716 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2763 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2717 |
2764 |
2718 MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK); |
2765 MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK); |
|
2766 stress_method_handle_walk(mh, CHECK); |
2719 } |
2767 } |
2720 JVM_END |
2768 JVM_END |
2721 |
2769 |
2722 // method type forms |
2770 // method type forms |
2723 JVM_ENTRY(void, MHN_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) { |
2771 JVM_ENTRY(void, MHN_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) { |