Mercurial > hg > graal-jvmci-8
comparison src/share/vm/interpreter/bytecodeInterpreter.cpp @ 14400:bfd9d884693d
8019519: PPC64 (part 105): C interpreter: implement support for jvmti early return.
Reviewed-by: sspitsyn, kvn
author | goetz |
---|---|
date | Wed, 03 Jul 2013 11:25:06 +0200 |
parents | 48b178ff07b6 |
children | 0014add32e54 |
comparison
equal
deleted
inserted
replaced
14399:48b178ff07b6 | 14400:bfd9d884693d |
---|---|
33 #include "memory/resourceArea.hpp" | 33 #include "memory/resourceArea.hpp" |
34 #include "oops/methodCounters.hpp" | 34 #include "oops/methodCounters.hpp" |
35 #include "oops/objArrayKlass.hpp" | 35 #include "oops/objArrayKlass.hpp" |
36 #include "oops/oop.inline.hpp" | 36 #include "oops/oop.inline.hpp" |
37 #include "prims/jvmtiExport.hpp" | 37 #include "prims/jvmtiExport.hpp" |
38 #include "prims/jvmtiThreadState.hpp" | |
38 #include "runtime/biasedLocking.hpp" | 39 #include "runtime/biasedLocking.hpp" |
39 #include "runtime/frame.inline.hpp" | 40 #include "runtime/frame.inline.hpp" |
40 #include "runtime/handles.inline.hpp" | 41 #include "runtime/handles.inline.hpp" |
41 #include "runtime/interfaceSupport.hpp" | 42 #include "runtime/interfaceSupport.hpp" |
42 #include "runtime/sharedRuntime.hpp" | 43 #include "runtime/sharedRuntime.hpp" |
195 CACHE_STATE(); \ | 196 CACHE_STATE(); \ |
196 if (THREAD->pop_frame_pending() && \ | 197 if (THREAD->pop_frame_pending() && \ |
197 !THREAD->pop_frame_in_process()) { \ | 198 !THREAD->pop_frame_in_process()) { \ |
198 goto handle_Pop_Frame; \ | 199 goto handle_Pop_Frame; \ |
199 } \ | 200 } \ |
201 if (THREAD->jvmti_thread_state() && \ | |
202 THREAD->jvmti_thread_state()->is_earlyret_pending()) { \ | |
203 goto handle_Early_Return; \ | |
204 } \ | |
200 opcode = *pc; \ | 205 opcode = *pc; \ |
201 } \ | 206 } \ |
202 } \ | 207 } \ |
203 } | 208 } |
204 #else | 209 #else |
409 CACHE_PC(); \ | 414 CACHE_PC(); \ |
410 CACHE_CP(); \ | 415 CACHE_CP(); \ |
411 CACHE_LOCALS(); | 416 CACHE_LOCALS(); |
412 | 417 |
413 // Call the VM don't check for pending exceptions | 418 // Call the VM don't check for pending exceptions |
414 #define CALL_VM_NOCHECK(func) \ | 419 #define CALL_VM_NOCHECK(func) \ |
415 DECACHE_STATE(); \ | 420 DECACHE_STATE(); \ |
416 SET_LAST_JAVA_FRAME(); \ | 421 SET_LAST_JAVA_FRAME(); \ |
417 func; \ | 422 func; \ |
418 RESET_LAST_JAVA_FRAME(); \ | 423 RESET_LAST_JAVA_FRAME(); \ |
419 CACHE_STATE(); \ | 424 CACHE_STATE(); \ |
420 if (THREAD->pop_frame_pending() && \ | 425 if (THREAD->pop_frame_pending() && \ |
421 !THREAD->pop_frame_in_process()) { \ | 426 !THREAD->pop_frame_in_process()) { \ |
422 goto handle_Pop_Frame; \ | 427 goto handle_Pop_Frame; \ |
423 } | 428 } \ |
429 if (THREAD->jvmti_thread_state() && \ | |
430 THREAD->jvmti_thread_state()->is_earlyret_pending()) { \ | |
431 goto handle_Early_Return; \ | |
432 } | |
424 | 433 |
425 // Call the VM and check for pending exceptions | 434 // Call the VM and check for pending exceptions |
426 #define CALL_VM(func, label) { \ | 435 #define CALL_VM(func, label) { \ |
427 CALL_VM_NOCHECK(func); \ | 436 CALL_VM_NOCHECK(func); \ |
428 if (THREAD->has_pending_exception()) goto label; \ | 437 if (THREAD->has_pending_exception()) goto label; \ |
429 } | 438 } |
430 | 439 |
431 /* | 440 /* |
432 * BytecodeInterpreter::run(interpreterState istate) | 441 * BytecodeInterpreter::run(interpreterState istate) |
433 * BytecodeInterpreter::runWithChecks(interpreterState istate) | 442 * BytecodeInterpreter::runWithChecks(interpreterState istate) |
781 } | 790 } |
782 | 791 |
783 case popping_frame: { | 792 case popping_frame: { |
784 // returned from a java call to pop the frame, restart the call | 793 // returned from a java call to pop the frame, restart the call |
785 // clear the message so we don't confuse ourselves later | 794 // clear the message so we don't confuse ourselves later |
786 ShouldNotReachHere(); // we don't return this. | |
787 assert(THREAD->pop_frame_in_process(), "wrong frame pop state"); | 795 assert(THREAD->pop_frame_in_process(), "wrong frame pop state"); |
788 istate->set_msg(no_request); | 796 istate->set_msg(no_request); |
789 THREAD->clr_pop_frame_in_process(); | 797 THREAD->clr_pop_frame_in_process(); |
790 goto run; | 798 goto run; |
791 } | 799 } |
808 } | 816 } |
809 #endif // HACK | 817 #endif // HACK |
810 // returned from a java call, continue executing. | 818 // returned from a java call, continue executing. |
811 if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) { | 819 if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) { |
812 goto handle_Pop_Frame; | 820 goto handle_Pop_Frame; |
821 } | |
822 if (THREAD->jvmti_thread_state() && | |
823 THREAD->jvmti_thread_state()->is_earlyret_pending()) { | |
824 goto handle_Early_Return; | |
813 } | 825 } |
814 | 826 |
815 if (THREAD->has_pending_exception()) goto handle_exception; | 827 if (THREAD->has_pending_exception()) goto handle_exception; |
816 // Update the pc by the saved amount of the invoke bytecode size | 828 // Update the pc by the saved amount of the invoke bytecode size |
817 UPDATE_PC(istate->bcp_advance()); | 829 UPDATE_PC(istate->bcp_advance()); |
2706 // for AbortVMOnException flag | 2718 // for AbortVMOnException flag |
2707 NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); | 2719 NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); |
2708 // No handler in this activation, unwind and try again | 2720 // No handler in this activation, unwind and try again |
2709 THREAD->set_pending_exception(except_oop(), NULL, 0); | 2721 THREAD->set_pending_exception(except_oop(), NULL, 0); |
2710 goto handle_return; | 2722 goto handle_return; |
2711 } /* handle_exception: */ | 2723 } // handle_exception: |
2712 | |
2713 | |
2714 | 2724 |
2715 // Return from an interpreter invocation with the result of the interpretation | 2725 // Return from an interpreter invocation with the result of the interpretation |
2716 // on the top of the Java Stack (or a pending exception) | 2726 // on the top of the Java Stack (or a pending exception) |
2717 | 2727 |
2718 handle_Pop_Frame: | 2728 handle_Pop_Frame: { |
2719 | 2729 |
2720 // We don't really do anything special here except we must be aware | 2730 // We don't really do anything special here except we must be aware |
2721 // that we can get here without ever locking the method (if sync). | 2731 // that we can get here without ever locking the method (if sync). |
2722 // Also we skip the notification of the exit. | 2732 // Also we skip the notification of the exit. |
2723 | 2733 |
2724 istate->set_msg(popping_frame); | 2734 istate->set_msg(popping_frame); |
2725 // Clear pending so while the pop is in process | 2735 // Clear pending so while the pop is in process |
2726 // we don't start another one if a call_vm is done. | 2736 // we don't start another one if a call_vm is done. |
2727 THREAD->clr_pop_frame_pending(); | 2737 THREAD->clr_pop_frame_pending(); |
2728 // Let interpreter (only) see the we're in the process of popping a frame | 2738 // Let interpreter (only) see the we're in the process of popping a frame |
2729 THREAD->set_pop_frame_in_process(); | 2739 THREAD->set_pop_frame_in_process(); |
2730 | 2740 |
2731 handle_return: | 2741 goto handle_return; |
2732 { | 2742 |
2743 } // handle_Pop_Frame | |
2744 | |
2745 // ForceEarlyReturn ends a method, and returns to the caller with a return value | |
2746 // given by the invoker of the early return. | |
2747 handle_Early_Return: { | |
2748 | |
2749 istate->set_msg(early_return); | |
2750 | |
2751 // Clear expression stack. | |
2752 topOfStack = istate->stack_base() - Interpreter::stackElementWords; | |
2753 | |
2754 JvmtiThreadState *ts = THREAD->jvmti_thread_state(); | |
2755 | |
2756 // Push the value to be returned. | |
2757 switch (istate->method()->result_type()) { | |
2758 case T_BOOLEAN: | |
2759 case T_SHORT: | |
2760 case T_BYTE: | |
2761 case T_CHAR: | |
2762 case T_INT: | |
2763 SET_STACK_INT(->earlyret_value().i, 0); | |
2764 MORE_STACK(1); | |
2765 break; | |
2766 case T_LONG: | |
2767 SET_STACK_LONG(ts->earlyret_value().j, 1); | |
2768 MORE_STACK(2); | |
2769 break; | |
2770 case T_FLOAT: | |
2771 SET_STACK_FLOAT(ts->earlyret_value().f, 0); | |
2772 MORE_STACK(1); | |
2773 break; | |
2774 case T_DOUBLE: | |
2775 SET_STACK_DOUBLE(ts->earlyret_value().d, 1); | |
2776 MORE_STACK(2); | |
2777 break; | |
2778 case T_ARRAY: | |
2779 case T_OBJECT: | |
2780 SET_STACK_OBJECT(ts->earlyret_oop(), 0); | |
2781 MORE_STACK(1); | |
2782 break; | |
2783 } | |
2784 | |
2785 ts->clr_earlyret_value(); | |
2786 ts->set_earlyret_oop(NULL); | |
2787 ts->clr_earlyret_pending(); | |
2788 | |
2789 // Fall through to handle_return. | |
2790 | |
2791 } // handle_Early_Return | |
2792 | |
2793 handle_return: { | |
2733 DECACHE_STATE(); | 2794 DECACHE_STATE(); |
2734 | 2795 |
2735 bool suppress_error = istate->msg() == popping_frame; | 2796 bool suppress_error = istate->msg() == popping_frame || istate->msg() == early_return; |
2736 bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error; | 2797 bool suppress_exit_event = THREAD->has_pending_exception() || istate->msg() == popping_frame; |
2737 Handle original_exception(THREAD, THREAD->pending_exception()); | 2798 Handle original_exception(THREAD, THREAD->pending_exception()); |
2738 Handle illegal_state_oop(THREAD, NULL); | 2799 Handle illegal_state_oop(THREAD, NULL); |
2739 | 2800 |
2740 // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner | 2801 // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner |
2741 // in any following VM entries from freeing our live handles, but illegal_state_oop | 2802 // in any following VM entries from freeing our live handles, but illegal_state_oop |
2944 istate->set_msg(throwing_exception); | 3005 istate->set_msg(throwing_exception); |
2945 if (illegal_state_oop() != NULL) | 3006 if (illegal_state_oop() != NULL) |
2946 THREAD->set_pending_exception(illegal_state_oop(), NULL, 0); | 3007 THREAD->set_pending_exception(illegal_state_oop(), NULL, 0); |
2947 else | 3008 else |
2948 THREAD->set_pending_exception(original_exception(), NULL, 0); | 3009 THREAD->set_pending_exception(original_exception(), NULL, 0); |
2949 istate->set_return_kind((Bytecodes::Code)opcode); | |
2950 UPDATE_PC_AND_RETURN(0); | 3010 UPDATE_PC_AND_RETURN(0); |
2951 } | 3011 } |
2952 | 3012 |
2953 if (istate->msg() == popping_frame) { | 3013 if (istate->msg() == popping_frame) { |
2954 // Make it simpler on the assembly code and set the message for the frame pop. | 3014 // Make it simpler on the assembly code and set the message for the frame pop. |
2963 // | 3023 // |
2964 THREAD->popframe_preserve_args(in_ByteSize(METHOD->size_of_parameters() * wordSize), | 3024 THREAD->popframe_preserve_args(in_ByteSize(METHOD->size_of_parameters() * wordSize), |
2965 LOCALS_SLOT(METHOD->size_of_parameters() - 1)); | 3025 LOCALS_SLOT(METHOD->size_of_parameters() - 1)); |
2966 THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); | 3026 THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); |
2967 } | 3027 } |
2968 THREAD->clr_pop_frame_in_process(); | 3028 } else { |
3029 istate->set_msg(return_from_method); | |
2969 } | 3030 } |
2970 | 3031 |
2971 // Normal return | 3032 // Normal return |
2972 // Advance the pc and return to frame manager | 3033 // Advance the pc and return to frame manager |
2973 istate->set_msg(return_from_method); | |
2974 istate->set_return_kind((Bytecodes::Code)opcode); | |
2975 UPDATE_PC_AND_RETURN(1); | 3034 UPDATE_PC_AND_RETURN(1); |
2976 } /* handle_return: */ | 3035 } /* handle_return: */ |
2977 | 3036 |
2978 // This is really a fatal error return | 3037 // This is really a fatal error return |
2979 | 3038 |
3244 tty->print_cr("result_to_call._callee: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee); | 3303 tty->print_cr("result_to_call._callee: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee); |
3245 tty->print_cr("result_to_call._callee_entry_point: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee_entry_point); | 3304 tty->print_cr("result_to_call._callee_entry_point: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee_entry_point); |
3246 tty->print_cr("result_to_call._bcp_advance: %d ", this->_result._to_call._bcp_advance); | 3305 tty->print_cr("result_to_call._bcp_advance: %d ", this->_result._to_call._bcp_advance); |
3247 tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf); | 3306 tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf); |
3248 tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry); | 3307 tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry); |
3249 tty->print_cr("result_return_kind 0x%x ", (int) this->_result._return_kind); | |
3250 tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link); | 3308 tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link); |
3251 tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp); | 3309 tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp); |
3252 tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base); | 3310 tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base); |
3253 tty->print_cr("stack_limit: " INTPTR_FORMAT, (uintptr_t) this->_stack_limit); | 3311 tty->print_cr("stack_limit: " INTPTR_FORMAT, (uintptr_t) this->_stack_limit); |
3254 tty->print_cr("monitor_base: " INTPTR_FORMAT, (uintptr_t) this->_monitor_base); | 3312 tty->print_cr("monitor_base: " INTPTR_FORMAT, (uintptr_t) this->_monitor_base); |