mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
8005817: Shark: implement deoptimization support
Reviewed-by: twisti
This commit is contained in:
parent
a42478ecf4
commit
a0a0d0b65e
5 changed files with 39 additions and 13 deletions
|
@ -98,10 +98,20 @@ BasicObjectLock* frame::interpreter_frame_monitor_end() const {
|
||||||
#endif // CC_INTERP
|
#endif // CC_INTERP
|
||||||
|
|
||||||
void frame::patch_pc(Thread* thread, address pc) {
|
void frame::patch_pc(Thread* thread, address pc) {
|
||||||
|
|
||||||
|
if (pc != NULL) {
|
||||||
|
_cb = CodeCache::find_blob(pc);
|
||||||
|
SharkFrame* sharkframe = zeroframe()->as_shark_frame();
|
||||||
|
sharkframe->set_pc(pc);
|
||||||
|
_pc = pc;
|
||||||
|
_deopt_state = is_deoptimized;
|
||||||
|
|
||||||
|
} else {
|
||||||
// We borrow this call to set the thread pointer in the interpreter
|
// We borrow this call to set the thread pointer in the interpreter
|
||||||
// state; the hook to set up deoptimized frames isn't supplied it.
|
// state; the hook to set up deoptimized frames isn't supplied it.
|
||||||
assert(pc == NULL, "should be");
|
assert(pc == NULL, "should be");
|
||||||
get_interpreterState()->set_thread((JavaThread *) thread);
|
get_interpreterState()->set_thread((JavaThread *) thread);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool frame::safe_for_sender(JavaThread *thread) {
|
bool frame::safe_for_sender(JavaThread *thread) {
|
||||||
|
|
|
@ -45,27 +45,36 @@ inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
|
||||||
case ZeroFrame::ENTRY_FRAME:
|
case ZeroFrame::ENTRY_FRAME:
|
||||||
_pc = StubRoutines::call_stub_return_pc();
|
_pc = StubRoutines::call_stub_return_pc();
|
||||||
_cb = NULL;
|
_cb = NULL;
|
||||||
|
_deopt_state = not_deoptimized;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZeroFrame::INTERPRETER_FRAME:
|
case ZeroFrame::INTERPRETER_FRAME:
|
||||||
_pc = NULL;
|
_pc = NULL;
|
||||||
_cb = NULL;
|
_cb = NULL;
|
||||||
|
_deopt_state = not_deoptimized;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZeroFrame::SHARK_FRAME:
|
case ZeroFrame::SHARK_FRAME: {
|
||||||
_pc = zero_sharkframe()->pc();
|
_pc = zero_sharkframe()->pc();
|
||||||
_cb = CodeCache::find_blob_unsafe(pc());
|
_cb = CodeCache::find_blob_unsafe(pc());
|
||||||
|
address original_pc = nmethod::get_deopt_original_pc(this);
|
||||||
|
if (original_pc != NULL) {
|
||||||
|
_pc = original_pc;
|
||||||
|
_deopt_state = is_deoptimized;
|
||||||
|
} else {
|
||||||
|
_deopt_state = not_deoptimized;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ZeroFrame::FAKE_STUB_FRAME:
|
case ZeroFrame::FAKE_STUB_FRAME:
|
||||||
_pc = NULL;
|
_pc = NULL;
|
||||||
_cb = NULL;
|
_cb = NULL;
|
||||||
|
_deopt_state = not_deoptimized;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
_deopt_state = not_deoptimized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
|
|
|
@ -68,6 +68,10 @@ class SharkFrame : public ZeroFrame {
|
||||||
return (address) value_of_word(pc_off);
|
return (address) value_of_word(pc_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_pc(address pc) const {
|
||||||
|
*((address*) addr_of_word(pc_off)) = pc;
|
||||||
|
}
|
||||||
|
|
||||||
intptr_t* unextended_sp() const {
|
intptr_t* unextended_sp() const {
|
||||||
return (intptr_t *) value_of_word(unextended_sp_off);
|
return (intptr_t *) value_of_word(unextended_sp_off);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,13 +99,15 @@ class SharkCompileInvariants : public ResourceObj {
|
||||||
DebugInformationRecorder* debug_info() const {
|
DebugInformationRecorder* debug_info() const {
|
||||||
return env()->debug_info();
|
return env()->debug_info();
|
||||||
}
|
}
|
||||||
Dependencies* dependencies() const {
|
|
||||||
return env()->dependencies();
|
|
||||||
}
|
|
||||||
SharkCodeBuffer* code_buffer() const {
|
SharkCodeBuffer* code_buffer() const {
|
||||||
return builder()->code_buffer();
|
return builder()->code_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Dependencies* dependencies() const {
|
||||||
|
return env()->dependencies();
|
||||||
|
}
|
||||||
|
|
||||||
// Commonly used classes
|
// Commonly used classes
|
||||||
protected:
|
protected:
|
||||||
ciInstanceKlass* java_lang_Object_klass() const {
|
ciInstanceKlass* java_lang_Object_klass() const {
|
||||||
|
|
|
@ -1030,7 +1030,6 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller,
|
||||||
dest_method->holder() == java_lang_Object_klass())
|
dest_method->holder() == java_lang_Object_klass())
|
||||||
return dest_method;
|
return dest_method;
|
||||||
|
|
||||||
#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE
|
|
||||||
// This code can replace a virtual call with a direct call if this
|
// This code can replace a virtual call with a direct call if this
|
||||||
// class is the only one in the entire set of loaded classes that
|
// class is the only one in the entire set of loaded classes that
|
||||||
// implements this method. This makes the compiled code dependent
|
// implements this method. This makes the compiled code dependent
|
||||||
|
@ -1064,6 +1063,8 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller,
|
||||||
if (monomorphic_target != NULL) {
|
if (monomorphic_target != NULL) {
|
||||||
assert(!monomorphic_target->is_abstract(), "shouldn't be");
|
assert(!monomorphic_target->is_abstract(), "shouldn't be");
|
||||||
|
|
||||||
|
function()->dependencies()->assert_unique_concrete_method(actual_receiver, monomorphic_target);
|
||||||
|
|
||||||
// Opto has a bunch of type checking here that I don't
|
// Opto has a bunch of type checking here that I don't
|
||||||
// understand. It's to inhibit casting in one direction,
|
// understand. It's to inhibit casting in one direction,
|
||||||
// possibly because objects in Opto can have inexact
|
// possibly because objects in Opto can have inexact
|
||||||
|
@ -1097,7 +1098,6 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller,
|
||||||
// with non-monomorphic targets if the receiver has an exact
|
// with non-monomorphic targets if the receiver has an exact
|
||||||
// type. We don't mark types this way, so we can't do this.
|
// type. We don't mark types this way, so we can't do this.
|
||||||
|
|
||||||
#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1298,9 +1298,10 @@ void SharkTopLevelBlock::do_call() {
|
||||||
|
|
||||||
// Try to inline the call
|
// Try to inline the call
|
||||||
if (!call_is_virtual) {
|
if (!call_is_virtual) {
|
||||||
if (SharkInliner::attempt_inline(call_method, current_state()))
|
if (SharkInliner::attempt_inline(call_method, current_state())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find the method we are calling
|
// Find the method we are calling
|
||||||
Value *callee;
|
Value *callee;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue