--- old/src/share/vm/interpreter/interpreter.cpp Thu Jul 16 16:02:31 2009 +++ new/src/share/vm/interpreter/interpreter.cpp Thu Jul 16 16:02:31 2009 @@ -284,18 +284,11 @@ //------------------------------------------------------------------------------------------------------------------------ // 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::continuation_for(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::bytecodes_to_reexecute(code), "should not reexecute"); int bci = method->bci_from(bcp); int length = -1; // initial value for debugging // compute continuation length @@ -302,10 +295,50 @@ 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::_invokevirtual : + case Bytecodes::_invokespecial : + case Bytecodes::_invokestatic : + case Bytecodes::_invokeinterface: { + Thread *thread = Thread::current(); + ResourceMark rm(thread); + methodHandle mh(thread, method); + type = Bytecode_invoke_at(mh, bci)->result_type(thread); + // since the cache entry might not be initialized: + // (NOT needed for the old calling convension) + if (!is_top_frame) { + int index = Bytes::get_native_u2(bcp+1); + method->constants()->cache()->entry_at(index)->set_parameter_size(callee_parameters); + } + break; + } + + case Bytecodes::_ldc : + type = constant_pool_type( method, *(bcp+1) ); + break; + + case Bytecodes::_ldc_w : // fall through + case Bytecodes::_ldc2_w: + type = constant_pool_type( method, Bytes::get_Java_u2(bcp+1) ); + break; + + default: + type = Bytecodes::result_type(code); + break; + } + + // return entry point for computed continuation state & bytecode length + return + is_top_frame + ? Interpreter::deopt_entry (as_TosState(type), length) + : Interpreter::return_entry(as_TosState(type), length); +} + +// If deoptimization happens, the interpreter should reexecute these bytecodes. +// This function mainly helps the compilers to set up the reexecute bit. +bool AbstractInterpreter::bytecodes_to_reexecute(Bytecodes::Code code) { + switch (code) { case Bytecodes::_lookupswitch: case Bytecodes::_tableswitch: case Bytecodes::_fast_binaryswitch: @@ -340,56 +373,30 @@ 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 + //special case of reexecution case Bytecodes::_athrow : - assert(is_top_frame, "must be top frame"); - use_next_mdp = false; - return Interpreter::rethrow_exception_entry(); - break; -#endif /* COMPILER1 */ +#endif + return true; - case Bytecodes::_invokevirtual : - case Bytecodes::_invokespecial : - case Bytecodes::_invokestatic : - case Bytecodes::_invokeinterface: { - Thread *thread = Thread::current(); - ResourceMark rm(thread); - methodHandle mh(thread, method); - type = Bytecode_invoke_at(mh, bci)->result_type(thread); - // since the cache entry might not be initialized: - // (NOT needed for the old calling convension) - if (!is_top_frame) { - int index = Bytes::get_native_u2(bcp+1); - method->constants()->cache()->entry_at(index)->set_parameter_size(callee_parameters); - } - break; - } - - case Bytecodes::_ldc : - type = constant_pool_type( method, *(bcp+1) ); - break; - - case Bytecodes::_ldc_w : // fall through - case Bytecodes::_ldc2_w: - type = constant_pool_type( method, Bytes::get_Java_u2(bcp+1) ); - break; - default: - type = Bytecodes::result_type(code); - break; + return false; } +} - // return entry point for computed continuation state & bytecode length - return - is_top_frame - ? Interpreter::deopt_entry (as_TosState(type), length) - : 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); } void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {