Wed, 03 Jul 2013 11:25:06 +0200
8019519: PPC64 (part 105): C interpreter: implement support for jvmti early return.
Reviewed-by: sspitsyn, kvn
src/share/vm/interpreter/bytecodeInterpreter.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/interpreter/bytecodeInterpreter.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed Jul 03 01:41:42 2013 +0200 1.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed Jul 03 11:25:06 2013 +0200 1.3 @@ -35,6 +35,7 @@ 1.4 #include "oops/objArrayKlass.hpp" 1.5 #include "oops/oop.inline.hpp" 1.6 #include "prims/jvmtiExport.hpp" 1.7 +#include "prims/jvmtiThreadState.hpp" 1.8 #include "runtime/biasedLocking.hpp" 1.9 #include "runtime/frame.inline.hpp" 1.10 #include "runtime/handles.inline.hpp" 1.11 @@ -197,6 +198,10 @@ 1.12 !THREAD->pop_frame_in_process()) { \ 1.13 goto handle_Pop_Frame; \ 1.14 } \ 1.15 + if (THREAD->jvmti_thread_state() && \ 1.16 + THREAD->jvmti_thread_state()->is_earlyret_pending()) { \ 1.17 + goto handle_Early_Return; \ 1.18 + } \ 1.19 opcode = *pc; \ 1.20 } \ 1.21 } \ 1.22 @@ -411,21 +416,25 @@ 1.23 CACHE_LOCALS(); 1.24 1.25 // Call the VM don't check for pending exceptions 1.26 -#define CALL_VM_NOCHECK(func) \ 1.27 - DECACHE_STATE(); \ 1.28 - SET_LAST_JAVA_FRAME(); \ 1.29 - func; \ 1.30 - RESET_LAST_JAVA_FRAME(); \ 1.31 - CACHE_STATE(); \ 1.32 - if (THREAD->pop_frame_pending() && \ 1.33 - !THREAD->pop_frame_in_process()) { \ 1.34 - goto handle_Pop_Frame; \ 1.35 - } 1.36 +#define CALL_VM_NOCHECK(func) \ 1.37 + DECACHE_STATE(); \ 1.38 + SET_LAST_JAVA_FRAME(); \ 1.39 + func; \ 1.40 + RESET_LAST_JAVA_FRAME(); \ 1.41 + CACHE_STATE(); \ 1.42 + if (THREAD->pop_frame_pending() && \ 1.43 + !THREAD->pop_frame_in_process()) { \ 1.44 + goto handle_Pop_Frame; \ 1.45 + } \ 1.46 + if (THREAD->jvmti_thread_state() && \ 1.47 + THREAD->jvmti_thread_state()->is_earlyret_pending()) { \ 1.48 + goto handle_Early_Return; \ 1.49 + } 1.50 1.51 // Call the VM and check for pending exceptions 1.52 -#define CALL_VM(func, label) { \ 1.53 - CALL_VM_NOCHECK(func); \ 1.54 - if (THREAD->has_pending_exception()) goto label; \ 1.55 +#define CALL_VM(func, label) { \ 1.56 + CALL_VM_NOCHECK(func); \ 1.57 + if (THREAD->has_pending_exception()) goto label; \ 1.58 } 1.59 1.60 /* 1.61 @@ -783,7 +792,6 @@ 1.62 case popping_frame: { 1.63 // returned from a java call to pop the frame, restart the call 1.64 // clear the message so we don't confuse ourselves later 1.65 - ShouldNotReachHere(); // we don't return this. 1.66 assert(THREAD->pop_frame_in_process(), "wrong frame pop state"); 1.67 istate->set_msg(no_request); 1.68 THREAD->clr_pop_frame_in_process(); 1.69 @@ -811,6 +819,10 @@ 1.70 if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) { 1.71 goto handle_Pop_Frame; 1.72 } 1.73 + if (THREAD->jvmti_thread_state() && 1.74 + THREAD->jvmti_thread_state()->is_earlyret_pending()) { 1.75 + goto handle_Early_Return; 1.76 + } 1.77 1.78 if (THREAD->has_pending_exception()) goto handle_exception; 1.79 // Update the pc by the saved amount of the invoke bytecode size 1.80 @@ -2708,32 +2720,81 @@ 1.81 // No handler in this activation, unwind and try again 1.82 THREAD->set_pending_exception(except_oop(), NULL, 0); 1.83 goto handle_return; 1.84 - } /* handle_exception: */ 1.85 - 1.86 - 1.87 + } // handle_exception: 1.88 1.89 // Return from an interpreter invocation with the result of the interpretation 1.90 // on the top of the Java Stack (or a pending exception) 1.91 1.92 -handle_Pop_Frame: 1.93 - 1.94 - // We don't really do anything special here except we must be aware 1.95 - // that we can get here without ever locking the method (if sync). 1.96 - // Also we skip the notification of the exit. 1.97 - 1.98 - istate->set_msg(popping_frame); 1.99 - // Clear pending so while the pop is in process 1.100 - // we don't start another one if a call_vm is done. 1.101 - THREAD->clr_pop_frame_pending(); 1.102 - // Let interpreter (only) see the we're in the process of popping a frame 1.103 - THREAD->set_pop_frame_in_process(); 1.104 - 1.105 -handle_return: 1.106 - { 1.107 + handle_Pop_Frame: { 1.108 + 1.109 + // We don't really do anything special here except we must be aware 1.110 + // that we can get here without ever locking the method (if sync). 1.111 + // Also we skip the notification of the exit. 1.112 + 1.113 + istate->set_msg(popping_frame); 1.114 + // Clear pending so while the pop is in process 1.115 + // we don't start another one if a call_vm is done. 1.116 + THREAD->clr_pop_frame_pending(); 1.117 + // Let interpreter (only) see the we're in the process of popping a frame 1.118 + THREAD->set_pop_frame_in_process(); 1.119 + 1.120 + goto handle_return; 1.121 + 1.122 + } // handle_Pop_Frame 1.123 + 1.124 + // ForceEarlyReturn ends a method, and returns to the caller with a return value 1.125 + // given by the invoker of the early return. 1.126 + handle_Early_Return: { 1.127 + 1.128 + istate->set_msg(early_return); 1.129 + 1.130 + // Clear expression stack. 1.131 + topOfStack = istate->stack_base() - Interpreter::stackElementWords; 1.132 + 1.133 + JvmtiThreadState *ts = THREAD->jvmti_thread_state(); 1.134 + 1.135 + // Push the value to be returned. 1.136 + switch (istate->method()->result_type()) { 1.137 + case T_BOOLEAN: 1.138 + case T_SHORT: 1.139 + case T_BYTE: 1.140 + case T_CHAR: 1.141 + case T_INT: 1.142 + SET_STACK_INT(->earlyret_value().i, 0); 1.143 + MORE_STACK(1); 1.144 + break; 1.145 + case T_LONG: 1.146 + SET_STACK_LONG(ts->earlyret_value().j, 1); 1.147 + MORE_STACK(2); 1.148 + break; 1.149 + case T_FLOAT: 1.150 + SET_STACK_FLOAT(ts->earlyret_value().f, 0); 1.151 + MORE_STACK(1); 1.152 + break; 1.153 + case T_DOUBLE: 1.154 + SET_STACK_DOUBLE(ts->earlyret_value().d, 1); 1.155 + MORE_STACK(2); 1.156 + break; 1.157 + case T_ARRAY: 1.158 + case T_OBJECT: 1.159 + SET_STACK_OBJECT(ts->earlyret_oop(), 0); 1.160 + MORE_STACK(1); 1.161 + break; 1.162 + } 1.163 + 1.164 + ts->clr_earlyret_value(); 1.165 + ts->set_earlyret_oop(NULL); 1.166 + ts->clr_earlyret_pending(); 1.167 + 1.168 + // Fall through to handle_return. 1.169 + 1.170 + } // handle_Early_Return 1.171 + 1.172 + handle_return: { 1.173 DECACHE_STATE(); 1.174 1.175 - bool suppress_error = istate->msg() == popping_frame; 1.176 - bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error; 1.177 + bool suppress_error = istate->msg() == popping_frame || istate->msg() == early_return; 1.178 + bool suppress_exit_event = THREAD->has_pending_exception() || istate->msg() == popping_frame; 1.179 Handle original_exception(THREAD, THREAD->pending_exception()); 1.180 Handle illegal_state_oop(THREAD, NULL); 1.181 1.182 @@ -2946,7 +3007,6 @@ 1.183 THREAD->set_pending_exception(illegal_state_oop(), NULL, 0); 1.184 else 1.185 THREAD->set_pending_exception(original_exception(), NULL, 0); 1.186 - istate->set_return_kind((Bytecodes::Code)opcode); 1.187 UPDATE_PC_AND_RETURN(0); 1.188 } 1.189 1.190 @@ -2965,13 +3025,12 @@ 1.191 LOCALS_SLOT(METHOD->size_of_parameters() - 1)); 1.192 THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); 1.193 } 1.194 - THREAD->clr_pop_frame_in_process(); 1.195 + } else { 1.196 + istate->set_msg(return_from_method); 1.197 } 1.198 1.199 // Normal return 1.200 // Advance the pc and return to frame manager 1.201 - istate->set_msg(return_from_method); 1.202 - istate->set_return_kind((Bytecodes::Code)opcode); 1.203 UPDATE_PC_AND_RETURN(1); 1.204 } /* handle_return: */ 1.205 1.206 @@ -3246,7 +3305,6 @@ 1.207 tty->print_cr("result_to_call._bcp_advance: %d ", this->_result._to_call._bcp_advance); 1.208 tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf); 1.209 tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry); 1.210 - tty->print_cr("result_return_kind 0x%x ", (int) this->_result._return_kind); 1.211 tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link); 1.212 tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp); 1.213 tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base);
2.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.hpp Wed Jul 03 01:41:42 2013 +0200 2.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp Wed Jul 03 11:25:06 2013 +0200 2.3 @@ -66,27 +66,26 @@ 2.4 typedef class BytecodeInterpreter* interpreterState; 2.5 2.6 struct call_message { 2.7 - class Method* _callee; /* method to call during call_method request */ 2.8 - address _callee_entry_point; /* address to jump to for call_method request */ 2.9 - int _bcp_advance; /* size of the invoke bytecode operation */ 2.10 + class Method* _callee; // method to call during call_method request 2.11 + address _callee_entry_point; // address to jump to for call_method request 2.12 + int _bcp_advance; // size of the invoke bytecode operation 2.13 }; 2.14 2.15 struct osr_message { 2.16 - address _osr_buf; /* the osr buffer */ 2.17 - address _osr_entry; /* the entry to the osr method */ 2.18 + address _osr_buf; // the osr buffer 2.19 + address _osr_entry; // the entry to the osr method 2.20 }; 2.21 2.22 struct osr_result { 2.23 - nmethod* nm; /* osr nmethod */ 2.24 - address return_addr; /* osr blob return address */ 2.25 + nmethod* nm; // osr nmethod 2.26 + address return_addr; // osr blob return address 2.27 }; 2.28 2.29 // Result returned to frame manager 2.30 union frame_manager_message { 2.31 - call_message _to_call; /* describes callee */ 2.32 - Bytecodes::Code _return_kind; /* i_return, a_return, ... */ 2.33 - osr_message _osr; /* describes the osr */ 2.34 - osr_result _osr_result; /* result of OSR request */ 2.35 + call_message _to_call; // describes callee 2.36 + osr_message _osr; // describes the osr 2.37 + osr_result _osr_result; // result of OSR request 2.38 }; 2.39 2.40 class BytecodeInterpreter : StackObj { 2.41 @@ -115,7 +114,8 @@ 2.42 more_monitors, // need a new monitor 2.43 throwing_exception, // unwind stack and rethrow 2.44 popping_frame, // unwind call and retry call 2.45 - do_osr // request this invocation be OSR's 2.46 + do_osr, // request this invocation be OSR's 2.47 + early_return // early return as commanded by jvmti 2.48 }; 2.49 2.50 private: 2.51 @@ -216,8 +216,6 @@ 2.52 inline int bcp_advance() { return _result._to_call._bcp_advance; } 2.53 inline void set_bcp_advance(int count) { _result._to_call._bcp_advance = count; } 2.54 2.55 -inline void set_return_kind(Bytecodes::Code kind) { _result._return_kind = kind; } 2.56 - 2.57 inline interpreterState prev() { return _prev_link; } 2.58 2.59 inline intptr_t* stack() { return _stack; }