src/share/vm/interpreter/interpreter.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6833129 Cdiff src/share/vm/interpreter/interpreter.cpp

src/share/vm/interpreter/interpreter.cpp

Print this page

        

*** 282,313 **** //------------------------------------------------------------------------------------------------------------------------ // 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) { assert(method->contains(bcp), "just checkin'"); Bytecodes::Code code = Bytecodes::java_code_at(bcp); 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> --- 282,346 ---- //------------------------------------------------------------------------------------------------------------------------ // Deoptimization support ! // 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 length = Bytecodes::length_at(bcp); // compute result type BasicType type = T_ILLEGAL; ! 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: case Bytecodes::_fast_linearswitch: // recompute condtional expression folded into _if<cond>
*** 338,397 **** 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 : - 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); } 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 --- 371,404 ---- 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; } + } ! // 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) { // Quick & dirty stack overflow checking: bang the stack & handle trap. // Note that we do the banging after the frame is setup, since the exception
src/share/vm/interpreter/interpreter.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File