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