--- a/hotspot/src/share/vm/interpreter/interpreter.cpp Fri Jul 31 12:04:07 2009 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp Fri Jul 31 17:12:33 2009 -0700
@@ -284,76 +284,19 @@
//------------------------------------------------------------------------------------------------------------------------
// Deoptimization support
-// If deoptimization happens, this method returns the point where to continue in
-// interpreter. For calls (invokexxxx, newxxxx) the continuation is at next
-// bci and the top of stack is in eax/edx/FPU tos.
-// For putfield/getfield, put/getstatic, the continuation is at the same
-// bci and the TOS is on stack.
-
-// Note: deopt_entry(type, 0) means reexecute bytecode
-// deopt_entry(type, length) means continue at next bytecode
-
-address AbstractInterpreter::continuation_for(methodOop method, address bcp, int callee_parameters, bool is_top_frame, bool& use_next_mdp) {
+// If deoptimization happens, this function returns the point of next bytecode to continue execution
+address AbstractInterpreter::deopt_continue_after_entry(methodOop method, address bcp, int callee_parameters, bool is_top_frame) {
assert(method->contains(bcp), "just checkin'");
Bytecodes::Code code = Bytecodes::java_code_at(bcp);
+ assert(!Interpreter::bytecode_should_reexecute(code), "should not reexecute");
int bci = method->bci_from(bcp);
int length = -1; // initial value for debugging
// compute continuation length
length = Bytecodes::length_at(bcp);
// compute result type
BasicType type = T_ILLEGAL;
- // when continuing after a compiler safepoint, re-execute the bytecode
- // (an invoke is continued after the safepoint)
- use_next_mdp = true;
+
switch (code) {
- case Bytecodes::_lookupswitch:
- case Bytecodes::_tableswitch:
- case Bytecodes::_fast_binaryswitch:
- case Bytecodes::_fast_linearswitch:
- // recompute condtional expression folded into _if<cond>
- case Bytecodes::_lcmp :
- case Bytecodes::_fcmpl :
- case Bytecodes::_fcmpg :
- case Bytecodes::_dcmpl :
- case Bytecodes::_dcmpg :
- case Bytecodes::_ifnull :
- case Bytecodes::_ifnonnull :
- case Bytecodes::_goto :
- case Bytecodes::_goto_w :
- case Bytecodes::_ifeq :
- case Bytecodes::_ifne :
- case Bytecodes::_iflt :
- case Bytecodes::_ifge :
- case Bytecodes::_ifgt :
- case Bytecodes::_ifle :
- case Bytecodes::_if_icmpeq :
- case Bytecodes::_if_icmpne :
- case Bytecodes::_if_icmplt :
- case Bytecodes::_if_icmpge :
- case Bytecodes::_if_icmpgt :
- case Bytecodes::_if_icmple :
- case Bytecodes::_if_acmpeq :
- case Bytecodes::_if_acmpne :
- // special cases
- case Bytecodes::_getfield :
- case Bytecodes::_putfield :
- case Bytecodes::_getstatic :
- case Bytecodes::_putstatic :
- case Bytecodes::_aastore :
- // reexecute the operation and TOS value is on stack
- assert(is_top_frame, "must be top frame");
- use_next_mdp = false;
- return Interpreter::deopt_entry(vtos, 0);
- break;
-
-#ifdef COMPILER1
- case Bytecodes::_athrow :
- assert(is_top_frame, "must be top frame");
- use_next_mdp = false;
- return Interpreter::rethrow_exception_entry();
- break;
-#endif /* COMPILER1 */
-
case Bytecodes::_invokevirtual :
case Bytecodes::_invokespecial :
case Bytecodes::_invokestatic :
@@ -392,6 +335,70 @@
: Interpreter::return_entry(as_TosState(type), length);
}
+// If deoptimization happens, this function returns the point where the interpreter reexecutes
+// the bytecode.
+// Note: Bytecodes::_athrow is a special case in that it does not return
+// Interpreter::deopt_entry(vtos, 0) like others
+address AbstractInterpreter::deopt_reexecute_entry(methodOop method, address bcp) {
+ assert(method->contains(bcp), "just checkin'");
+ Bytecodes::Code code = Bytecodes::java_code_at(bcp);
+#ifdef COMPILER1
+ if(code == Bytecodes::_athrow ) {
+ return Interpreter::rethrow_exception_entry();
+ }
+#endif /* COMPILER1 */
+ return Interpreter::deopt_entry(vtos, 0);
+}
+
+// If deoptimization happens, the interpreter should reexecute these bytecodes.
+// This function mainly helps the compilers to set up the reexecute bit.
+bool AbstractInterpreter::bytecode_should_reexecute(Bytecodes::Code code) {
+ switch (code) {
+ case Bytecodes::_lookupswitch:
+ case Bytecodes::_tableswitch:
+ case Bytecodes::_fast_binaryswitch:
+ case Bytecodes::_fast_linearswitch:
+ // recompute condtional expression folded into _if<cond>
+ case Bytecodes::_lcmp :
+ case Bytecodes::_fcmpl :
+ case Bytecodes::_fcmpg :
+ case Bytecodes::_dcmpl :
+ case Bytecodes::_dcmpg :
+ case Bytecodes::_ifnull :
+ case Bytecodes::_ifnonnull :
+ case Bytecodes::_goto :
+ case Bytecodes::_goto_w :
+ case Bytecodes::_ifeq :
+ case Bytecodes::_ifne :
+ case Bytecodes::_iflt :
+ case Bytecodes::_ifge :
+ case Bytecodes::_ifgt :
+ case Bytecodes::_ifle :
+ case Bytecodes::_if_icmpeq :
+ case Bytecodes::_if_icmpne :
+ case Bytecodes::_if_icmplt :
+ case Bytecodes::_if_icmpge :
+ case Bytecodes::_if_icmpgt :
+ case Bytecodes::_if_icmple :
+ case Bytecodes::_if_acmpeq :
+ case Bytecodes::_if_acmpne :
+ // special cases
+ case Bytecodes::_getfield :
+ case Bytecodes::_putfield :
+ case Bytecodes::_getstatic :
+ case Bytecodes::_putstatic :
+ case Bytecodes::_aastore :
+#ifdef COMPILER1
+ //special case of reexecution
+ case Bytecodes::_athrow :
+#endif
+ return true;
+
+ default:
+ return false;
+ }
+}
+
void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
// Quick & dirty stack overflow checking: bang the stack & handle trap.
// Note that we do the banging after the frame is setup, since the exception