src/share/vm/interpreter/bytecodeInterpreter.cpp

Print this page
rev 4869 : 8019519: PPC64 (part 105): C interpreter: implement support for jvmti early return.

*** 34,43 **** --- 34,44 ---- #include "memory/resourceArea.hpp" #include "oops/methodCounters.hpp" #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiExport.hpp" + #include "prims/jvmtiThreadState.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/sharedRuntime.hpp"
*** 196,205 **** --- 197,210 ---- CACHE_STATE(); \ if (THREAD->pop_frame_pending() && \ !THREAD->pop_frame_in_process()) { \ goto handle_Pop_Frame; \ } \ + if (THREAD->jvmti_thread_state() && \ + THREAD->jvmti_thread_state()->is_earlyret_pending()) { \ + goto handle_Early_Return; \ + } \ opcode = *pc; \ } \ } \ } #else
*** 419,428 **** --- 424,437 ---- RESET_LAST_JAVA_FRAME(); \ CACHE_STATE(); \ if (THREAD->pop_frame_pending() && \ !THREAD->pop_frame_in_process()) { \ goto handle_Pop_Frame; \ + } \ + if (THREAD->jvmti_thread_state() && \ + THREAD->jvmti_thread_state()->is_earlyret_pending()) { \ + goto handle_Early_Return; \ } // Call the VM and check for pending exceptions #define CALL_VM(func, label) { \ CALL_VM_NOCHECK(func); \
*** 818,827 **** --- 827,840 ---- #endif // HACK // returned from a java call, continue executing. if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) { goto handle_Pop_Frame; } + if (THREAD->jvmti_thread_state() && + THREAD->jvmti_thread_state()->is_earlyret_pending()) { + goto handle_Early_Return; + } if (THREAD->has_pending_exception()) goto handle_exception; // Update the pc by the saved amount of the invoke bytecode size UPDATE_PC(istate->bcp_advance()); goto run;
*** 2721,2732 **** // No handler in this activation, unwind and try again THREAD->set_pending_exception(except_oop(), NULL, 0); goto handle_return; } /* handle_exception: */ - - // Return from an interpreter invocation with the result of the interpretation // on the top of the Java Stack (or a pending exception) handle_Pop_Frame: --- 2734,2743 ----
*** 2739,2754 **** // we don't start another one if a call_vm is done. THREAD->clr_pop_frame_pending(); // Let interpreter (only) see the we're in the process of popping a frame THREAD->set_pop_frame_in_process(); handle_return: { DECACHE_STATE(); ! bool suppress_error = istate->msg() == popping_frame; ! bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error; Handle original_exception(THREAD, THREAD->pending_exception()); Handle illegal_state_oop(THREAD, NULL); // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner // in any following VM entries from freeing our live handles, but illegal_state_oop --- 2750,2811 ---- // we don't start another one if a call_vm is done. THREAD->clr_pop_frame_pending(); // Let interpreter (only) see the we're in the process of popping a frame THREAD->set_pop_frame_in_process(); + goto handle_return; + + // ForceEarlyReturn ends a method, and returns to the caller with a return value + // given by the invoker of the early return. + handle_Early_Return: + + istate->set_msg(early_return); + + // Clear expression stack. + topOfStack = istate->stack_base() - Interpreter::stackElementWords; + + // Push the value to be returned. + switch (istate->method()->result_type()) { + case T_BOOLEAN: + case T_SHORT: + case T_BYTE: + case T_CHAR: + case T_INT: + SET_STACK_INT(THREAD->jvmti_thread_state()->earlyret_value().i, 0); + MORE_STACK(1); + break; + case T_LONG: + SET_STACK_LONG(THREAD->jvmti_thread_state()->earlyret_value().j, 1); + MORE_STACK(2); + break; + case T_FLOAT: + SET_STACK_FLOAT(THREAD->jvmti_thread_state()->earlyret_value().f, 0); + MORE_STACK(1); + break; + case T_DOUBLE: + SET_STACK_DOUBLE(THREAD->jvmti_thread_state()->earlyret_value().d, 1); + MORE_STACK(2); + break; + case T_ARRAY: + case T_OBJECT: + SET_STACK_OBJECT(THREAD->jvmti_thread_state()->earlyret_oop(), 0); + MORE_STACK(1); + break; + } + + THREAD->jvmti_thread_state()->clr_earlyret_value(); + THREAD->jvmti_thread_state()->set_earlyret_oop(NULL); + THREAD->jvmti_thread_state()->clr_earlyret_pending(); + + // Fall through to handle_return. + handle_return: { DECACHE_STATE(); ! bool suppress_error = istate->msg() == popping_frame || istate->msg() == early_return; ! bool suppress_exit_event = THREAD->has_pending_exception() || istate->msg() == popping_frame; Handle original_exception(THREAD, THREAD->pending_exception()); Handle illegal_state_oop(THREAD, NULL); // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner // in any following VM entries from freeing our live handles, but illegal_state_oop
*** 2957,2967 **** istate->set_msg(throwing_exception); if (illegal_state_oop() != NULL) THREAD->set_pending_exception(illegal_state_oop(), NULL, 0); else THREAD->set_pending_exception(original_exception(), NULL, 0); - istate->set_return_kind((Bytecodes::Code)opcode); UPDATE_PC_AND_RETURN(0); } if (istate->msg() == popping_frame) { // Make it simpler on the assembly code and set the message for the frame pop. --- 3014,3023 ----
*** 2976,2992 **** // THREAD->popframe_preserve_args(in_ByteSize(METHOD->size_of_parameters() * wordSize), LOCALS_SLOT(METHOD->size_of_parameters() - 1)); THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); } ! THREAD->clr_pop_frame_in_process(); } // Normal return // Advance the pc and return to frame manager - istate->set_msg(return_from_method); - istate->set_return_kind((Bytecodes::Code)opcode); UPDATE_PC_AND_RETURN(1); } /* handle_return: */ // This is really a fatal error return --- 3032,3047 ---- // THREAD->popframe_preserve_args(in_ByteSize(METHOD->size_of_parameters() * wordSize), LOCALS_SLOT(METHOD->size_of_parameters() - 1)); THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); } ! } else { ! istate->set_msg(return_from_method); } // Normal return // Advance the pc and return to frame manager UPDATE_PC_AND_RETURN(1); } /* handle_return: */ // This is really a fatal error return